
大厂 MCP 面试实录基于 stdio 传输的只读业务上下文暴露方案设计本文采用模拟面试形式复盘 MCP 岗位面试中的场景设计题聚焦 Resources 能力、stdio 传输与 Prompts 的落地实践面向具备基础开发经验的读者。面试官今天我们聊一个实际业务需求——你所在的团队要给内部 AI 助手做业务上下文增强需要把订单系统的只读规则、用户权限范围、商品类目说明三类静态业务资料通过 MCP 暴露给模型要求使用 stdio 传输同时支持用户一键调用预设的上下文查询模板。你先说说整体的方案思路候选人我的整体方案是基于 MCP Server 端实现用 stdio 作为传输层三类静态资料封装为 Resources常见的查询逻辑封装为 PromptsHost 侧只要启动本地子进程即可接入不需要额外网络配置。 选型依据上三类资料都是只读静态内容没有副作用符合 MCP 中 Resources 的语义定位——Resources 专门用于向模型提供可读取的上下文由 URI 唯一标识比强行设计成有操作语义的 Tool 更符合协议规范[资料1]。传输层选 stdio 是因为需求是内部工具部署在员工本机不需要远程访问stdio 适合 Host 本机启动子进程的场景比 Streamable HTTP 更轻量不需要处理远程部署的认证、会话管理、限流等问题[资料1]。Prompts 的作用是把常见的查询模板提前封装好比如“查询当前用户的订单规则”“查询商品类目说明”用户不用自行编写提示词直接选择对应的模板就能调用减少模型对查询意图的理解偏差。面试官你把三类资料封装成 Resources那 URI 设计有什么讲究如果后续业务资料更新怎么保证模型拿到的是最新内容又不会频繁读磁盘影响性能候选人URI 设计要遵循可读、可层级划分的原则比如用order://rules/latest标识最新订单规则、user://permission/scope标识用户权限范围、product://category/list标识商品类目列表符合 RFC 3986 的 URI 规范也方便 Host 侧做预加载和缓存[资料2]。 内容更新机制上MCP 的 Resources 是应用驱动的Host 侧可以根据自身需求决定何时拉取资源[资料2]。我可以在 Resources 的响应元数据里加版本号字段Host 侧缓存资源时同时记录版本号每次调用前先对比版本号只有版本变化时才重新拉取内容既保证内容时效性又避免频繁读磁盘。如果业务资料是存在本地文件里的还可以监听文件的修改事件文件更新时主动通知 Host 更新缓存进一步降低延迟。面试官你提到用 stdio 传输如果 Server 端不小心把调试日志输出到标准输出会有什么后果怎么规避候选人stdio 传输下MCP 的 JSON-RPC 协议消息是走 Server 的标准输出stdout如果调试日志也输出到 stdout会直接破坏消息格式导致 Host 侧解析失败通信中断轻则上下文获取失败重则整个 AI 助手功能不可用[资料1]。 规避方式有两个一是日志库配置把调试日志输出到标准错误stderr或者直接写入本地日志文件只有协议消息走 stdout二是在 Server 启动时做输出流校验如果有非 JSON 内容输出到 stdout直接终止进程并报错。另外 Host 侧也要做容错如果子进程启动失败或者通信中断要给用户明确的错误提示比如“业务上下文服务异常请检查安装是否完整”。面试官现在有个新需求用户查询订单规则时需要根据当前用户的角色返回不同的规则内容这个需求用 Resources 还是 Prompts 实现更合适如果后续要支持用户输入自定义查询条件又该怎么调整候选人这个需求要分场景选型如果不同角色对应的规则是静态的、提前写好的优先用 Prompts 实现更合适。我们可以把“查询角色对应订单规则”封装成一个 Prompt预置user_role参数用户选择模板时 Host 侧自动把当前用户的角色作为参数传入Server 侧根据角色返回对应角色的 Resources 内容逻辑清晰且可控。 如果后续要支持用户输入自定义查询条件比如查询特定时间段的订单规则就需要扩展只读 Tool 能力把这个查询逻辑封装成只读 Tool明确标注无副作用参数里加时间范围的校验规则。这里要注意Tool 的参数 schema 只是结构约束Server 侧必须对用户输入的时间参数做合法性校验防止 SQL 注入或者路径遍历等攻击[资料1]。另外所有用户传入的文本都要视为不可信输入不能直接拼接文件路径或者查询语句。面试官这个 Server 要部署到团队所有员工的本机怎么保证安全有没有潜在的泄露风险候选人首先是代码安全Server 的代码是团队内部开源的员工安装时可以做哈希校验防止被恶意篡改。然后是内容安全Resources 暴露的都是静态只读内容Server 侧不会执行文件里的任何代码只是返回纯文本所以不会有代码执行风险。Prompts 里的参数都是预置的用户不能输入任意内容也不会存在注入风险。 如果后续扩展了动态查询 Tool必须做参数校验比如用户ID必须是数字格式文件路径只能在规定的业务目录下不能访问系统文件[资料1]。另外日志里不能打印敏感信息比如用户权限内容、用户ID 等要做脱敏处理审计日志只记录调用时间、调用者、资源标识和结果状态不记录敏感字段[资料1]。面试官那你写一个可落地的示例代码吧用 Python 实现就行。候选人以下代码基于 MCP 公开规范与 Python SDK 公开文档设计具体接口以官方文档为准[资料3]# 参考 MCP Python SDK 公开接口设计仅作示例 from mcp.server import Server from mcp.types import Resource, Prompt, PromptArgument app Server(business-context-server) # 定义只读业务资源 app.list_resources() async def list_resources(): return [ Resource( uriorder://rules/latest, name最新订单规则, description订单系统核心规则说明只读, mime_typetext/markdown ), Resource( uriproduct://category/list, name商品类目列表, description全量商品类目说明只读, mime_typetext/markdown ) ] app.read_resource() async def read_resource(uri: str): if uri order://rules/latest: with open(./rules/order.md, r) as f: return f.read() if uri product://category/list: with open(./rules/category.md, r) as f: return f.read() raise ValueError(f不支持的资源标识{uri}) # 定义预设Prompt app.list_prompts() async def list_prompts(): return [ Prompt( namequery-order-rule, description查询当前登录用户的订单规则, arguments[PromptArgument(nameuser_role, description用户角色, requiredTrue)] ), Prompt( namequery-category, description查询商品类目说明, arguments[] ) ] app.get_prompt() async def get_prompt(name: str, arguments: dict): if name query-order-rule: role arguments.get(user_role, guest) return { messages: [{role: user, content: f请读取订单规则资源针对{role}角色的用户说明下单、退款、售后的相关规则}] } if name query-category: return { messages: [{role: user, content: 请读取商品类目资源说明全量类目的划分规则和适用范围}] } raise ValueError(f不存在的模板{name}) if __name__ __main__: # stdio 传输标准输出用于协议消息标准错误用于日志 app.run(transportstdio)这个示例的适用边界是静态只读业务资料的暴露不支持动态参数化的资源查询若要支持需扩展 Tool 能力。关键取舍是stdio 传输仅支持本机部署不支持多用户远程共享适合小团队内部个人工具使用如果是全公司大规模部署建议换成 Streamable HTTP 传输加上认证、授权和限流机制[资料1]。面试官点评考察点本题核心考察四个方向一是对 MCP 三类能力Tools、Resources、Prompts的语义区分避免乱用能力二是传输方式的选型权衡是否了解 stdio 的适用场景和限制三是安全边界意识是否知道 MCP 场景下的常见安全风险四是可落地能力能不能把方案转化为可运行的代码。合格回答能明确区分 Resources 和 Tool 的适用场景知道 stdio 传输下日志不能输出到 stdout 的要求能设计合理的 URI 和 Prompts 模板考虑到基本的参数校验和敏感信息保护给出的示例代码能跑通核心流程。加分项能提到 Resources 的“应用驱动”特性知道 Host 侧的缓存优化机制能区分静态和动态场景的选型考虑到后续扩展性能指出 stdio 传输仅适合本机部署的边界以及大规模部署的替代方案能提到路径遍历、日志脱敏等容易被忽略的安全细节。容易踩坑的细节很多开发者会把需要动态参数的只读查询设计成 Resource比如user://permission/123导致 Resource 列表爆炸且 Host 侧无法预知所有可能的 URI无法做预加载缓存。动态查询场景优先用 Prompts 或者只读 Tool 实现。stdio 传输下把调试日志输出到 stdout 是非常常见的错误会导致通信直接中断一定要把日志输出到 stderr 或者文件。不要因为请求来自 AI 应用就默认可信所有用户传入的参数都要做服务端校验不能只依赖前端或者 Host 侧的限制。总结本场景下的技术选型逻辑非常清晰只读静态业务上下文优先用 Resources 暴露模板化查询逻辑用 Prompts 封装本地小范围部署用 stdio 传输降低成本。整个方案的核心是遵循 MCP 的能力语义不强行拼接技术同时守住安全边界保证服务稳定。如果是更复杂的动态查询场景再扩展只读 Tool 能力同时做好参数校验和权限控制。参考资料MCP 基础知识Resources | https://modelcontextprotocol.io/specification/2026-07-28/server/resourcesMCP Python SDK | https://github.com/modelcontextprotocol/python-sdkSampling | https://modelcontextprotocol.io/specification/2026-07-28/client/sampling