尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用MCP在朋友之间共享上下文:从零搭建最小可用的MCP Server

用MCP在朋友之间共享上下文:从零搭建最小可用的MCP Server 最近在 Hacker News 上看到一个很有意思的项目Show HN: Share context between friends via MCP。第一眼看到这个标题时我想到的是“两个 AI 助手之间怎么互相传递上下文”但点进去仔细想了一下它真正想解决的问题其实更朴素不同的人、不同的工具、不同的 AI 会话如何围绕同一份“上下文”协作。如果你最近在关注 MCP可能会发现它已经从一个“Anthropic 推出的协议”演变成了整个 AI 工具链的通用接口。热词里频繁出现MCP Server、Dify 本地 MCP、Codex MCP、.mcp文件说明大家都已经开始在实际项目中接入 MCP 了。这篇文章就围绕“通过 MCP 在朋友之间共享上下文”这个方向展开带大家从协议概念入手完整实现一个最小可用的 MCP Server并接入常见客户端跑通闭环。全文会覆盖MCP 的核心架构、共享上下文的业务模型、Python 实现思路、客户端配置方案、高频报错排查以及工程化落地的注意事项。无论你是第一次接触 MCP 协议还是已经在项目里接入过 MCP 工具都可以在这篇文章里找到可以复用的内容。1. 为什么要用 MCP 做上下文共享1.1 Model Context Protocol 是什么MCP 全称是 Model Context Protocol翻译过来是“模型上下文协议”。它由 Anthropic 在 2024 年底提出目标是统一大模型与外部工具、数据源之间的交互方式。在没有 MCP 之前大模型应用接入外部能力通常要写很多胶水代码调用数据库需要自己封装 JDBC、连接池、SQL 拼接。调用搜索引擎需要引入对应 SDK处理签名、重试、限流。调用企业内部系统需要定制 HTTP 接口再配置鉴权。更麻烦的是每个 AI 产品接入方式都不同。你今天给 Claude 写了一个插件明天要迁移到 Dify可能又要重写一遍。MCP 就是为了解决这个“重复造轮子”的问题它定义了一套标准化的 Client-Server 结构让模型成为客户端通过一个协议就能访问任意符合规范的“工具服务端”。用一句话概括MCP 是把大模型可以调用的能力做成了类似于 USB 接口的标准插口。服务端实现好这个插口客户端插上就能用。1.2 “朋友之间的上下文共享”解决什么问题常规的 MCP 教程大多围绕“让 AI 查数据库”“让 AI 调 API”来展开。Share context between friends via MCP这个方向把视角切到了“上下文本身”的流通上。这里说的 context可以是一段高质量的对话记录。一份会议纪要或者技术方案。一个值得收藏的代码片段、报错日志。一次 AI 工具分析出来的结论和背景材料。举个例子你和朋友都在用 AI 辅助写代码你花了一上午排查了一个 WebGL 报错最后发现是 Canvas Context 创建失败导致的。这个结论和排查过程很有价值如果通过 MCP 共享出去朋友那边的 AI 助手就能直接搜索到这段“上下文”下次遇到类似问题就不需要从零开始排查。所以这个项目的核心思路是构建一个 MCP Server用来存取和搜索结构化的上下文记录。朋友之间不再是手工转发聊天记录而是让各自的 AI 工具通过协议自动读取、检索、复用这些内容。1.3 目标拆解一个最小可用的 MCP Server我们最终要实现的东西并不复杂为了便于理解先拆成三个 Toolshare_context发布一条上下文记录包含作者、标题、正文、标签。search_context按照关键词搜索所有朋友共享的上下文。recent_contexts获取最新的上下文信息流类似一个“好友知识动态”。这个模型足够简单但已经覆盖了 MCP Server 最关键的开发路径数据存储、工具注册、参数校验、结果返回。跑通之后你可以很容易地扩展权限管理、评论互动、多人群组、跨设备同步等能力。2. 环境准备与协议核心概念2.1 技术选型与环境说明MCP 官方提供了 Python 和 TypeScript 两套 SDK社区里也有 Java、Go、C#、Rust 等语言实现。本文选择 Python因为语言上手快且mcpPython SDK 对 stdio 传输方式支持得很好。环境项建议操作系统Windows / macOS / Linux 均可建议使用 Linux 或 macOS 做服务器验证Python3.10 及以上MCP SDKmcpPython 包安装最新版即可数据库SQLitePython 内置支持不需要额外启动服务客户端Claude Desktop、Dify、Codex 等支持 MCP 的 AI 工具需要注意的是MCP 协议和 SDK 仍在快速演进。不同版本的 Python SDK 在 API 细节上可能有差异比如FastMCP的位置、mcp.tool()装饰器的写法请以你安装版本的官方文档为准。本文代码示例在 2025 年上半年的主流版本上验证过思路遇到报错优先查看版本对应文档。2.2 传输方式stdio 与 HTTPMCP 支持两种主流传输方式stdioClient 以子进程方式启动 Server 进程通过标准输入输出传输 JSON-RPC 消息。本地开发和小型工具最常用配置简单不需要暴露端口安全性也更好。HTTP / SSEServer 作为一个独立服务通过 HTTP 或 SSE 长连接与 Client 通信。适合部署在服务器上供多个客户端远程访问也适合集成到 Web 应用里。在“朋友之间共享上下文”这个场景里本地开发可以先走 stdio如果要做成像“共享知识库”那样多人远程使用的服务建议后续切换到 HTTP 方式。2.3 MCP 的工具、资源与提示词MCP 协议中Server 主要对外暴露三类能力Tool可执行的函数模型在需要时自动调用返回结构化结果。适合“操作”类能力比如写入数据、触发任务。Resource可读取的上下文数据通过 URI 定位适合“数据”类能力比如读取文件、数据库记录。Prompt预定义的提示词模板方便客户端快速复用。在共享上下文的场景中发布和搜索功能适合做成 Tool如果你希望某个特定上下文能被客户端像文件一样直接读取也可以把内容暴露成 Resource。3. 搭建 friend-context 共享服务3.1 初始化项目首先创建项目目录和虚拟环境mkdir friend-context-mcp cd friend-context-mcp python -m venv .venv source .venv/bin/activate # Windows 下使用 .venv\Scripts\activate pip install mcp项目结构如下friend-context-mcp/ ├── pyproject.toml ├── friend_context/ │ ├── __init__.py │ ├── db.py │ └── server.py └── .mcp.json其中db.py负责 SQLite 初始化和数据操作server.py负责注册 MCP 工具并启动服务。3.2 数据表设计共享上下文的核心数据是“用户”和“上下文记录”。一个用户可以有多个上下文记录一条上下文可以被多个好友搜索到。为了后续扩展我们再加一张评论表。文件路径friend_context/db.pyimport json import sqlite3 from datetime import datetime, timezone from pathlib import Path DB_PATH Path(__file__).parent / shared_context.db def get_conn() - sqlite3.Connection: conn sqlite3.connect(DB_PATH) conn.row_factory sqlite3.Row return conn def now_str() - str: return datetime.now(timezone.utc).isoformat() def init_db() - None: with get_conn() as conn: conn.executescript( CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, nickname TEXT, created_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS contexts ( id INTEGER PRIMARY KEY AUTOINCREMENT, author_id INTEGER NOT NULL REFERENCES users(id), title TEXT NOT NULL, content TEXT NOT NULL, tags TEXT NOT NULL DEFAULT [], created_at TEXT NOT NULL, updated_at TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS comments ( id INTEGER PRIMARY KEY AUTOINCREMENT, context_id INTEGER NOT NULL REFERENCES contexts(id), author_id INTEGER NOT NULL REFERENCES users(id), content TEXT NOT NULL, created_at TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_contexts_author ON contexts(author_id); CREATE INDEX IF NOT EXISTS idx_contexts_created ON contexts(created_at DESC); )这里使用 SQLite 作为存储层优点是零配置、单文件、方便迁移。如果你需要更强的并发支持后续可以替换为 MySQL 或 PostgreSQLSQL 基本不用大改。3.3 实现分享上下文工具接下来在server.py中创建 MCP Server 实例并实现share_context工具。文件路径friend_context/server.pyimport json from typing import Any, Optional from mcp.server.fastmcp import FastMCP from friend_context.db import get_conn, init_db, now_str mcp FastMCP(friend-context-server) def _ensure_user(username: str, nickname: str ) - int: 确保用户存在返回用户 id。 with get_conn() as conn: row conn.execute( SELECT id FROM users WHERE username ?, (username,) ).fetchone() if row: return row[id] cur conn.execute( INSERT INTO users (username, nickname, created_at) VALUES (?, ?, ?), (username, nickname or username, now_str()), ) return cur.lastrowid mcp.tool() def share_context( username: str, title: str, content: str, tags: Optional[list[str]] None, ) - dict[str, Any]: 把一条上下文记录分享给好友。 Args: username: 当前用户的用户名。 title: 上下文标题建议 50 字以内方便搜索。 content: 正文内容。 tags: 可选标签列表例如 [AI, MCP, 排错]。 user_id _ensure_user(username.strip()) tags_json json.dumps(tags or [], ensure_asciiFalse) now now_str() with get_conn() as conn: cur conn.execute( INSERT INTO contexts (author_id, title, content, tags, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?) , (user_id, title.strip(), content.strip(), tags_json, now, now), ) context_id cur.lastrowid return { id: context_id, status: shared, created_by: username.strip(), created_at: now, }这里需要注意几个细节_ensure_user采用“按用户名查找不存在则创建”的策略避免每次调用都重复建用户。tags用 JSON 字符串存储读取时再反序列化方便扩展为数组过滤。share_context的 docstring 会被 MCP 协议读取作为工具的说明和参数注释所以描述要写清楚。3.4 实现搜索与信息流工具有了数据写入还需要支持查询。下面实现search_context和recent_contexts。mcp.tool() def search_context( query: str, username: str , limit: int 10, ) - dict[str, Any]: 在好友共享的上下文中搜索关键词。 Args: query: 要搜索的关键词会匹配标题、正文和标签。 username: 可选按作者过滤。 limit: 返回数量默认 10最大 50。 like f%{query.strip()}% params: list[Any] [like, like, like] sql SELECT c.id, c.title, c.content, c.tags, c.created_at, u.username AS author FROM contexts c JOIN users u ON u.id c.author_id WHERE c.title LIKE ? OR c.content LIKE ? OR c.tags LIKE ? if username.strip(): sql AND u.username ? params.append(username.strip()) sql ORDER BY c.created_at DESC LIMIT ? params.append(min(limit, 50)) with get_conn() as conn: rows conn.execute(sql, params).fetchall() items [] for row in rows: items.append( { id: row[id], author: row[author], title: row[title], content: row[content], tags: json.loads(row[tags]), created_at: row[created_at], } ) return {query: query.strip(), total: len(items), items: items} mcp.tool() def recent_contexts(limit: int 20) - dict[str, Any]: 获取好友们最新共享的上下文列表按发布时间倒序排列。 with get_conn() as conn: rows conn.execute( SELECT c.id, c.title, c.content, c.tags, c.created_at, u.username AS author FROM contexts c JOIN users u ON u.id c.author_id ORDER BY c.created_at DESC LIMIT ? , (min(limit, 50),), ).fetchall() items [] for row in rows: items.append( { id: row[id], author: row[author], title: row[title], content: row[content], tags: json.loads(row[tags]), created_at: row[created_at], } ) return {total: len(items), items: items}搜索使用LIKE模糊匹配对于最小版本足够。如果后续数据量变大建议引入全文索引或者 ES避免LIKE全表扫描。3.5 启动服务在server.py末尾添加入口def main() - None: init_db() mcp.run() if __name__ __main__: main()创建friend_context/__init__.py内容可以为空用于标识 Python 包。创建pyproject.toml方便安装和命令行调用[project] name friend-context-mcp version 0.1.0 description Share context between friends via MCP requires-python 3.10 dependencies [ mcp, ] [project.scripts] friend-context-server friend_context.server:main安装到当前环境pip install -e .然后启动friend-context-server如果看到类似于MCP server running on stdio的输出说明服务已经启动等待客户端连接。4. 配置 MCP 客户端4.1 Claude Desktop 配置Claude Desktop 支持通过配置文件加载本地 MCP Server。找到 Claude Desktop 的配置文件claude_desktop_config.json添加如下内容{ mcpServers: { friend-context: { command: python, args: [-m, friend_context.server] } } }如果你的 Python 环境是虚拟环境command需要改成虚拟环境里的 Python 绝对路径否则客户端可能找不到依赖包。重启 Claude Desktop在对话中就可以直接让模型调用分享和搜索工具。例如输入帮我搜索一下最近关于 MCP 上下文共享的学习笔记。模型会自动调用search_context把结果整理后回复给你。4.2 Dify 本地 MCP 服务配置Dify 目前也支持接入 MCP 工具。在 Dify 的工具配置页面选择 MCP添加本地服务时需要根据 Dify 版本选择传输方式。如果 Dify 运行在 Docker 容器中访问宿主机上的 stdio MCP Server 会比较麻烦因为子进程调用发生在容器内部。更推荐的方式是先把 MCP Server 以 HTTP 模式启动然后在 Dify 中配置 SSE 或 Streamable HTTP 地址。这里给出一个通过uvicorn或 FastMCP 内置 HTTP 能力启动的思路具体配置项以 Dify 版本的界面提示为准。核心是在 MCP Server 端增加远程访问能力然后确保地址可达。4.3 使用 .mcp.json 管理开发环境配置越来越多的 IDE 和开发工具支持.mcp.json文件来声明 MCP Server。这个文件通常放在项目根目录格式如下{ mcpServers: { friend-context: { command: python, args: [-m, friend_context.server], env: { FRIEND_CONTEXT_DB: /absolute/path/to/shared_context.db } } } }使用.mcp.json的好处是项目克隆下来后团队成员不需要手动配置IDE 会自动识别。如果你最近看到“Win 系统上怎么创建 MCP”“.mcp 文件”这类问题基本都是在配置这一步遇到困惑核心就是确认 json 格式和路径正确。4.4 验证调用效果在任意 MCP 客户端中如果配置成功应该能看到三个工具share_contextsearch_contextrecent_contexts每个工具都有完整的参数描述。调用share_context后返回值中会包含新记录的id。再次调用search_context输入刚才标题中的关键词就能检索到这条记录。可以做一个简单验证# 如果你用 Python 写测试脚本可以直接调用 MCP 暴露的接口 python -c from friend_context.server import share_context, search_context print(share_context(usernamealice, titleMCP上下文共享笔记, content通过MCP在朋友之间共享上下文。, tags[MCP])) print(search_context(queryMCP, limit5)) 预期第一次输出会返回status: shared第二次输出能看到total: 1并包含刚才的内容片段。5. 常见问题与排查思路MCP 环境的问题往往不在代码本身而是集中在客户端连接、版本兼容和参数格式上。我把高频问题整理成表格。问题现象常见原因解决思路客户端提示连接 MCP Server 失败command或args配置错误Python 环境不对使用绝对路径的 Python先命令行启动一次确认无报错工具调用后返回Tool not foundMCP Server 没有成功注册工具或客户端缓存了旧配置重启客户端查看 Server 启动日志确认装饰器生效远程访问时连接超时服务器没有开启 HTTP / SSE 模式防火墙拦截端口改用 HTTP 模式检查端口监听和防火墙规则参数报错提示缺少username模型没有理解参数说明或 docstring 描述不清晰给工具补充更明确的参数说明设置合理默认值模型认为没有权限查看内容Server 端未提供鉴权能力客户端认证未通过增加 token 或认证头注意最小权限原则Context Window 被撑爆返回给模型的内容过多在工具返回结果时做截断、分页限制单次返回长度5.1 客户端连不上 Server这是最常遇到的问题。检查顺序如下先手动在终端执行python -m friend_context.server看有没有报错。确认客户端配置里的command指向正确的 Python。确认args里的路径和模块名正确。查看客户端日志定位是否已经启动子进程。5.2 Context Window 被撑爆热词里能看到很多关于 “Context Window”“Context automatically compacting” 的讨论。当 MCP 工具返回大量内容时模型上下文会迅速膨胀。解决方案工具返回内容做裁剪正文只保留前 N 个字符。使用分页参数一次只返回一页。让模型优先返回摘要再按需获取完整内容。5.3 跨语言调用很多后端团队会问“Java 怎么连接 MCP 服务”。MCP 是传输协议和语言无关。你可以在 Java 项目中通过 MCP Java SDK 建立 Client也可以直接用 HTTP 方式调用远程 MCP Server。只要协议兼容Python 写的 Server 可以被任意语言写的 Client 调用。5.4 版本兼容性MCP 协议版本和 SDK 版本比较接近但不是完全画等号。SDK 升级后构造方式和装饰器写法可能变化。遇到诡异问题时优先锁定mcp包版本再对照官方迁移文档调整。6. 最佳实践与工程化建议6.1 权限与数据安全“朋友之间共享”听起来很美好但落到工程上必须考虑权限边界。默认私密上下文默认只给作者自己使用分享时才开放给指定好友或群组。最小权限MCP Server 不应该自动暴露所有数据建议按工具粒度控制访问范围。认证授权如果采用 HTTP 模式务必在网关层加入 API Key、OAuth 或至少一个简单的 token 校验。在自己本地测试时可以不加密但一旦部署到公网未授权访问会导致上下文内容泄露这一点要格外谨慎。6.2 上下文格式规范化上下文内容质量决定了好友能不能高效检索到。建议在写入前做规范处理标题控制在 50 字以内突出核心关键词。正文区分“背景、现象、排查过程、结论”几个段落。标签统一风格比如全部小写使用连字符或中文短标签二选一不要混用。def normalize_tags(tags: list[str] | None) - list[str]: if not tags: return [] normalized [] for tag in tags: tag tag.strip().lower().replace( , -) if tag and tag not in normalized: normalized.append(tag) return normalized[:10]使用统一的规范化函数可以避免MCP、mcp、MCP被当成三个不同标签。6.3 日志与可观测性MCP Server 虽然小巧但在生产环境中也要有日志。重点记录谁调用了哪个工具。返回结果大小。耗时和错误类型。工具参数脱敏后的摘要。Python 内置的logging模块就够用关键点是把日志输出到独立文件避免和 stdio 混淆。因为 stdio 是 MCP 协议的通信通道日志如果直接打到标准输出会干扰 Client-Server 通信。6.4 生产部署建议如果你要把共享上下文服务部署成多人使用的远程服务建议使用数据库替代 SQLite 文件或者确保 SQLite 文件定期备份。将 MCP Server 以 HTTP 模式部署到内网或公网统一走网关。为数据表增加updated_at和删除标记方便做数据同步和软删除。对搜索结果做排序优化按匹配度、更新时间、热度综合排序。7. 总结与后续方向本文从一个 Hacker News 上的创意出发完整梳理了“通过 MCP 在朋友之间共享上下文”的实现路径。你可以从零搭建一个基于 SQLite 的 MCP Server暴露share_context、search_context、recent_contexts三个工具再接入 Claude Desktop、Dify 等客户端让不同 AI 工具共享同一份上下文记忆。实际项目中你最需要关注的风险是权限边界和上下文规模。MCP 让数据流通变得简单也意味着一旦 Server 暴露私密上下文可能被任意客户端读取。生产环境一定要走认证授权并且对工具返回值做限流和裁剪避免把 Context Window 撑爆。下一步建议往这几个方向深入把工具从本地 stdio 迁移到 HTTP 模式支持多设备访问。引入用户好友关系表实现基于好友关系的动态授权。使用向量数据库做语义搜索替代现在的LIKE模糊匹配。把上下文同步能力封装成 Resource让客户端可以像读文件一样读取上下文。如果你身边也有一起用 AI 工具的朋友不妨直接按这套思路搭一个小组件把各自的踩坑笔记和重要结论共享起来。跑通之后你会发现MCP 的价值不只是“让 AI 会调工具”更是让 AI 之间、人与 AI 之间的上下文真正流动起来。
返回列表