news 2026/9/5 19:38:45

MCP servers 仓库 Everything Server 项目结构详解:目录布局、模块职责与源码级实现导读

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MCP servers 仓库 Everything Server 项目结构详解:目录布局、模块职责与源码级实现导读

MCP servers 仓库 Everything Server 项目结构详解:目录布局、模块职责与源码级实现导读

【免费下载链接】serversModel Context Protocol Servers项目地址: https://gitcode.com/GitHub_Trending/se/servers

本文基于src/everything/docs/structure.md这份官方结构文档展开,逐目录、逐文件地讲解 MCP "Everything" 参考服务器的项目组织方式:入口与传输选择、文档体系、prompts / resources / tools 三大原语的注册编排、server 工厂与 transport 层的落地实现。读完之后,你可以快速定位任意功能对应的源码文件,理解各模块之间的调用关系,并按照仓库既有模式为该服务器新增工具、资源、提示词或传输方式。

总体目录布局

structure.md首先给出了一份完整的目录树,这是理解整个 Everything Server 的骨架:

src/everything ├── index.ts ├── AGENTS.md ├── package.json ├── docs │ ├── architecture.md │ ├── extension.md │ ├── features.md │ ├── how-it-works.md │ ├── instructions.md │ ├── startup.md │ └── structure.md ├── prompts │ ├── index.ts │ ├── args.ts │ ├── completions.ts │ ├── simple.ts │ └── resource.ts ├── resources │ ├── index.ts │ ├── files.ts │ ├── session.ts │ ├── subscriptions.ts │ └── templates.ts ├── server │ ├── index.ts │ ├── logging.ts │ └── roots.ts ├── tools │ ├── index.ts │ ├── echo.ts │ ├── get-annotated-message.ts │ ├── get-env.ts │ ├── get-resource-links.ts │ ├── get-resource-reference.ts │ ├── get-roots-list.ts │ ├── get-structured-content.ts │ ├── get-sum.ts │ ├── get-tiny-image.ts │ ├── gzip-file-as-resource.ts │ ├── simulate-research-query.ts │ ├── toggle-simulated-logging.ts │ ├── toggle-subscriber-updates.ts │ ├── trigger-elicitation-request.ts │ ├── trigger-elicitation-request-async.ts │ ├── trigger-long-running-operation.ts │ ├── trigger-sampling-request.ts │ ├── trigger-sampling-request-async.ts │ └── trigger-url-elicitation.ts └── transports ├── sse.ts ├── stdio.ts └── streamableHttp.ts

从目录树可以清楚看到分层思路:prompts/resources/tools/分别承载 MCP 协议三大原语,每个目录内部都是"一个index.ts编排器 + 每个功能一个文件"的模式;server/负责组装服务器实例;transports/负责三种通信方式(stdio、SSE、Streamable HTTP);docs/则是随构建一起打包进发行产物的文档集。同一套文档导航中还包括 架构说明、扩展指南、功能清单、工作原理 与 启动流程,结构文档与它们互为补充。

入口层:index.ts、AGENTS.md 与 package.json

index.ts:基于第一个 CLI 参数选择传输

index.ts 是整个服务器的启动入口,逻辑非常克制:

  • 读取process.argv,取第一个参数作为传输名,缺省为stdio
  • 通过switch分支动态import对应的传输模块(./transports/stdio.js./transports/sse.js./transports/streamableHttp.js),从而保证只有被请求的传输模块会被加载和执行,避免其他模块在未被使用时就完成初始化;
  • 遇到未知参数时打印使用说明(node ./index.js [stdio|sse|streamableHttp])并以退出码 1 结束。

对应到 npm scripts 上,就是 package.json 中的三个启动命令:

"start:stdio": "node dist/index.js stdio", "start:sse": "node dist/index.js sse", "start:streamableHttp": "node dist/index.js streamableHttp"

AGENTS.md:面向 Agent 的编码规范

AGENTS.md 是写给 Agent / LLM 的开发者指南,规定了构建与运行命令、代码风格(ES 模块 +.js导入后缀、严格类型、zod schema 校验、2 空格缩进、camelCase / PascalCase / kebab-case 的命名约定等),以及扩展服务器的规则:新工具、资源、提示词分别放在对应目录,导出registerX(server)函数,再接入中心index.ts编排。它相当于把"如何正确地扩展这个服务器"固化成了可被机器读取的约束。

package.json:元数据、脚本与依赖

package.json 声明了包名@modelcontextprotocol/server-everything(当前版本 2.0.0),bin字段将dist/index.js暴露为mcp-server-everything可执行命令,files只发布dist目录。关键脚本为:

"build": "tsc && shx cp -r docs dist/ && shx chmod +x dist/*.js", "watch": "tsc --watch", "test": "vitest run --coverage"

build脚本做了三件事:TypeScript 编译到dist/、把docs/原样复制到dist/(这就是server/index.ts启动时能读到instructions.md的前提)、标记编译后的入口脚本可执行。依赖方面,运行时依赖@modelcontextprotocol/sdkexpresscorszodjszip;开发依赖含typescriptvitestprettiershx

docs/ 文档体系

docs/目录在结构文档中被逐一列出,每个文件承担明确职责:

文件职责
architecture.md描述服务器架构:传输层、会话初始化、原语注册
extension.md讲解如何扩展新工具、提示词、资源或传输
features.md完整的功能参考:所有 prompts、resources、tools 与协议行为
how-it-works.mdSSE 与 Streamable HTTP 传输的搭建方式与 session 管理
instructions.md人类可读的使用指引,启动时被服务器读取并在 initialize 交互中返回给客户端
startup.md启动时序、环境检查与初始化
structure.md即本文所依据的结构文档

其中instructions.md有特殊的运行时身份:readInstructions()会在服务器创建时把它读入内存。从 resources/index.ts 的readInstructions实现可以看到,它按相对路径docs/instructions.md读取文件,读取失败时返回一条错误说明字符串而不是抛异常——这解释了为什么构建脚本必须把docs/复制到dist/中一起发布。

prompts/ 提示词目录

prompts/的 index.ts 提供registerPrompts(server)编排函数,把注册工作委托给各个提示词文件:

  • simple.ts:注册simple-prompt,无参数,返回单条用户消息;
  • args.ts:注册args-prompt,带两个参数(city必填、state可选),用于演示参数化消息拼装;
  • completions.ts:注册completable-prompt,参数使用 SDK 的completable(...)助手支持服务器驱动的补全(如department以及上下文相关的name补全);
  • resource.ts:导出registerEmbeddedResourcePrompt(server),注册resource-prompt——接受resourceType("Text" 或 "Blob")与resourceId(整数),在返回消息中嵌入一个动态生成的指定类型资源。它内部直接复用resources/templates.ts暴露的构造函数,是"资源与提示词跨模块协作"的典型示例。

resources/ 资源目录

resources/实际包含五个文件,index.ts 中的编排器只做两件事:

export const registerResources = (server: McpServer) => { registerResourceTemplates(server); registerFileResources(server); };

templates.ts:两个动态模板资源

templates.ts 通过ResourceTemplate注册两个模板驱动的动态资源:

  • 文本:demo://resource/dynamic/text/{resourceId}(MIMEtext/plain
  • 二进制:demo://resource/dynamic/blob/{resourceId}(MIMEapplication/octet-stream,Base64 载荷)

结构文档称该路径变量为{index},其约束是必须为有限的正整数;源码中的parseResourceId(templates.ts)正是这样校验的——非正整数或未知 URI 会抛出Unknown resource错误。内容在请求时才生成,并带当前时间戳。此外还注册了resourceId的模板补全函数,只接受正整数字符串。

该文件还对外暴露四个辅助函数,供其他模块(尤其是resource-prompt)直接构造动态资源:

textResource(uri, resourceId) // 生成文本型动态资源 textResourceUri(resourceId) // 生成 demo://resource/dynamic/text/{id} blobResource(uri, resourceId) // 生成 Blob 型动态资源 blobResourceUri(resourceId) // 生成 demo://resource/dynamic/blob/{id}

files.ts:静态文件资源

files.tsdocs/目录下每个文件注册一个静态资源,URI 遵循demo://resource/static/document/<filename>模式;MIME 类型按扩展名映射:.mdtext/markdown.txttext/plain.jsonapplication/json,其余默认text/plain

session.tssubscriptions.ts

结构文档对这两个文件的描述较简略,但它们承担会话级能力:

  • session.ts:提供按会话注册/查找临时资源的机制。gzip-file-as-resource工具就用它把压缩后的 Blob 注册为会话资源,URI 形如demo://resource/session/<name>mimeType: application/gzip,生命周期仅限当前会话;
  • subscriptions.ts:server/index.ts 从这里导入setSubscriptionHandlersstopSimulatedResourceUpdates,前者为服务器挂接资源订阅处理,后者在会话清理时停止模拟的资源更新检查(配合toggle-subscriber-updates工具触发)。

server/ 服务器组装

index.ts:服务器工厂

server/index.ts 导出createServer()工厂函数,返回{ server, cleanup }

  1. 通过readInstructions()载入服务器指令;
  2. 创建InMemoryTaskStoreInMemoryTaskMessageQueue,以支持实验性 Tasks 能力;
  3. 构造McpServer,声明能力包括tools.listChangedprompts.listChangedresources.subscribe/listChangedlogging,以及tasks(list、cancel 与tools.call请求);
  4. 依次调用registerTools(server)registerResources(server)registerPrompts(server),再挂接setSubscriptionHandlers(server)
  5. 注册oninitialized钩子:在客户端能力已知后注册条件工具(见下文 tools 一节),并在 350ms 延迟后调用syncRoots同步 roots(注释说明延迟是为了避免在notifications/initialized处理完成前发出请求导致丢失,见 server/index.ts);
  6. cleanup(sessionId)负责会话结束时的收尾:停止模拟日志(stopSimulatedLogging)、停止模拟资源更新、清理 task store 定时器、清除初始化超时。

传输层在客户端断开时调用cleanup(),这是"服务器状态与传输生命周期解耦"的关键设计。

logging.tsroots.ts

  • logging.ts:实现模拟日志——按随机间隔向客户端会话发送不同级别的日志消息,由toggle-simulated-logging工具按需启停;
  • roots.ts:提供syncRoots,在初始化后向客户端请求 roots 列表并缓存,供get-roots-list工具返回"客户端最近一次发送的 roots"。

tools/ 工具目录:两级注册机制

结构文档将tools/index.ts描述为registerTools(server)编排器。深入 tools/index.ts 源码可以看到,实际存在两级注册

export const registerTools = (server: McpServer) => { registerEchoTool(server); registerGetAnnotatedMessageTool(server); // ... 共 13 个无条件工具 }; export const registerConditionalTools = (server: McpServer) => { registerGetRootsListTool(server); registerTriggerElicitationRequestTool(server); // ... 其余依赖客户端能力的工具 };

第一级在createServer()中立即执行,注册与客户端能力无关的工具;第二级registerConditionalToolsserver.server.oninitialized中执行,因为rootselicitationsampling、Tasks 等工具依赖客户端在 initialize 阶段声明的能力。这一分层在 server/index.ts 中有对应调用,是理解该服务器启动时序的重要细节。

各工具的职责(沿用结构文档描述,并对照源码印证):

  • echo.ts:接收消息并返回Echo: {message}
  • get-annotated-message.ts:演示内容级注解——按messageType"error" | "success" | "debug")输出带priorityaudience注解的主文本消息,includeImage为 true 时附带一张小型 PNG 图片;该服务器所有工具均带工具级注解(readOnlyHintdestructiveHintidempotentHintopenWorldHint);
  • get-env.ts:以格式化 JSON 返回当前进程环境变量,便于调试配置;
  • get-resource-links.ts:返回一段引导text块加多个resource_link项;
  • get-resource-reference.ts:返回选定动态资源的引用;
  • get-roots-list.ts:返回客户端最近一次发送的 roots 列表;
  • get-structured-content.ts:演示structuredContent结构化响应;
  • get-sum.ts:Zod 输入 schema,求ab之和;
  • get-tiny-image.ts:返回一张小型 PNG(MCP 徽标)image内容及说明文本;
  • trigger-long-running-operation.ts:按duration(秒)与steps数模拟长时任务,客户端提供progressToken时发送notifications/progress进度通知;
  • toggle-simulated-logging.ts/toggle-subscriber-updates.ts:分别启停当前会话的模拟日志与模拟资源订阅更新检查;
  • trigger-elicitation-request.ts:向客户端/LLM 发起elicitation/create并返回结果;
  • trigger-elicitation-request-async.ts:演示双向 Tasks——带任务元数据发起 elicitation 请求,随后轮询客户端tasks/get端点获取完成状态再取最终结果;
  • trigger-sampling-request.ts/trigger-sampling-request-async.ts:同步与基于双向任务的sampling/createMessage请求演示;
  • trigger-url-elicitation.ts:发送带外 URL 模式(mode: "url",含elicitationId请求路径)的 elicitation 请求,或抛出UrlElicitationRequiredError(错误码-32042)走客户端处理路径;错误路径携带的前置 elicitation 指向不同 URL(https://modelcontextprotocol.io),客户端满足后重试同一调用时忽略errorPath改走请求路径,避免客户端在同一错误上死循环;
  • simulate-research-query.ts:基于 MCP Tasks(SEP-1686)的任务型工具,模拟带进度更新的多阶段研究操作;当查询被标记为含糊且客户端支持 elicitation 时,会在执行中途暂停并通过elicitation/create请求澄清,使用server.experimental.tasks.registerToolTask()execution: { taskSupport: "required" }
  • gzip-file-as-resource.ts:抓取 URL 或 data URI 内容并 gzip 压缩,默认返回指向会话级资源的resource_link,也可返回内联resource(含 gzip 数据);该会话资源在会话期间可通过resources/list发现。它受三个环境变量控制:
    • GZIP_MAX_FETCH_SIZE(字节,默认 10 MiB)
    • GZIP_MAX_FETCH_TIME_MILLIS(毫秒,默认 30000)
    • GZIP_ALLOWED_DOMAINS(逗号分隔的域名白名单;留空表示允许所有域名)

transports/ 传输目录

三种传输模块各自是一个可独立执行的 Express/Node 入口:

stdio.ts

启动StdioServerTransport,通过createServer()创建服务器并连接;处理SIGINT以优雅关闭,并在退出前调用cleanup()清理所有活动 interval。

sse.ts

基于 Express 暴露两个端点:

  • GET /sse:为每个会话建立一条 SSE 连接;
  • POST /message:接收客户端消息。

通过 transport 映射表管理多个并发客户端;每次新连接时创建SSEServerTransport,再经createServer()建服务器并连接;断开时调用cleanup()

streamableHttp.ts

streamableHttp.ts 用单个/mcp端点承载 POST(JSON-RPC)、GET(SSE 流)与 DELETE(会话终止),底层使用 SDK 的StreamableHTTPServerTransport。源码印证了结构文档的三点描述:

  • 自定义的InMemoryEventStore(streamableHttp.ts)实现storeEvent/replayEventsAfter,支持 SSE 断线后的事件重放,即"可恢复会话";
  • sessionId为键维护transports: Map<string, StreamableHTTPServerTransport>,收到携带mcp-session-id头的 POST 时复用既有传输,无 session 时初始化请求则新建createServer()实例并连接;
  • 启用宽松 CORS(origin: "*",注释明确这是为 Inspector 直连调试所用),并暴露mcp-session-idlast-event-idmcp-protocol-version响应头。

测试验证与扩展路径

src/everything/__tests__/下有五组测试,与目录结构一一对应:registrations.test.ts、tools.test.ts、prompts.test.ts、resources.test.ts、server.test.ts,通过npm run test(vitest + 覆盖率)运行。其中 registrations.test.ts 直接验证了registerResources对 mock 服务器的注册调用,为本文所述的"编排器 + 单文件工厂"模式提供了可执行的验证依据。

当你要为这个服务器新增功能时,结构文档指出的扩展约定是:跟随所在目录的既有模式,导出一个registerX(server)函数,再接入对应的中心index.tstools/index.tsresources/index.tsprompts/index.ts);更完整的扩展说明见 extension.md 与 AGENTS.md。

小结

Everything Server 的结构可以概括为一条清晰的链条:index.ts按 CLI 参数选择传输 → 传输模块调用createServer()工厂 → 工厂声明能力并依次执行registerTools/registerResources/registerPrompts三个编排器 → 初始化完成后按客户端能力补充条件工具 → 会话结束时以cleanup()统一回收定时器等资源。每个功能独立成文件、以 kebab-case 命名、由register*函数注入,使得目录布局、注册时序与测试边界三者高度一致。对于想学习 MCP 服务器工程化组织,或想参考"如何在单一参考实现中覆盖全部协议特性"的开发者,这套结构本身就是最有价值的部分。

【免费下载链接】serversModel Context Protocol Servers项目地址: https://gitcode.com/GitHub_Trending/se/servers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 19:37:34

电机启动方式全解析:DOL与星三角原理、选型及排查

第一次接触大功率电机起动柜&#xff0c;是在一个老厂房的配电间里。当时身边一位老师傅反复叮嘱&#xff1a;这台电机不能直接按启动&#xff0c;要先把切换开关打到星形&#xff0c;等转速上来再切到三角形。我不以为然&#xff0c;觉得无非是多按一个按钮。结果后来看到厂里…

作者头像 李华
网站建设 2026/9/5 19:36:34

基于ROS2与视觉算法的四轮差速机器人巡线开发全流程解析

简介&#xff1a;本资源是一个基于ROS2实现视觉巡线功能的四轮差速驱动机器人完整工程包&#xff0c;面向高校机器人方向本科生、研究生及ROS初学者&#xff0c;适用于毕业设计、课程设计与自主导航算法实践。项目融合机器视觉、运动控制与ROS2节点通信&#xff0c;解决移动机器…

作者头像 李华
网站建设 2026/9/5 19:35:55

前端学习避坑指南:从课件到知识体系的构建与实践

简介&#xff1a;本资源是一套面向前端初学者与进阶开发者的系统化教学课件包&#xff0c;覆盖HTML5、CSS3、JavaScript&#xff08;含ES6&#xff09;、jQuery、Bootstrap、Vue.js及uni-app跨端开发等主流技术栈&#xff0c;解决学习路径碎片化、实战案例缺失、知识体系不完整…

作者头像 李华
网站建设 2026/9/5 19:35:24

5分钟跑通faster-whisper语音转文字

5分钟跑通faster-whisper语音转文字 【免费下载链接】faster-whisper Faster Whisper transcription with CTranslate2 项目地址: https://gitcode.com/GitHub_Trending/fa/faster-whisper 上周三&#xff0c;我把一段 1 小时 40 分的播客扔进脚本&#xff0c;4 分 20 秒…

作者头像 李华
网站建设 2026/9/5 19:34:46

skills:把AI代理技能变成可复用目录的团队协作实践

skills&#xff1a;把AI代理技能变成可复用目录的团队协作实践 【免费下载链接】skills Skills Catalog for Codex 项目地址: https://gitcode.com/GitHub_Trending/skills4/skills skills&#xff08;Skills Catalog for Codex&#xff09;是一个 Codex 代理技能目录&a…

作者头像 李华
网站建设 2026/9/5 19:29:17

14MB端侧模型Needle 2:工具调用的本地部署实战解析

一天一个开源项目系列更到第202期了。这一期锁定 Needle 2&#xff0c;最吸引我的不是它背后有什么惊艳算法&#xff0c;而是三个字&#xff1a;14MB。在开源社区里泡久了你会发现&#xff0c;模型体积越做越小&#xff0c;目标却越来越明确。Needle 2 是一个端侧工具调用模型&…

作者头像 李华