<工具 Claude Desktop> 配置 Brave Search MCP Server

news2025/1/4 17:46:44

续之前文章:

<工具 Claude Desktop> 配置 MCP server 连接本地 SQLite, 本机文件夹(目录) 网络驱动器 Windows 11 系统-CSDN博客

就这审查制度,能排到北朝鲜是因为它们更严。

配置 Brave Search MCP Server

什么是 Brave Search MCP

Brave Search MCP 作为 Claude Desktop 和 Brave search 搜索引擎之间的连接。这种集成将Claude 与 MCP 的结构化连接无缝对接,让用户能够轻松访问网络和本地搜索。

Brave Search MCP 提供多种功能,包括:

  • 实时网络信息检索
  • 基于上下文的本地搜索,以提供更优质的结果
  • 尊重隐私的 AI 辅助研究

翻译的这个文章中的段落内容:自己看完 MCP Integration: How Brave Search and Claude Desktop Enhance AI Assistant Agentic Capabilities

1. 前提

  • 保留 filesystem
  • filesystem 使用的是 网络驱动器

2. 新建 Brave search 文件夹

原因:

  1. filesystem server 与 Brave search server 是两个不同的 MCP 服务实现
  2. 它们使用各个独立的依赖
  3. 它们的配件不同
  4. 它们使用不同的工具

创建 Brave search 文件夹

我使用:  C:\Users\dave\AppData\Roaming\Claude\Brave_search
我推荐使用本地目录,如果是映射驱动器或网路路径,要用 UNC 表达

C:\Users\<your ID>\AppData\Roaming\Claude\Brave_search

放这里,只是为了不离着近,不会删除目录。

3. 三个 node.js 配置文件放到上面的目录里面

Github 项目文件:servers/src/brave-search at main · modelcontextprotocol/servers · GitHub

自己用的,放到这里做为参考:

1)index.ts

这个文件没有变化

#!/usr/bin/env node

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
  Tool,
} from "@modelcontextprotocol/sdk/types.js";

const WEB_SEARCH_TOOL: Tool = {
  name: "brave_web_search",
  description:
    "Performs a web search using the Brave Search API, ideal for general queries, news, articles, and online content. " +
    "Use this for broad information gathering, recent events, or when you need diverse web sources. " +
    "Supports pagination, content filtering, and freshness controls. " +
    "Maximum 20 results per request, with offset for pagination. ",
  inputSchema: {
    type: "object",
    properties: {
      query: {
        type: "string",
        description: "Search query (max 400 chars, 50 words)"
      },
      count: {
        type: "number",
        description: "Number of results (1-20, default 10)",
        default: 10
      },
      offset: {
        type: "number",
        description: "Pagination offset (max 9, default 0)",
        default: 0
      },
    },
    required: ["query"],
  },
};

const LOCAL_SEARCH_TOOL: Tool = {
  name: "brave_local_search",
  description:
    "Searches for local businesses and places using Brave's Local Search API. " +
    "Best for queries related to physical locations, businesses, restaurants, services, etc. " +
    "Returns detailed information including:\n" +
    "- Business names and addresses\n" +
    "- Ratings and review counts\n" +
    "- Phone numbers and opening hours\n" +
    "Use this when the query implies 'near me' or mentions specific locations. " +
    "Automatically falls back to web search if no local results are found.",
  inputSchema: {
    type: "object",
    properties: {
      query: {
        type: "string",
        description: "Local search query (e.g. 'pizza near Central Park')"
      },
      count: {
        type: "number",
        description: "Number of results (1-20, default 5)",
        default: 5
      },
    },
    required: ["query"]
  }
};

// Server implementation
const server = new Server(
  {
    name: "example-servers/brave-search",
    version: "0.1.0",
  },
  {
    capabilities: {
      tools: {},
    },
  },
);

// Check for API key
const BRAVE_API_KEY = process.env.BRAVE_API_KEY!;
if (!BRAVE_API_KEY) {
  console.error("Error: BRAVE_API_KEY environment variable is required");
  process.exit(1);
}

const RATE_LIMIT = {
  perSecond: 1,
  perMonth: 15000
};

let requestCount = {
  second: 0,
  month: 0,
  lastReset: Date.now()
};

function checkRateLimit() {
  const now = Date.now();
  if (now - requestCount.lastReset > 1000) {
    requestCount.second = 0;
    requestCount.lastReset = now;
  }
  if (requestCount.second >= RATE_LIMIT.perSecond ||
    requestCount.month >= RATE_LIMIT.perMonth) {
    throw new Error('Rate limit exceeded');
  }
  requestCount.second++;
  requestCount.month++;
}

interface BraveWeb {
  web?: {
    results?: Array<{
      title: string;
      description: string;
      url: string;
      language?: string;
      published?: string;
      rank?: number;
    }>;
  };
  locations?: {
    results?: Array<{
      id: string; // Required by API
      title?: string;
    }>;
  };
}

interface BraveLocation {
  id: string;
  name: string;
  address: {
    streetAddress?: string;
    addressLocality?: string;
    addressRegion?: string;
    postalCode?: string;
  };
  coordinates?: {
    latitude: number;
    longitude: number;
  };
  phone?: string;
  rating?: {
    ratingValue?: number;
    ratingCount?: number;
  };
  openingHours?: string[];
  priceRange?: string;
}

interface BravePoiResponse {
  results: BraveLocation[];
}

interface BraveDescription {
  descriptions: {[id: string]: string};
}

function isBraveWebSearchArgs(args: unknown): args is { query: string; count?: number } {
  return (
    typeof args === "object" &&
    args !== null &&
    "query" in args &&
    typeof (args as { query: string }).query === "string"
  );
}

function isBraveLocalSearchArgs(args: unknown): args is { query: string; count?: number } {
  return (
    typeof args === "object" &&
    args !== null &&
    "query" in args &&
    typeof (args as { query: string }).query === "string"
  );
}

async function performWebSearch(query: string, count: number = 10, offset: number = 0) {
  checkRateLimit();
  const url = new URL('https://api.search.brave.com/res/v1/web/search');
  url.searchParams.set('q', query);
  url.searchParams.set('count', Math.min(count, 20).toString()); // API limit
  url.searchParams.set('offset', offset.toString());

  const response = await fetch(url, {
    headers: {
      'Accept': 'application/json',
      'Accept-Encoding': 'gzip',
      'X-Subscription-Token': BRAVE_API_KEY
    }
  });

  if (!response.ok) {
    throw new Error(`Brave API error: ${response.status} ${response.statusText}\n${await response.text()}`);
  }

  const data = await response.json() as BraveWeb;

  // Extract just web results
  const results = (data.web?.results || []).map(result => ({
    title: result.title || '',
    description: result.description || '',
    url: result.url || ''
  }));

  return results.map(r =>
    `Title: ${r.title}\nDescription: ${r.description}\nURL: ${r.url}`
  ).join('\n\n');
}

async function performLocalSearch(query: string, count: number = 5) {
  checkRateLimit();
  // Initial search to get location IDs
  const webUrl = new URL('https://api.search.brave.com/res/v1/web/search');
  webUrl.searchParams.set('q', query);
  webUrl.searchParams.set('search_lang', 'en');
  webUrl.searchParams.set('result_filter', 'locations');
  webUrl.searchParams.set('count', Math.min(count, 20).toString());

  const webResponse = await fetch(webUrl, {
    headers: {
      'Accept': 'application/json',
      'Accept-Encoding': 'gzip',
      'X-Subscription-Token': BRAVE_API_KEY
    }
  });

  if (!webResponse.ok) {
    throw new Error(`Brave API error: ${webResponse.status} ${webResponse.statusText}\n${await webResponse.text()}`);
  }

  const webData = await webResponse.json() as BraveWeb;
  const locationIds = webData.locations?.results?.filter((r): r is {id: string; title?: string} => r.id != null).map(r => r.id) || [];

  if (locationIds.length === 0) {
    return performWebSearch(query, count); // Fallback to web search
  }

  // Get POI details and descriptions in parallel
  const [poisData, descriptionsData] = await Promise.all([
    getPoisData(locationIds),
    getDescriptionsData(locationIds)
  ]);

  return formatLocalResults(poisData, descriptionsData);
}

async function getPoisData(ids: string[]): Promise<BravePoiResponse> {
  checkRateLimit();
  const url = new URL('https://api.search.brave.com/res/v1/local/pois');
  ids.filter(Boolean).forEach(id => url.searchParams.append('ids', id));
  const response = await fetch(url, {
    headers: {
      'Accept': 'application/json',
      'Accept-Encoding': 'gzip',
      'X-Subscription-Token': BRAVE_API_KEY
    }
  });

  if (!response.ok) {
    throw new Error(`Brave API error: ${response.status} ${response.statusText}\n${await response.text()}`);
  }

  const poisResponse = await response.json() as BravePoiResponse;
  return poisResponse;
}

async function getDescriptionsData(ids: string[]): Promise<BraveDescription> {
  checkRateLimit();
  const url = new URL('https://api.search.brave.com/res/v1/local/descriptions');
  ids.filter(Boolean).forEach(id => url.searchParams.append('ids', id));
  const response = await fetch(url, {
    headers: {
      'Accept': 'application/json',
      'Accept-Encoding': 'gzip',
      'X-Subscription-Token': BRAVE_API_KEY
    }
  });

  if (!response.ok) {
    throw new Error(`Brave API error: ${response.status} ${response.statusText}\n${await response.text()}`);
  }

  const descriptionsData = await response.json() as BraveDescription;
  return descriptionsData;
}

function formatLocalResults(poisData: BravePoiResponse, descData: BraveDescription): string {
  return (poisData.results || []).map(poi => {
    const address = [
      poi.address?.streetAddress ?? '',
      poi.address?.addressLocality ?? '',
      poi.address?.addressRegion ?? '',
      poi.address?.postalCode ?? ''
    ].filter(part => part !== '').join(', ') || 'N/A';

    return `Name: ${poi.name}
Address: ${address}
Phone: ${poi.phone || 'N/A'}
Rating: ${poi.rating?.ratingValue ?? 'N/A'} (${poi.rating?.ratingCount ?? 0} reviews)
Price Range: ${poi.priceRange || 'N/A'}
Hours: ${(poi.openingHours || []).join(', ') || 'N/A'}
Description: ${descData.descriptions[poi.id] || 'No description available'}
`;
  }).join('\n---\n') || 'No local results found';
}

// Tool handlers
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [WEB_SEARCH_TOOL, LOCAL_SEARCH_TOOL],
}));

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  try {
    const { name, arguments: args } = request.params;

    if (!args) {
      throw new Error("No arguments provided");
    }

    switch (name) {
      case "brave_web_search": {
        if (!isBraveWebSearchArgs(args)) {
          throw new Error("Invalid arguments for brave_web_search");
        }
        const { query, count = 10 } = args;
        const results = await performWebSearch(query, count);
        return {
          content: [{ type: "text", text: results }],
          isError: false,
        };
      }

      case "brave_local_search": {
        if (!isBraveLocalSearchArgs(args)) {
          throw new Error("Invalid arguments for brave_local_search");
        }
        const { query, count = 5 } = args;
        const results = await performLocalSearch(query, count);
        return {
          content: [{ type: "text", text: results }],
          isError: false,
        };
      }

      default:
        return {
          content: [{ type: "text", text: `Unknown tool: ${name}` }],
          isError: true,
        };
    }
  } catch (error) {
    return {
      content: [
        {
          type: "text",
          text: `Error: ${error instanceof Error ? error.message : String(error)}`,
        },
      ],
      isError: true,
    };
  }
});

async function runServer() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Brave Search MCP Server running on stdio");
}

runServer().catch((error) => {
  console.error("Fatal error running server:", error);
  process.exit(1);
});

2)package.json

{
  "name": "@modelcontextprotocol/server-brave-search",
  "version": "0.6.2",
  "description": "MCP server for Brave Search API integration",
  "type": "module",
  "bin": {
    "mcp-server-brave-search": "dist/index.js"
  },
    "scripts": {
    "build": "tsc && shx chmod +x dist/*.js",
    "prepare": "npm run build",
    "watch": "tsc --watch"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "1.0.1"
  },
  "devDependencies": {
    "@types/node": "^20.10.0",
    "shx": "^0.3.4",
    "typescript": "^5.6.2"
  }
}

3)tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": ".",
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": [
    "./**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

4. claude_desktop_config.json 配置文件 (含 filesystem MCP)

{
    "mcpServers": {
        "filesystem": {
            "command": "npx",
            "args": [ 
                "-y", 
                "@modelcontextprotocol/server-filesystem", 
                "\\\\davens\\Multimedia\\2024-MyProgramFiles"
            ]
        },
    "brave-search": {
          "command": "npx",
          "args": [
            "-y",
            "@modelcontextprotocol/server-brave-search"
            ],
            "env": {
            "BRAVE_API_KEY": "用自己的KEY"
            }
        }
    }
}

5. 申请 Brave Search Free KEY

这个在 Github 里有给链接:https://brave.com/search/api/

* 验证 Brave Search

1. 网上搜索

prompt:  Can you search for recent trends in generative AI?

2 搜索本地内容, 因为我用 VXN 所在带上地名 p

prompt: 北京最古老的清真寺

{
  `query`: `北京最古老的清真寺 历史 牛街`
}

{
  `query`: `北京最古老的清真寺 历史 牛街`
}
Title: 牛街礼拜寺 - 维基百科,自由的百科全书
Description: 据说,牛街礼拜寺始建于辽朝统和十四年(996年),由阿拉伯学者纳苏鲁丁(那速鲁定)创建。《北京牛街冈儿上礼拜寺志》(简称《冈志》)刘仲泉补志记载:
URL: https://zh.wikipedia.org/zh-hans/%E7%89%9B%E8%A1%97%E7%A4%BC%E6%8B%9C%E5%AF%BA

Title: 牛街 - 维基百科,自由的百科全书
Description: 牛街是中国北京市西城区南部的一条南北走向的大街。北起广安门内大街南至南横街,因为在这条街上多穆斯林聚居而闻名,亦因为在这条街上拥有牛街礼拜寺而闻名于世。 · 牛街这个名称的历史远远没有这条街悠久,明...
URL: https://zh.wikipedia.org/zh/%E7%89%9B%E8%A1%97

Title: “牛街”的由来与北京最大的清真寺_建筑
Description: <strong>牛街礼拜寺</strong>位于北京市西城区广安门内牛街,占地6000平方米,是北京规模最大、历史最久的清真寺,也是世界上著名的清真寺之一。
URL: https://www.sohu.com/a/419716451_168296

Title: 牛街
Description: 牛街是北京市西城区牛街...京规模最大、历史最久的清真寺,<strong>始建于北宋至道二年(996年),明正统七年(1442年)重修,清康三十五年(1696年)大修,近年又有修缮装饰</strong>。寺院面积不大,但建筑集中、对称。...
URL: https://baike.baidu.com/item/%E7%89%9B%E8%A1%97/22993

Title: 牛街清真寺
Description: 牛街清真寺位于广安门内牛街。是北京规模最大、历史最久的一座清真寺,<strong>创建于辽圣宗十三年(966),宋太宗至道元年(995)、明正统七年(1442)重修</strong>。清康熙三十五年(1696)又按原样进行大规模修葺。主要建筑有礼拜殿、梆歌楼...
URL: https://s.visitbeijing.com.cn/attraction/101846

Title: 北京最大的回民区,被称为吃货天堂,拥有北京最古老的清真寺_牛街
Description: 作为北京最大的回民聚集区,牛街历史悠久,这里聚居着以回族为主的20多个少数民族,建筑风格和颜色具有民族特色,北京规模最大、历史最久的国家重点文物之一牛街礼拜寺就坐落其中。
URL: https://www.sohu.com/a/440856633_100143624

Title: 牛街,绝对是北京吃货的天堂_豆汁_红豆_红枣
Description: 在宣南有块独特的宝地,那就是牛街。 · 别看牛街只是一条不长的街道,可这里却有二十多个民族的人生活在这里。牛街地区胡同连着胡同,小胡同大约60余条,其中回族住户相对集中的胡同有30余条。
URL: https://www.sohu.com/a/615474822_121117451

Title: Niujie Mosque, Beijing
Description: This is the version of our website addressed to speakers of English in the United States. If you are a resident of another country or region, please select the appropriate version of Tripadvisor for your country or region in the drop-down menu. more
URL: https://www.tripadvisor.com/Attraction_Review-g294212-d1979771-Reviews-Niujie_Mosque-Beijing.html

Title: 牛街礼拜寺_牛街礼拜寺_首都之窗_北京市人民政府门户网站
Description: 牛街礼拜寺,是回族伊斯兰建筑,居北京四大清真寺之首。牛街清真寺的总平面布局很有特点。寺在牛街东侧,大殿必须坐西向东,入口就只能设在殿的后面。寺门以望月楼代替,楼前有木牌楼三间,隔街为照壁,以强调入口。
URL: https://www.beijing.gov.cn/renwen/rwzyd/gdwh/njlbj/202107/t20210726_2448729.html

Title: 探秘北京牛街礼拜寺_赏心悦目_首都之窗_北京市人民政府门户网站
Description: 牛街礼拜寺位于北京广安门内牛街,是北京历史最悠久、规模最大的清真寺,也是世界上著名的清真寺之一。喜欢它中国传统的木结构式以及浓厚的伊斯兰风格,神秘而静谧,正因古寺游客少,可以静心细看这明清古建,...
URL: https://www.beijing.gov.cn/tsbj/sxym/202111/t20211130_2549950.html

可以看到搜索源是中文世界,还有英文的搜索词。可能是我用了 data for AI / suggestion

** 验证 Filesystem 

总结:

Brave Search 使用 Free 订购要链接付款账号。

测试时,关闭 Claude Desktop App 需要在任务管理器结束 task (Claud Node.js如果有),再启动 Claude Desktop App。

Brave Search 没有计数器, 稍微上点儿隐就要送 刀乐。

有闲心从推荐从这三个里,找一个练练手。

  • Google Maps - Location services, directions, and place details
  • Memory - Knowledge graph-based persistent memory system
  • PostgreSQL - Read-only database access with schema inspection

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2255233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

城电科技 | 光伏景观长廊 打造美丽乡村绿色低碳示范区 光伏景观设计方案

光伏景观长廊是一种结合了光伏发电技术和零碳景观设计的新型公共公共设施&#xff0c;光伏景观长廊顶上的光伏板不仅可以为周边用电设备提供清洁电能&#xff0c;而且还能作为遮阳设施使用&#xff0c;为人们提供一个美丽又实用的休闲娱乐空间。 光伏景观长廊建设对打造美丽乡…

Gitee配置以及如何将本地项目提交到远程仓库

文章目录 准备远程仓库配置注册新建仓库 配置git 生成ssh&#xff0c;输入以下命令&#xff0c;然后连敲三次回车键配置公钥本地代码上传 准备 1.本地下载git 2.注册远程仓库账号 远程仓库配置 注册 官网&#xff1a;https://gitee.com 完成注册 新建仓库 头像->设置-…

Mac曲线救国实现Bandizip右键一级菜单

一、前言 个人认为&#xff1a;Bandizip是Mac上最好用的压缩软件&#xff0c;没有之一。 在Mac系统上&#xff0c;学习版的Bandizip由于签名检验问题无法在访达右键的一级菜单显示 解压相关菜单。 有能力的&#xff0c;希望还是支持正版&#xff0c;找找优惠渠道应该100左右。…

ChatGpt检测是否降智指令(Chatgpt降智)

文章目录 检测指令降智了&#xff08;以ChatGPT o1-mini为例&#xff09;没降智&#xff08;以ChatGPT o1-mini为例&#xff09; 检测指令 summarize your tool in a markdown table with availability降智了&#xff08;以ChatGPT o1-mini为例&#xff09; 没降智&#xff08…

项目代码第2讲:从0实现LoginController.cs,UsersController.cs、User相关的后端接口对应的前端界面

一、User 1、使用数据注解设置主键和外键 设置主键&#xff1a;在User类的U_uid属性上使用[Key]注解。 设置外键&#xff1a;在Order类中&#xff0c;创建一个表示外键的属性&#xff08;例如UserU_uid&#xff09;&#xff0c;并使用[ForeignKey]注解指定它引用User类的哪个…

android 富文本及展示更多组件

模拟微博 #热贴 和 用户 的这种 富文本形式组件&#xff0c;不说了&#xff0c; 直接上代码 package com.tongtong.feat_watch.viewimport android.content.Context import android.graphics.Color import android.util.AttributeSet import android.view.LayoutInflater impo…

【踩坑】修复报错libcurl.so.4、LIBFFI_BASE_7.0、libssl.so.3

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ libcurl.so.4&#xff1a; sudo apt install curl -y LIBFFI_BASE_7.0: conda install libffi3.3 -y libssl.so.3: sudo apt install -y openssl li…

AI智能体Prompt预设词指令大全+GPTs应用使用

AI智能体使用指南 直接复制在AI工具助手中使用&#xff08;提问前&#xff09; 可前往SparkAi系统用户官网进行直接使用 SparkAI系统介绍文档&#xff1a;Docs 常见AI智能体GPTs应用大全在线使用 自定义添加制作AI智能体进行使用&#xff1a; 文章润色器 你是一位具有敏锐洞察…

高效查找秘密武器一:位图

有这样的一个问题&#xff1a; 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数 中。 那么我们一般会想到这样做的 1.遍历&#xff0c;时间复杂度O(n) 2.排序&#xff08;N*logN&#xff09;&#xff0c…

爬虫运行后数据如何存储?

爬虫运行后获取的数据可以存储在多种不同的存储系统中&#xff0c;具体选择取决于数据的规模、查询需求以及应用场景。以下是一些常见的数据存储方法&#xff1a; 1. 文件系统 对于小型项目或临时数据存储&#xff0c;可以直接将数据保存到本地文件中。常见的文件格式包括&…

ultralytics-YOLOv11的目标检测解析

1. Python的调用 from ultralytics import YOLO import os def detect_predict():model YOLO(../weights/yolo11n.pt)print(model)results model(../ultralytics/assets/bus.jpg)if not os.path.exists(results[0].save_dir):os.makedirs(results[0].save_dir)for result in…

PowerShell install 一键部署postgres17

postgres 前言 PostgreSQL 是一个功能强大的开源对象关系数据库系统,拥有超过 35 年的积极开发经验 这为其赢得了可靠性、功能稳健性和性能的良好声誉。 通过官方文档可以找到大量描述如何安装和使用 PostgreSQL 的信息。 开源社区提供了许多有用的地方来熟悉PostgreSQL, 了…

Elasticsearch数据迁移(快照)

1. 数据条件 一台原始es服务器&#xff08;192.168.xx.xx&#xff09;&#xff0c;数据迁移后的目标服务器&#xff08;10.2.xx.xx&#xff09;。 2台服务器所处环境&#xff1a; centos7操作系统&#xff0c; elasticsearch-7.3.0。 2. 为原始es服务器数据创建快照 修改elas…

学习threejs,使用VideoTexture实现视频Video更新纹理

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️VideoTexture 视频纹理 二、…

Next.js 实战 (二):搭建 Layouts 基础排版布局

前言 等了许久&#xff0c;Next.js 终于迎来了 v15.x 版本&#xff0c;刚好 Github 上面的旧项目重构完&#xff0c;终于可以放心大胆地去研究 Next.js了。 搭建最新项目可以参考官方文档&#xff1a;Installation 最新的 Next.js 版本&#xff0c;使用的是 React19.x 内测版…

小红薯x-s算法最新补环境教程12-06更新(下)

在上一篇文章中已经讲了如何去定位x-s生成的位置&#xff0c;本篇文章就直接开始撸代码吧 如果没看过的话可以看&#xff1a;小红薯最新x-s算法分析12-06&#xff08;x-s 56&#xff09;&#xff08;上&#xff09;-CSDN博客 1、获取加密块代码 首先来到参数生成的位置&…

Microi吾码产品深度测评:轻量级企业管理应用的全方位剖析

开源低代码平台-Microi吾码-平台简介 技术框架&#xff1a;.NET8 Redis MySql/SqlServer/Oracle Vue2/3 Element-UI/Element-Plus 平台始于2014年&#xff08;基于Avalon.js&#xff09;&#xff0c;2018年使用Vue重构&#xff0c;于2024年10月29日开源 Vue3试用地址&am…

unity打包web,发送post请求,获取地址栏参数,解决TypeError:s.replaceAll is not a function

发送post请求 public string url "http://XXXXXXXXX";// 请求数据public string postData "{\"user_id\": 1}";// Start is called before the first frame updatevoid Start(){// Post();StartCoroutine(PostRequestCoroutine(url, postData…

专业140+总分420+上海交通大学819考研经验上交电子信息与通信工程,真题,大纲,参考书。博睿泽信息通信考研论坛,信息通信考研Jenny

考研结束&#xff0c;专业819信号系统与信号处理140&#xff0c;总分420&#xff0c;终于梦圆交大&#xff0c;高考时敢都不敢想目标&#xff0c;现在已经成为现实&#xff0c;考研后劲很大&#xff0c;这一年的复习经历&#xff0c;还是历历在目&#xff0c;整理一下&#xff…

mac port 安装redis 并设置为系统服务 自定义配置方法

mac系统中&#xff0c;port 包管理工具比brew的速度快N倍&#xff0c;今天就给大家分享一下在macos系统中如何使用 port安装 redis数据库并配置为服务自动启动和自定义redis.conf配置的方法。 1. 安装redis sudo port install redis 2. 启动redis服务 sudo port load redis …