首页 / 文章 / 《实用笔记》:MCP服务器详解——我所学到的完整指南

《实用笔记》:MCP服务器详解——我所学到的完整指南

《实用笔记操作指南》:MCP服务器详解——我所学到的完整指南:适用于采用该模式的团队的契约、校验机制以及即插即用代码槽。

2300 词

本指南将逐步构建从原材料到可运行系统的完整流程,内容涉及《MCP服务器详解:我在AWS EC2上部署它的全部经验》。重点在于可操作的步骤、明确的检查点,以及可直接放入代码仓库的代码,无需猜测其用途。

内容概览

在“内容概览”阶段,需先明确输入项、各步骤的负责人以及完成标准,然后再修改代码。操作人员应能够从已知的检查点重新运行步骤,而无需猜测隐藏的状态。应将此阶段视为输入与经过验证的输出之间的契约:为相关文件命名、定义成功标准,并杜绝无声的半完成状态。应在网关处进行身份验证,在数据层再次授权——仅凭承载令牌并不足以界定租户边界。

基础知识

在“基础阶段”,在修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。应在功能结果旁记录执行时间以及令牌或查询成本。提前了解这些成本可以避免在从演示环境过渡到共享环境时出现意外费用。

MCP的实际覆盖范围

在“MCP实际涵盖的内容”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审核。 在网关处进行身份验证,在数据层再次授权。仅凭承载令牌并不足以界定租户边界。

为何部署细节是个高价值问题

对于为何部署细节要分阶段进行的问题,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和故障恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的功能。 在网关处进行身份验证,在数据层再次授权。仅凭承载令牌并不足以界定租户边界。

完整架构

在“完整架构”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。相比庞大的脚本,更应采用小型且可测试的单元。当某个步骤失败时,故障原因应能指向单一责任主体,而非复杂的流程链。应在网关处进行身份验证,在数据层再次授权——仅凭承载令牌并不足以界定租户边界。

AI Client ── HTTPS POST ──▶ nginx (TLS termination, auth check, reverse proxy)
                                    │
                                    ▼
                          MCP Server Process
                          (Streamable HTTP transport)
                                    │
                       ┌────────────┴────────────┐
                    Tools                    Resources

在“完整架构”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。应在功能结果旁记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。

核心层解析

在完成“核心层解析”阶段时,首先写下契约内容:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 为每次调用记录工具名称、参数哈希值、延迟时间以及最终结果。如果没有这些记录,调试代理将陷入无止境的循环,耗费大量时间。

1. 传输层:流式 HTTP

在处理“1 Transport Streamable HTTP”阶段时,首先需明确相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会偏离原有设计。

location /mcp {
    proxy_pass http://127.0.0.1:8000;
    proxy_set_header Host $host;
    proxy_set_header Authorization $http_authorization;
    proxy_http_version 1.1;
    proxy_read_timeout 300s;
}

2. 认证:Bearer令牌(起点而非终点)

在处理“2个认证令牌”阶段时,首先需明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改始终符合预期。 建议采用小型、可测试的单元而非庞大的脚本。当某个步骤出现故障时,故障应指向单一责任模块,而非复杂的流程链。 对稳定的系统指令和工具结构进行缓存。重复发送相同的开头信息是导致资源浪费的常见原因。 在处理“2个认证令牌”阶段时,首先需明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改始终符合预期。 在功能结果旁记录执行时间以及令牌或查询的成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。

from fastapi import Request, HTTPException
VALID_TOKEN = "your-rotated-secret-token"async def verify_bearer(request: Request):
    auth = request.headers.get("authorization", "")
    if auth != f"Bearer {VALID_TOKEN}":
        raise HTTPException(status_code=401, detail="Unauthorized")

3. 无状态性——2026年7月重写的核心

在将“3无状态性核心”阶段视为可度量的目标时,其效果最佳。在扩大范围之前,需记录一份理想的操作日志、一个故障案例以及回滚说明。 应将配置置于应用程序代码之外。环境文件、密钥存储和功能标志应集中存放,以便操作人员无需查看整个系统结构即可进行审计。 需提供具有明确数据结构和清晰副作用标签的工具。主机需要在自动批准之前知道哪些调用会修改状态。

4. 多次往返请求(在调用过程中向用户提问)

将“4个多往返请求阶段”视为可度量的指标来处理时效果最佳。在扩大范围之前,先记录一份成功的测试用例、一个失败案例以及回滚说明。同时记录正常流程和恢复流程的文档。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的功能。应提供具有明确结构规范和清晰副作用标识的工具,这样主机在自动批准之前就能知道哪些调用会改变状态。

5. 权限强化:OAuth 2.1、PKCE与资源标识

将OAuth的5个授权强化阶段视为可度量的对象来处理,效果最佳。在扩大应用范围之前,需记录一份标准操作流程、一个故障案例以及回滚说明。 相比复杂的脚本,应优先使用小型且可测试的单元。当某一步骤出现故障时,故障原因应能明确指向某个具体责任方,而非整个复杂的流程。 应提供具有严格结构定义和明确副作用标注的工具。主机需要在自动批准之前知道哪些调用会改变系统状态。 将OAuth的5个授权强化阶段视为可度量的对象来处理,效果最佳。在扩大应用范围之前,需记录一份标准操作流程、一个故障案例以及回滚说明。 除了功能结果外,还需记录执行时间以及令牌或查询的成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。

6. 废弃政策与扩展框架

对于6项废弃策略及对应阶段,在修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 在网关处进行身份验证,在数据层再次授权。仅凭承载令牌并不足以界定租户边界。

端到端流程详解

在端到端演练阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误消息处理都是产品功能的一部分,而非后续需要补充的内容。 在网关处进行身份验证,在数据层再次授权。仅凭承载令牌并不能作为租户边界。

特殊情况

在“特殊场景”阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任模块,而非复杂的流程链。 在网关处进行身份验证,在数据层再次授权。仅凭承载令牌并不足以界定租户边界。 在“特殊场景”阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 在功能结果之外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示环境转向共享环境时出现意外账单。

扩展与生产环境中的挑战

在处理“扩展生产环境挑战”阶段时,首先列出相关要求:所需输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放,以便运维人员无需查看全部代码结构即可进行审计。 为每次调用记录工具名称、参数哈希值、延迟时间以及执行结果。没有这些记录,调试代理将陷入无止境的循环,耗费大量时间。

代码示例

在处理代码示例阶段时,首先需明确契约内容:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及死信处理都是产品功能的一部分,而非后续需要补充的内容。 需为每次调用记录工具名称、参数哈希值、延迟时间以及最终结果。没有这些记录,调试过程将会浪费大量时间。

async def call_tool_with_resume(client, tool_name, params):
    result = await client.call_tool(tool_name, params)
    if result.get("type") == "InputRequiredResult":
        answers = collect_answers(result["questions"])
        return await client.call_tool(
            tool_name,
            {**params, "answers": answers, "requestState": result["requestState"]},
        )
    return result

常见误区

在处理“常见陷阱”阶段时,首先需明确合同规范:所需的输入参数、成功标志以及部分失败时的处理方式。这份清单能确保后续的代码修改保持一致性。 建议采用小型、可测试的单元而非庞大的脚本。当某个步骤出错时,错误应指向单一责任模块,而非复杂的流程链。 需为每次调用记录工具名称、参数哈希值、延迟时间以及最终结果。没有这些记录,调试过程将会浪费大量时间。 在处理“常见陷阱”阶段时,首先需明确合同规范:所需的输入参数、成功标志以及部分失败时的处理方式。这份清单能确保后续的代码修改保持一致性。 在功能结果旁还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。

生产环境最佳实践

将“生产最佳实践”阶段视为可度量的对象来处理,效果最为理想。在扩大范围之前,先记录一份最佳实践案例、一个故障实例以及回滚说明。 应将配置与应用程序代码分开。环境文件、密钥存储和功能开关应集中存放于一处,这样操作人员无需查看整个系统结构即可进行审计。 需提供具有明确数据结构和清晰副作用标签的工具。主机在自动批准之前,必须知道哪些调用会改变系统状态。

总结

将“总结阶段”视为可度量的工作面时效果最佳。在扩大范围之前,需记录一份理想运行案例、一个故障案例以及回滚说明。

操作检查清单

将“操作检查清单阶段”视为可度量的工作面时效果最佳。在扩大范围之前,需记录一份理想运行案例、一个故障案例以及回滚说明。

应将此阶段视为输入与经过验证的输出之间的契约。为相关文档命名,明确成功标准,杜绝无声的半完成状态。

为那些具有狭窄数据结构且带有明确副作用标签的工具提供接口。在自动批准之前,主机方需要知道哪些调用会修改状态。

只要预算允许,就在持续集成过程中使用测试数据而非真实的付费 API 来执行关键路径的冒烟测试。

在功能结果之外,还需记录处理时间以及令牌或查询的成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外账单。

为那些具有狭窄数据结构且带有明确副作用标签的工具提供接口。在自动批准之前,主机方需要知道哪些调用会修改状态。

在升级技术栈之前,应冻结版本、为关键路径保存标准操作记录,并确认回滚步骤。共享环境需要设置速率限制、进行租户身份验证,同时明确密钥轮换的责任人。与其追求华丽的临时演示,不如注重扎实的可靠性。

a75b5a936f62的批处理说明:不要将提供者密钥放入代码仓库,为每个会话设置令牌上限,并将转录内容存储在评估测试用例的旁边,以便后续更换模型时仍能保持可比性。