编程 MCP 深度实战:当 AI Agent 终于有了「USB-C 接口」——从协议内核、传输层到生产级 MCP Server 与 codebase-memory-mcp 案例的完全指南

2026-07-12 02:44:30 +0800 CST views 9

MCP 深度实战:当 AI Agent 终于有了「USB-C 接口」——从协议内核、传输层到生产级 MCP Server 与 codebase-memory-mcp 案例的完全指南

2026 年 7 月,GitHub 周榜第二的项目 codebase-memory-mcp 拿到了 2.6 万 Star。它做的事很简单:把你的代码库索引成一张持久化的知识图谱,让 AI 编程 Agent 用结构化查询代替「grep + 读文件」。而它底层依赖的,正是最近一年彻底改变 AI 工程形态的协议——MCP(Model Context Protocol)。本文不堆概念,带你从协议内核、传输层、三大原语一路打到生产级 Server 实现,并拆解这个 26K Star 项目的真实架构。


一、背景:AI 工具碎片化的真正痛点

2024 年底之前,如果你想让一个大模型去查数据库、读文件、调内部 API,路线只有一条:为每个模型、每个工具写一套定制集成

于是你会看到这样的局面:

  • OpenAI 有一套 Function Calling 格式,Anthropic 有一套 tool use 格式,Google 又是一套;
  • 你在 Claude 上接好的「查订单」工具,换到 Cursor 里要重写一遍;
  • 工具的鉴权、错误处理、权限边界,每接一次都要重新设计;
  • 更复杂的是「上下文」——模型不仅需要「调用工具」,还需要「读取数据」(比如某份文档、某张表),以及「预置提示模板」。这些东西散落在不同厂商的私有实现里,没有统一抽象。

这个问题的本质是 N × M 集成爆炸:N 个模型客户端 × M 个工具 = N×M 套胶水代码。

MCP 的出现,把乘法变成了加法。它的核心心智模型只有一句话:

写一次 MCP Server,即可被任何支持 MCP 的客户端(Claude Desktop、Cursor、VS Code Copilot、Windsurf、你自己的 Agent)调用。

业界给它的比喻是 「AI 世界的 USB-C 接口」:物理接口统一之后,充电器、显示器、硬盘可以随意插拔;协议统一之后,工具、数据源、提示模板也可以即插即用。

截至 2026 年 7 月,MCP 已被捐赠给 Linux Foundation,微软 Agent Framework、Google ADK、腾讯云、百度智能云等主流平台均原生支持,生态中已有 400+ 开源 Server。


二、MCP 是什么:三层角色与一张图

MCP 采用经典的 Client-Server 架构,但引入了一个关键的中间角色——Host。三者的职责划分是理解整个协议的基础:

┌─────────────────────────────────────────────────────────────┐
│  Host(宿主应用,运行大模型、与用户交互)                       │
│   例如:Claude Desktop / Cursor / VS Code / 你写的 Agent       │
│                                                               │
│    ┌──────────────┐         JSON-RPC 2.0        ┌──────────┐ │
│    │ MCP Client   │ ◄──────────────────────────► │ MCP Server│ │
│    │ (内嵌于 Host)│   (stdio / Streamable HTTP) │(提供能力)│ │
│    └──────────────┘                              └──────────┘ │
└─────────────────────────────────────────────────────────────┘
  • Host(宿主):真正运行大模型、负责和用户对话的应用。它管理着与多个 MCP Server 的连接。
  • Client(客户端):内嵌在 Host 内部的一个组件,负责与某一个 MCP Server 建立一对一的连接,维护独立的会话状态。注意:一个 Host 里通常有多个 Client,每个 Client 只连一个 Server。
  • Server(服务端):真正提供能力的一侧。它可以是本地子进程(stdio),也可以是远程 HTTP 服务。每个 Server 暴露一组 Tools(工具)/ Resources(资源)/ Prompts(提示模板)

这种设计最妙的地方在于:模型不需要知道工具怎么实现,工具也不需要知道是哪个模型在调用它——协议层把两边彻底解耦。

一个反直觉的关键点

很多人以为 MCP 的革新在「传输协议」。其实 JSON-RPC 2.0 是 2009 年的老技术,stdio 更是古老。MCP 真正的革新是 控制反转(Inversion of Control)

  • 在传统代码里,调用什么工具由 if/else 决定;
  • 在 MCP 里,调用什么工具由 大模型的概率推断 决定;
  • 调用参数不是结构化输入,而是自然语言解析的结果。

这意味着控制权从确定性的代码,交给了不确定的模型。这是能力跃迁,也是风险来源——后文「安全边界」一节会专门讲如何给这种不确定性套上缰绳。


三、协议内核:JSON-RPC 2.0 与生命周期

MCP 的所有通信都跑在 JSON-RPC 2.0 之上。把「协议」二字拆开,其实就三件事:消息格式、生命周期、方法集。

3.1 一次真实握手长什么样

当你在 Cursor 里启用一个 MCP Server,Host 会启动 Server 子进程,第一件事就是 initialize 握手。下面是一段真实 transcript(已简化):

Client → Server(initialize 请求,协商能力):

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "roots": { "listChanged": true },
      "sampling": {}
    },
    "clientInfo": { "name": "cursor", "version": "1.0.0" }
  }
}

Server → Client(回应,声明自己支持什么):

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": {},
      "prompts": {}
    },
    "serverInfo": { "name": "pg-readonly", "version": "0.1.0" }
  }
}

Client → Server(握手完成通知,无 id,因为 notification 不需要回复):

{ "jsonrpc": "2.0", "method": "notifications/initialized" }

几个要点:

  1. protocolVersion 协商:客户端发自己支持的最高版本,服务端可以「降级」到双方都懂的版本。这是向后兼容的基石——老客户端连新服务端、新客户端连老服务端都不会直接崩。
  2. capabilities 是双向声明的:客户端说自己支持 roots / sampling,服务端说自己支持 tools / resources / prompts。双方只调用对方声明过的能力。
  3. notifications/* 没有 id:这是 JSON-RPC 的 notification 语义,单向、不需要响应,常用于生命周期事件(如 initialized、日志级别变更)。

3.2 之后才是真活儿

握手完成后,才是日常调用循环:

  • tools/list —— 客户端问「你有哪些工具?」拿到工具名、描述、inputSchema;
  • tools/call —— 客户端说「调用这个工具,参数如下」;
  • resources/list / resources/read —— 读取数据源;
  • prompts/list / prompts/get —— 拉取提示模板;
  • ping —— 心跳保活;
  • logging/setLevel —— 让客户端控制服务端的日志详略。

实战建议:排错时,第一件事就是把这段 JSON-RPC transcript 打出来。90% 的「工具调不起来」问题,要么是 capabilities 没声明,要么是 inputSchema 写错导致模型填的参数不匹配。


四、三大原语:Tools / Resources / Prompts

MCP 把「模型能用的外部能力」分成了三种语义不同的原语。理解它们的区别,是设计好一个 Server 的关键。

4.1 Tools:模型控制(model-controlled)

Tools 是模型可以主动调用的函数,等价于 Function Calling。典型例子:执行 SQL、调用 API、运行 shell 命令。

特点:

  • 模型决定何时调用(基于用户意图推理);
  • 必须提供 namedescription、以及 JSON Schema 格式的 inputSchema
  • 调用结果返回给模型,模型据此继续推理。
{
  "name": "query_orders",
  "description": "按用户 ID 查询最近 30 天的订单",
  "inputSchema": {
    "type": "object",
    "properties": {
      "user_id": { "type": "string", "description": "用户 ID" },
      "limit": { "type": "integer", "default": 20 }
    },
    "required": ["user_id"]
  }
}

4.2 Resources:应用/用户控制(app/user-controlled)

Resources 是模型可以「读取」的数据源,由 URI 寻址,例如 file:///logs/app.logpostgres://db/orders

区别在哪?Tools 是「动作」,Resources 是「数据」。一个 Resource 是你塞进模型上下文的「参考资料」,通常由应用或用户决定加载哪个(而不是模型临时决定)。

{
  "uri": "file:///docs/api.md",
  "name": "API 文档",
  "mimeType": "text/markdown",
  "description": "内部 API 规范"
}

4.3 Prompts:用户控制(user-controlled)

Prompts 是预定义的提示模板,由用户主动触发。比如「代码评审模板」「SQL 优化模板」。它把常用的工作流固化下来,用户点一下就能把结构化的提示注入对话。

{
  "name": "review_pr",
  "description": "对一段代码变更做评审",
  "arguments": [{ "name": "diff", "description": "git diff 内容", "required": true }]
}

4.4 决策框架:该用哪个?

你的能力是…
一个「动作」(查、算、调、改)Tool
一份「资料」(文件、表、文档)Resource
一套「工作流模板」(评审、总结)Prompt

此外还有三个进阶原语,生产中越来越重要:

  • Sampling:Server 反向请求 Client,让模型「补全一段文字」(服务端也能调用 LLM,形成嵌套智能);
  • Roots:Client 告诉 Server「你允许访问哪些文件系统根目录」,是安全边界;
  • Elicitation:Server 在运行中向用户请求缺失的额外输入(2025-06-18 修订引入)。

五、传输层:stdio 与 Streamable HTTP

MCP 不绑定某一种传输,它定义的是「消息如何序列化、如何分帧」,具体怎么传由两个官方传输实现负责。

5.1 stdio:本地子进程

最简单、最常用。Host 直接 fork 一个子进程,通过标准输入/输出收发 JSON-RPC 消息,每行一条。

适用场景:

  • Server 跑在你本机(读本地文件、跑本地命令、连 localhost 数据库);
  • 不需要网络,天然隔离,权限等同于当前用户。

优点:零部署、零网络、安全模型清晰(本地信任)。缺点:只能本机,无法多人共享。

5.2 Streamable HTTP:从 SSE 的演进

这是 2026 年最该搞清楚的变化。MCP 早期用 SSE 传输:服务端开一个 GET /sse 的 Event Stream 推消息,客户端再开一个 POST /messages 把请求发过去。这套方案有三个硬伤:

  1. 必须维护一条长连接事件流,负载均衡器和 Serverless 很难友好支持;
  2. 服务端要记住每个客户端的 SSE 通道,有状态,扩缩容麻烦;
  3. 两个端点,心智负担重。

2025-03-26 协议修订引入了 Streamable HTTP 传输,彻底改写:

  • 一个端点(如 POST /mcp)同时处理客户端请求;
  • 只有当服务端需要流式推送时,才在这条响应里用 SSE 分块返回;
  • 支持无状态模式——服务端可以不保存会话,每条请求自带上下文,轻松跑在负载均衡器后面;
  • 也支持有状态模式(通过 Mcp-Session-Id 头部维持会话)。

一句话总结演进:SSE 是「始终开着的广播」,Streamable HTTP 是「按需开流的单通道」。这让 MCP Server 第一次能像普通 Web 服务一样部署、扩缩、上云。

5.3 远程服务器的鉴权:OAuth 2.0

本地 stdio Server 默认信任当前用户;远程 HTTP Server 必须鉴权。2025-03-26 修订把 OAuth 2.0 定为标准鉴权方案,并引入 RFC 9728 的资源指示器(Resource Indicators)和动态客户端注册(Dynamic Client Registration)。

这意味着:当你连一个第三方远程 MCP Server(比如某个 SaaS 提供的「查 CRM」服务),流程和标准 OAuth 登录一模一样——弹窗授权、拿 token、Bearer 携带。不要让模型在无鉴权的远程 Server 上裸奔。


六、代码实战一:用 Python FastMCP 构建生产级 Server

理论够了,上代码。我们用 Python 官方 mcp 包的 FastMCP 高层 API,构建一个真实有用的 Server:给 AI Agent 提供一个只读的 PostgreSQL 查询工具 + 一个代码检索工具

6.1 安装与骨架

pip install "mcp[cli]"
# server.py
from mcp.server.fastmcp import FastMCP
import asyncpg
import os

mcp = FastMCP("pg-readonly")

# 连接池在模块级懒加载,避免每次调用都建连
_pool = None

async def get_pool():
    global _pool
    if _pool is None:
        _pool = await asyncpg.create_pool(
            dsn=os.environ["DATABASE_URL"],
            min_size=1,
            max_size=10,
        )
    return _pool

6.2 一个安全的只读查询工具

生产级工具的第一个原则:永远不要把用户原话拼进 SQL。 这里我们用参数化查询 + 白名单表 + 只读事务三重保险。

ALLOWED_TABLES = {"orders", "users", "products", "order_items"}

@mcp.tool()
async def query_table(
    table: str,
    columns: list[str] | None = None,
    limit: int = 20,
) -> str:
    """对白名单内的表执行安全的只读查询。

    Args:
        table: 表名,仅允许 orders/users/products/order_items
        columns: 要查询的列,默认 SELECT *
        limit: 返回行数上限,最大 100
    """
    if table not in ALLOWED_TABLES:
        return f"❌ 拒绝:表 {table!r} 不在白名单中"
    limit = min(max(limit, 1), 100)
    cols = "*" if not columns else ", ".join(columns)

    # 注意:table/columns 是标识符,不能参数化,必须白名单校验后安全拼接
    sql = f"SELECT {cols} FROM {table} LIMIT $1"

    pool = await get_pool()
    async with pool.acquire() as conn:
        # 强制只读事务
        await conn.execute("SET TRANSACTION READ ONLY")
        rows = await conn.fetch(sql, limit)

    # 转成模型易读的表格文本
    if not rows:
        return "(无结果)"
    header = "\t".join(rows[0].keys())
    body = "\n".join("\t".join(str(v) for v in r.values()) for r in rows)
    return f"{header}\n{body}"

注意几个生产细节:

  • table/columns标识符,SQL 不支持用 $1 参数化标识符,所以必须用白名单校验后拼接——绝不能直接 f-string 用户任意输入;
  • limit 是值,用 $1 参数化,且做上下夹紧;
  • SET TRANSACTION READ ONLY纵深防御:即使有人绕过白名单,也写不进库;
  • 返回值用纯文本表格,模型解析友好。

6.3 一个代码检索工具(为后续案例铺路)

import subprocess, shlex
from pathlib import Path

REPO_ROOT = Path(os.environ.get("REPO_ROOT", ".")).resolve()

@mcp.tool()
async def grep_symbol(symbol: str, top_k: int = 10) -> str:
    """在代码库中检索符号(函数/类/常量)定义位置。

    Args:
        symbol: 要找的符号名
        top_k: 最多返回几个匹配
    """
    # 用 ripgrep 做精确匹配,限定在仓库根内,避免越权读系统文件
    cmd = [
        "rg", "--line-number", "--max-count", "1",
        "--glob", "!*.lock", symbol, str(REPO_ROOT),
    ]
    try:
        out = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
    except subprocess.TimeoutExpired:
        return "⏱️ 超时:检索超过 15 秒被中止"
    lines = out.stdout.splitlines()[:top_k]
    return "\n".join(lines) if lines else "(未找到符号)"

6.4 暴露 Resources 与 Prompts

@mcp.resource("file://docs/{name}")
def read_doc(name: str) -> str:
    """按名称读取 docs/ 下的内部文档,作为模型上下文。"""
    path = (REPO_ROOT / "docs" / f"{name}.md").resolve()
    if not str(path).startswith(str(REPO_ROOT)):
        return "❌ 越权访问"
    return path.read_text(encoding="utf-8", errors="ignore")

@mcp.prompt()
def review_code(diff: str) -> str:
    """生成一段代码评审提示模板。"""
    return f"""你是一名资深工程师,请评审以下 git diff:

{diff}


请重点指出:1) 正确性 bug;2) 安全隐患;3) 可读性;4) 性能问题。每条给出具体修改建议。"""

6.5 启动与接入

if __name__ == "__main__":
    # 默认 stdio 传输;生产远程部署可换成 Streamable HTTP
    mcp.run()

本地用 stdio 跑,什么都不用配;在 Cursor / Claude Desktop 的 mcp.json 里加一行即可接入:

{
  "mcpServers": {
    "pg-readonly": {
      "command": "python",
      "args": ["/abs/path/server.py"],
      "env": { "DATABASE_URL": "postgres://user:pass@localhost/db" }
    }
  }
}

七、代码实战二:TypeScript SDK 的 Resource + Prompt

Python 写后端顺手,前端/全栈团队更常用 TypeScript SDK。下面用 @modelcontextprotocol/sdk 实现带流式日志的 Server:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "ts-demo", version: "0.1.0" });

// Tool:带 zod schema 校验入参
server.tool(
  "calc",
  { expr: z.string().describe("简单算术表达式,如 1+2*3") },
  async ({ expr }) => {
    // 生产环境务必用安全求值器,禁止 eval 用户输入
    const result = safeEval(expr);
    return { content: [{ type: "text", text: String(result) }] };
  }
);

// Resource:暴露项目 README
server.resource("readme", "file:///README.md", async (uri) => ({
  contents: [{ uri: uri.href, text: await Bun.file("README.md").text() }],
}));

// Prompt:需求拆解模板
server.prompt("breakdown", { goal: z.string() }, ({ goal }) => ({
  messages: [{
    role: "user",
    content: { type: "text", text: `把目标「${goal}」拆成可执行的任务清单,按优先级排序。` },
  }],
}));

const transport = new StdioServerTransport();
await server.connect(transport);

TS SDK 的亮点是用 zod 直接定义 inputSchema,类型与校验一体,比手写 JSON Schema 省心。注意:示例代码里的 safeEval 必须替换为真正的沙箱求值(如 eval5 或受限 AST 解释器),绝不能直接 eval 用户字符串——这是 MCP 工具最常见的 RCE 漏洞来源。


八、真实案例:codebase-memory-mcp(26K Star 的架构解剖)

回到开头那个 7 月周榜第二的项目。它问了一个被很多人忽略的问题:

AI 编程 Agent 变强之后,瓶颈已经不是「模型不会写代码」,而是「模型不知道该看哪些代码」。

一个中大型项目里,Agent 为了回答「这个请求怎么走到数据库」,往往要先 grep、再 glob、再 Read 一堆文件,token 哗哗地烧,还经常看漏。codebase-memory-mcp 的解法是:把代码结构预先抽成一张持久化的知识图谱,Agent 直接查图谱,而不是读文件。

8.1 架构:两层解析

源码文件
  │
  ├─ Tree-sitter 语法层(158 种语言)
  │   提取:函数、类、结构体、接口的定义与位置
  │
  └─ Hybrid LSP 语义层(Python/TS/Go/C++/Rust…)
      提取:类型、调用关系、跨文件引用、HTTP 路由
  │
  ▼
持久化知识图谱(SQLite,支持 Cypher 式查询)
  │
  ▼
14 个 MCP 工具(index / query / callers-of / callees-of / routes / …)
  • Tree-sitter 层负责「快而广」:无需类型信息,纯语法就能解析 158 种语言,把函数/类骨架捞出来;
  • Hybrid LSP 层负责「准而深」:借助语言服务器协议拿到类型与跨文件调用链,把「谁调用了谁」「这个 HTTP 路径映射到哪个 handler」这种语义边连上。

两层结合,图谱既有广度又有语义深度。

8.2 三个工程巧思(值得每个做 MCP 的人借鉴)

  1. 本地缓存,拒绝重复扫描:图谱落盘到 SQLite,下次启动直接加载,不再全量重建;
  2. 团队共享压缩图谱:把压缩后的图谱文件提交进 Git,队友拉下来秒加载,跳过十几分钟的全量索引——这是「索引即产物」思想的落地;
  3. 增量更新:只对比代码变更,刷新受影响的调用链子图,而不是推倒重来。

8.3 性能数据(官方口径)

  • Linux 内核(约 2800 万行、7.5 万文件)全量建图约 3 分钟
  • 结构化查询响应 < 1ms
  • 相比反复读文件,Agent 的 token 消耗下降约 99%
  • 单一静态二进制分发(v0.5.0 起由 Go 重写为 C),零依赖,mac/Linux/Win 通吃。

对我们的启发:codebase-memory-mcp 本质是「把昂贵的离线预处理,换成便宜的在线查询」。这个模式可以套用到任何「Agent 反复读大块上下文」的场景——文档库、API 规范、日志归档,都值得抽成图谱/索引再暴露成 MCP 工具。


九、生产级考量(上线的硬门槛)

Demo 跑通容易,上生产有五道坎。

9.1 并发与隔离

stdio Server 通常是「一个 Client 一个进程」,天然隔离;但远程 Streamable HTTP Server 会面对多会话并发。工具内部如果有全局可变状态(如示例里的 _pool 是安全的连接池,但若有模块级字典存用户数据就危险),必须用 per-session 状态或干脆无状态化。无状态模式 + 外部存储(Redis/DB)是云上首选。

9.2 超时与取消

工具的耗时不可控。必须:

  • 给每个外部调用(SQL、HTTP、subprocess)设 timeout
  • 监听 MCP 的 cancelled 通知,及时中止底层操作(如数据库 cnx.cancel()、子进程 kill);
  • 超时返回结构化错误,而不是让整个会话卡死。

9.3 错误处理:让模型优雅失败

工具失败不是抛异常就完了,而是返回模型能理解的、可行动的错误信息。对比:

# 差:模型拿到这个只会困惑
"Exception: timeout"

# 好:模型能自我纠正
"⏱️ 查询超时(>15s)。建议:缩小时间范围,或只查 1 个表。"

9.4 安全边界:给不确定性套缰绳

因为「调不调用、调什么」由模型决定,安全必须前置:

  • 最小权限:只读库就用只读账号;工具能不写就不写;
  • 工具分级:破坏性工具(删除、部署)标注 destructive,Host 端要求用户二次确认;
  • Secrets 不外泄:工具返回里绝不回显密码、token;
  • 输入白名单:标识符类参数(表名、路径)必须白名单/路径前缀校验,防越权读 /etc/passwd
  • 远程必鉴权:HTTP Server 一律 OAuth 2.0,不裸奔。

9.5 可观测性

  • logging/setLevel + notifications/message 把 Server 内部日志回流到 Host;
  • 关键路径埋 trace_id,把 tools/call 的入参、耗时、结果落到日志系统;
  • 监控工具调用成功率、P99 耗时、超时率——这决定了你能否在模型「乱调工具」时及时发现。

十、常见陷阱与排错清单

现象90% 的原因修法
工具不显示Server 没声明 tools capability,或 tools/list 报错initialize 响应,确认 capabilities
模型填错参数inputSchema 描述不清 / 缺 required写清 description,约束类型
调用卡住工具无超时、长连接阻塞加 timeout + cancelled 监听
远程连不上Streamable HTTP 端点/鉴权错核对 /mcp 路径与 OAuth 流程
权限被拒Roots 没配,Server 越权访问Client 端声明 roots
中文乱码日志/返回未按 UTF-8Server 统一 UTF-8 输出

十一、总结与展望:MCP 在 2026 的位置

回看开头那句话——MCP 给 AI Agent 装上了「USB-C 接口」。一年前的「N×M 集成地狱」,如今变成了「写一次、处处用」。

到 2026 年 7 月,几个趋势已经明确:

  1. 协议标准化:捐赠 Linux Foundation,版本协商机制成熟,厂商各自为战的日子结束;
  2. 传输云原生化:Streamable HTTP 让 MCP Server 能像普通微服务一样部署、扩缩、上 Serverless;
  3. 生态规模化:400+ 开源 Server,覆盖数据库、文件系统、SaaS、IoT;
  4. 企业级落地:腾讯云、百度智能云等提供全生命周期 MCP 服务,从「开发者玩具」走向「企业基础设施」;
  5. 垂直深化:像 codebase-memory-mcp 这样的项目,把「Agent 不知道看哪段代码」的瓶颈用知识图谱化解,token 成本砍掉 99%——这预示着 MCP 的竞争会从「工具有没有」转向「上下文质量高不高」。

对工程师的实操建议:现在就把你团队里那些「模型反复读取的大块上下文」抽成 MCP 工具——文档、规范、代码索引、工单。哪个 Agent 接上都能用,一次建设,处处受益。这比追每一个新模型都更划算。

毕竟,模型会越来越强,但「让模型高效、安全、低成本地接入你的世界」,永远是工程价值的高地。MCP,就是这块高地上目前最稳的那块地基。


参考资料方向:Anthropic MCP 官方规范(2024-11-05 / 2025-03-26 / 2025-06-18 修订)、GitHub 项目 DeusData/codebase-memory-mcp、Panniantong/Agent-Reach,以及 2026 年 7 月 GitHub 周榜趋势。

推荐文章

robots.txt 的写法及用法
2024-11-19 01:44:21 +0800 CST
php常用的正则表达式
2024-11-19 03:48:35 +0800 CST
使用 `nohup` 命令的概述及案例
2024-11-18 08:18:36 +0800 CST
程序员茄子在线接单