核心要点
本质是写一个"薄适配层"——不重写业务逻辑,只把已有 REST API / 数据库 / 内部服务的能力按 MCP 规范暴露出去
用官方 MCP SDK(TypeScript / Python / Java 等)创建 Server,声明三类能力:Tools(可调用的动作,映射到你的 API)、Resources(可读数据)、Prompts(可复用模板)
每个 Tool 要给清楚名称、描述、输入参数的 JSON Schema;handler 内部把入参转成对你已有接口的调用,再把结果整理成文本 / 结构化内容返回
选传输方式:本地进程用 stdio,远程多客户端用 Streamable HTTP;远程务必加鉴权(OAuth / API Key)与权限收敛
封好后,Claude、IDE、各类 Agent 等任意 MCP 客户端都能即插即用地复用你的能力,无需各自再做一遍集成
标准回答
整体思路:写一个薄适配层,而不是重写系统
把已有应用接入 MCP,不是把业务逻辑搬到 MCP 里,而是在它前面加一层很薄的"翻译层"。你已有的 REST API、数据库查询、内部 RPC 服务保持不动,MCP Server 只负责:对外按 MCP 规范声明能力、对内把请求转调你原来的接口。这样改动小、风险低,也不影响现有调用方。
第一步:用 MCP SDK 起一个 Server
选对应语言的官方 SDK(TypeScript、Python、Java 等都有)。SDK 帮你处理底层的 JSON-RPC 收发、能力协商、生命周期,你只需要注册能力和写 handler。
第二步:把能力归到三类
- Tools(动作):对应"会产生效果或需要参数的调用",比如「创建工单」「查询订单状态」「发送通知」。这是最常用的一类,直接映射到你的 POST/PUT 类 API。
- Resources(数据):对应"可读的内容",比如一份文档、一条配置、一张表的某行,用 URI 标识,供客户端按需读取。偏向你的 GET 类只读数据。
- Prompts(模板):把团队沉淀的提示词 / 工作流做成可复用模板,客户端可一键调用。
第三步:认真写 Tool 的声明与 handler
每个 Tool 要给三样东西:唯一的 name、清晰的 description(模型靠它判断何时调用,写得越准确调用越精准)、以及输入参数的 JSON Schema(字段、类型、是否必填、枚举值)。handler 里做的事很固定:取出校验过的入参 → 转调你已有的 API / SQL / 服务 → 把返回结果整理成文本或结构化内容回传。错误也要返回得清楚,便于模型纠偏。
第四步:选传输并加鉴权
- 只在本机给单个客户端用 → stdio,把 Server 作为子进程拉起,简单零网络。
- 要远程、给多个客户端 / 多用户共享 → Streamable HTTP,部署成一个服务。此时鉴权是重点:加 OAuth 或 API Key,并把每个 Tool 能触达的范围收敛到最小权限,避免把内部能力裸奔到公网。
收尾
封装完成后,这台 Server 就成了一个标准的能力供给方:Claude 桌面端、支持 MCP 的 IDE、你自研的 Agent,任意 MCP 客户端配置上它就能复用,无需每家再单独对接你的私有 API。一次封装,处处可用,这正是 MCP 想消除的"M×N 集成"问题。
常见误区
⚠️ 常见踩坑
别把 MCP Server 写成"把整套数据库 / 全部 API 一股脑暴露"——Tool 不是越多越好。Tool 太多、描述含糊会让模型选错或被淹没;更要警惕把高危操作(删库、转账、批量改写)裸暴露且不加鉴权与权限边界。正确做法是按场景挑出真正该让 Agent 用的少量能力,描述精准、参数有校验、远程必带认证、危险动作加确认或只读化。
追问
追问 1:Tools、Resources、Prompts 三者怎么区分?同一个查询接口该归到哪一类?
按"语义意图"分而不是按 HTTP 方法机械套。Tools 是"模型主动发起的动作调用",带参数、可能有副作用,由模型在对话中决定何时触发;Resources 是"可被引用 / 读取的上下文数据",用 URI 标识,更像是把内容挂出来供客户端按需加载;Prompts 是"预置的提示词 / 流程模板",由用户或客户端显式选用。
对一个查询接口,看你想要的交互方式:如果希望模型"在需要时自己去查某个具体订单",那就做成 Tool(带 orderId 参数);如果是"把一份相对固定、可被引用的内容(如某份手册、某段配置)提供给模型",更适合做成 Resource。很多团队会两者都给:高频、参数化的查询走 Tool,静态可引用的内容走 Resource。
追问 2:为什么 Tool 的 description 和输入 Schema 这么关键?写不好会出什么问题?
因为模型不是读你的源码来决定调用的,它只能读你给的 name、description 和参数 Schema。这几样就是模型唯一的"说明书"。
description 含糊(比如只写"处理数据")会导致两类问题:该调时不调、不该调时乱调,或者多个相似 Tool 之间选错。输入 Schema 不严谨(缺类型、缺必填标记、没有枚举约束)则会让模型传错参数、漏参数,handler 拿到脏输入。
实践上:description 要写清"做什么、什么时候用、返回什么",参数给明确类型 / required / enum / 取值说明;handler 内再做一层服务端校验,对非法输入返回可读的错误信息,让模型能据此自我修正。把 Tool 当成给一个聪明但只看文档的同事用的 API 来设计。
追问 3:stdio 和 Streamable HTTP 两种传输怎么选?远程暴露时安全上要注意什么?
选型看部署形态。stdio:Server 作为客户端的本地子进程被拉起,通过标准输入输出通信,没有网络、配置最简单,适合"本机单用户单客户端"场景,比如给本地 IDE 或桌面客户端接一个本地工具。Streamable HTTP:Server 是一个独立网络服务,支持远程、多客户端、多用户并发,适合团队共享或云端部署。
远程暴露时安全是第一位的:一是鉴权,加 OAuth 或 API Key,识别调用方身份;二是最小权限,每个 Tool 只开放它该有的数据范围,按用户做隔离,别让 A 用户能查到 B 用户的数据;三是危险操作收敛,删除 / 转账 / 批量写这类动作要么不暴露,要么加二次确认 / 审计日志;四是输入校验与限流,防注入、防滥用。本质上你是在把内部能力开到模型可触达的边界上,必须按对外 API 的安全标准来对待。
🔗 相似问题
同一考点的不同问法,面试官可能换着问,一起刷更稳
没找到想看的面试题?把你想看的告诉我们 →
延伸学习
按主题分类的相关资源,便于系统复习