ChatGPT、Codex实战:MCP接上以后为什么还是不好用?从工具调用、权限到上下文边界的7项排查
很多人第一次给Codex接MCP时,都会有一个很自然的预期:
MCP连接成功以后,Codex是不是马上就能更聪明地使用浏览器、文档、数据库或者外部开发工具?
真正用起来却经常不是这样。
你可能已经看到MCP Server正常连接:
Connected甚至在Codex里也能看到对应Server。
但真正开始任务以后,却出现:
Codex根本不调用MCP;
明明有合适的Tool,却继续自己搜索;
调用了错误的工具;
Tool调用到一半突然要求Approval;
MCP返回了大量内容,后面的任务反而越来越乱;
显示调用成功,但最终结果明显不对;
同一个MCP在一个任务里很好用,换个任务又像“失忆”了一样。
这时候很多人会怀疑:
是不是MCP没有配置成功?
实际上:
MCP连接成功,只能证明“Agent拥有了这个工具”,不能证明Agent会在正确时间、以正确方式使用这个工具。
目前Codex把MCP提供的工具和自身Shell、Plan等工具一起放进Agent Loop。模型在推理过程中决定是否发起Tool Call,工具返回结果以后,这些结果又重新进入上下文,Agent再继续下一轮判断。
所以MCP真正稳定工作,至少存在这样一条链:
Server Connection ↓ Tool Discovery ↓ Tool Selection ↓ Permission ↓ Execution ↓ Context ↓ Verification任何一层出现问题,最终表现出来都可能是:
“MCP不好用”。
下面按照这7层依次排查。
一、第一层:Server连上了,不代表当前Codex真的能用到对应Tool
第一步不要急着看Prompt。
先确认:
当前Codex Session到底看到了什么。
Codex目前支持STDIO和Streamable HTTP类型的MCP Server;ChatGPT桌面端、Codex CLI和IDE扩展可以共享同一Codex Host下的MCP配置。CLI里可以通过codex mcp list查看配置,在交互界面中也可以用/mcp查看当前Active Server。需要OAuth的Server还必须完成对应认证。
这里经常出现几个非常基础的问题。
Server配置存在,但没有启用
Codex的MCP配置允许:
enabled = false也就是说配置文件里有Server,不代表它实际处于启用状态。
Server启动成功,但部分Tool被过滤
MCP配置还支持:
enabled_tools disabled_tools也就是说:
Server有10个工具,当前Session可能只暴露其中3个。
而且disabled_tools会在enabled_tools之后继续应用。
所以不要只确认:
MCP Server在线。
还应该确认:
真正需要的那个Tool有没有暴露给Codex。
OAuth状态不完整
HTTP MCP可能需要:
Bearer Token;
OAuth;
ChatGPT Session认证。
一个Server地址可以访问,并不代表当前用户已经获得了真正执行目标动作需要的身份。Codex也允许单独运行MCP OAuth登录。
所以第一层真正应该确认的是:
Server存在? ↓ Enabled? ↓ Authenticated? ↓ 目标Tool存在? ↓ 当前Session可见?只有这5项都成立,才进入下一层。
二、第二层:Tool存在,不代表模型知道“什么时候应该调用它”
这是MCP最容易产生误解的地方。
很多人认为:
我把一个Tool接进Codex,它自然就知道什么时候使用。
其实模型并不是看到:
有一个MCP Server就自动理解这个系统所有业务含义。
在Codex的Agent Loop里,MCP Tool最终会作为Tool Definition进入模型能够选择的工具列表;工具定义里会包含名称、description以及参数Schema。
也就是说,模型做选择时看到的更像:
Tool A 名称 描述 参数 Tool B 名称 描述 参数然后判断:
当前任务应该调用哪一个?
这时候Tool Description就非常重要。
看一个不太好的例子:
searchDescription:
Search information.
问题是:
搜什么?
什么时候用?
搜索本地?
外部文档?
公司内部知识?
API?
模型很难形成稳定判断。
更好的描述应该告诉Agent:
用途 + 适用场景 + 数据范围 + 限制例如:
Search the internal engineering documentation for API contracts, service ownership, deployment procedures, and runbooks. Use this before guessing internal platform behavior.
现在Agent就更容易判断:
什么时候应该调用。
三、第三层:Server Instructions写得不好,也会导致Agent工具选择混乱
MCP不仅可以暴露Tools。
Server初始化时还可以返回:
instructions。
Codex会读取这部分内容,把它作为整个Server级别的指导信息,与Server提供的Tools一起使用。OpenAI当前还特别建议:MCP Server Instructions开头约512字符应该能够独立表达最重要的信息,因为这部分会影响Codex判断如何使用整个Server。
这意味着如果一个MCP里有:
search_docs get_ticket update_ticket deploy_service只给四个Tool,而没有解释它们之间的Workflow,Agent可能只能自己推断。
但如果Server Instructions告诉它:
排查线上问题时: 先搜索Runbook, 再读取相关Incident, 不要直接执行Deploy; 部署动作必须在用户确认变更方案后进行。整个工具使用路径会稳定很多。
所以MCP设计里有两个层次。
Tool Description
回答:
这个工具做什么?
Server Instructions
回答:
这一组工具应该怎样协同工作?
很多所谓:
Codex总是乱调用MCP。
真正缺失的可能不是模型能力。
而是:
工具系统根本没有给模型一张清楚的地图。
四、第四层:工具能调用,却被Approval和权限边界挡住
还有一种非常常见的情况:
MCP明明已经被调用。
但执行到关键步骤突然:
Approval Required于是用户认为:
MCP是不是坏了?
其实这里需要区分:
Tool Availability
和:
Action Permission。
Codex目前可以针对MCP Server设置不同的Tool Approval模式,包括:
auto prompt writes approve还可以对单个Tool单独覆盖Approval规则。
其中尤其重要的一点是:
如果MCP Tool自己标记了 destructive action,Codex会要求审批,即使这个工具同时声明了其他低风险属性。
例如:
查询Issue
可能属于:
Read修改Issue状态
已经属于:
Write删除资源
则可能属于:
Destructive Action风险完全不同。
所以不要把:
Tool被Codex发现
理解成:
Tool可以无条件自动执行。
一个合理的MCP应该让不同动作拥有不同风险等级。
例如:
search_docs → Auto read_ticket → Auto update_ticket → Approval based on policy delete_resource → Human Approval这其实和我们之前讨论Full Access是同一个原则:
Agent拥有能力,不意味着所有能力都应该默认自动使用。
五、第五层:不要把Codex Shell的Network权限和MCP权限混成一件事
这是非常容易混淆的一层。
Codex本地运行时,Shell Command通常受到Sandbox约束。
例如默认Workspace模式下,Shell网络访问可能关闭;用户可以另外配置网络访问和Network Proxy规则。
于是有人看到:
Network Access Off
就认为:
所有MCP也一定不能联网。
但这里要注意一个非常关键的边界:
Codex自己的Shell Tool和MCP Tool不是同一个执行系统。
OpenAI在拆解Codex Agent Loop时明确说明:Codex给Shell提供的Sandbox指令主要约束Codex自身提供的Shell工具,而来自MCP Server的其他Tools并不是简单套在同一个Shell Sandbox中,它们需要由各自工具和服务端实现自己的安全边界。
所以实际架构更接近:
Codex │ ├── Shell │ └── Codex Sandbox / Network Policy │ └── MCP Tool └── MCP Server自己的权限与Guardrail这是一个非常重要的概念。
例如:
一个GitHub MCP能够修改Issue,
并不意味着Codex本地Shell也获得了GitHub网络访问。
反过来也一样。
所以排查权限时不要只问:
Codex有没有网络?
而应该具体到:
哪个Tool? ↓ 运行在哪里? ↓ 通过什么身份? ↓ 由谁执行? ↓ 谁负责权限控制?越具体,问题越容易定位。
六、第六层:MCP返回的信息太多,可能反而污染Agent上下文
这是接入MCP以后非常容易忽略的问题。
我们通常会认为:
Tool返回越多信息越好。
但Agent工作并不是数据库查询。
Tool结果最终需要进入Agent Loop。
Codex执行Tool Call以后,会把工具输出追加回当前交互上下文,模型根据新的结果再次推理;长任务中不断累积的Tool Calls和输出同样会占用Context,Codex也需要通过Compaction等机制管理不断增长的对话状态。
所以假设用户问:
这个API返回401的原因是什么?
理想MCP返回:
Auth API文档 相关认证规则 当前版本变化但一个设计不好的Tool可能直接返回:
整个API知识库 几十页文档 大量无关示例 历史版本说明 几百条搜索结果模型拥有的信息确实增加了。
但:
Signal / Noise下降了。
最后Agent可能出现:
重复分析;
抓错重点;
重新关注旧信息;
消耗大量Context;
长任务后半段越来越混乱。
这和我们之前讲的Context Pollution完全一致。
MCP真正应该追求的不是“大返回”,而是“高相关返回”
一个好的Tool最好能够支持:
Query Filter Limit Scope而不是:
把全部资料交给模型自己筛。
例如:
search_docs( query, service, version, limit )通常比:
get_all_docs()更加适合Agent。
因为MCP真正应该提供的是:
Just-in-Time Context。
不是:
Just-in-Case Context。
七、第七层:Tool调用成功,不代表任务成功
这是MCP最重要的一层。
例如Codex调用:
search_internal_docs返回:
Success这只能证明:
Tool Call完成。
不能证明:
Agent获得了正确答案。
再例如:
update_ticket返回:
200 OK也只能说明:
请求成功。
并不能证明:
更新的是正确Ticket;
写入了正确内容;
符合当前任务目标。
所以MCP工作流同样必须建立:
Verification。
一个更成熟的结构应该是:
Tool Call ↓ Tool Result ↓ Interpretation ↓ Independent Check ↓ Evidence ↓ Task Completion而不是:
Tool Call ↓ Success ↓ DoneRead类Tool怎么验证?
例如:
查最新API规范。
可以确认:
版本;
更新时间;
目标Service;
是否来自预期数据源。
Write类Tool怎么验证?
例如:
更新Issue状态。
执行完以后:
重新读取Issue。
确认:
目标Issue 状态 内容 时间真的发生了变化。
外部执行Tool怎么验证?
例如:
部署;
触发CI;
修改配置。
最好进一步读取:
Execution Status Logs Result不能只相信:
API请求已经发送。
八、MCP调用失败时,不要马上让Codex“再试一次”
这是实际使用中非常低效的一种模式。
Tool调用失败。
用户直接说:
再试试。
Agent重复调用。
再次失败。
继续重试。
但失败可能来自完全不同的层级:
Connection Authentication Tool Discovery Parameter Permission Timeout Server Error Business Validation如果不知道是哪一层,重试没有意义。
Codex当前MCP配置本身就提供:
startup_timeout_sec tool_timeout_sec required enabled_tools disabled_tools这些配置说明“Tool调用失败”从来不是一个单一错误类型。
所以更合理的做法是先分类:
Connection Error
Server根本没启动。
Authentication Error
身份无效。
Tool Error
Tool存在,但执行失败。
Policy Error
被权限或Approval挡住。
Semantic Error
工具调用成功,但选错Tool或者参数。
Context Error
返回信息不适合当前任务。
Verification Error
调用完成,但没有证明目标达成。
这样MCP才真正开始变得:
可诊断。
九、什么时候应该用MCP,什么时候直接用Shell?
MCP工具越来越多以后,还有一个新的问题:
是不是所有事情都应该MCP化?
没有必要。
假设Agent要:
读取当前Repository里的package.json直接文件工具就已经很好。
再例如:
运行pytestShell非常自然。
这时候如果强行绕成一个MCP:
run-project-test-via-mcp不一定提高效率。
MCP更适合解决什么?
我认为主要是三类问题。
第一类:Codex原本无法直接访问的上下文
例如:
内部文档;
Issue系统;
设计系统;
企业知识库。
第二类:拥有结构化API的外部工具
例如:
Figma;
浏览器;
项目管理系统;
监控平台。
OpenAI目前对MCP的定位本身就是连接ChatGPT/Codex与第三方工具和上下文,例如文档、浏览器和Figma。
第三类:需要稳定封装权限和业务规则的动作
例如:
create_incident而不是让Agent自己:
找到API;
拼HTTP请求;
猜认证方式。
MCP可以把外部系统能力封装成明确Tool。
所以真正好的Agent工具体系不是:
所有东西都走MCP。
而是:
Repository → Native File Tools Local Commands → Shell External Context / SaaS → MCP Repeatable Workflow → Skills这样边界才清楚。
十、MCP、Skills和AGENTS.md到底怎么配合?
接上第一篇Skills以后,这里正好可以建立一个完整结构。
AGENTS.md
定义:
规则。
例如:
不要修改生产数据库。Skills
定义:
工作流程。
例如:
Incident排查流程MCP
提供:
外部能力。
例如:
查询监控 读取Incident 搜索Runbook于是一次真实任务可能变成:
AGENTS.md 定义安全边界 ↓ Skill 定义Incident Workflow ↓ MCP 读取监控和Runbook ↓ Codex 分析与执行 ↓ Verification 确认结果这比:
给Codex接20个MCP Server。
然后期待它自己聪明地使用,
稳定得多。
十一、一个真正成熟的MCP Tool应该具备什么?
如果是自己设计MCP,我会重点看六件事情。
1. Name清晰
看到名字就知道它做什么。
2. Description准确
明确:
什么时候调用;
数据范围;
限制。
3. Parameter足够结构化
减少Agent猜参数。
4. Return尽量高信噪比
不要一次返回整个世界。
5. Side Effect明确
Read和Write必须区分。
6. Result可以验证
不要只返回:
Success最好返回:
resource_id status changed_fields timestamp真正让Agent能够继续确认:
操作到底产生了什么状态变化。
这才是Agent友好的Tool Design。
十二、MCP真正改变的不是“Agent会更多工具”,而是Agent的能力边界
过去Codex主要面对:
Repository Terminal Tests接入MCP以后,它能够继续进入:
Docs Browser Design Issue Tracker Monitoring Internal Systems这当然让Agent更强。
但也意味着系统复杂度开始增加。
因为每增加一个Tool,都同时增加:
Capability + Permission + Context + Failure Mode + Verification Cost所以MCP数量不是越多越好。
真正成熟的Agent环境追求的应该是:
最小但足够的Tool Set。
就像权限一样。
不是:
Agent能用什么全部给它。
而是:
当前任务真正需要什么,就提供什么。
十三、一套更实用的MCP排查顺序
以后遇到:
MCP已经连接,但Codex还是不好用。
可以直接按照这个顺序排查:
① Server 是否在线、启用、认证完成? ↓ ② Discovery 目标Tool是否真正暴露? ↓ ③ Selection Tool描述和Server Instructions是否清楚? ↓ ④ Permission 当前Action是否需要Approval? ↓ ⑤ Execution Tool运行在哪里,权限由谁负责? ↓ ⑥ Context 返回内容是否过多或不相关? ↓ ⑦ Verification 有没有证明任务真正完成?这个顺序比不停修改Prompt有效得多。
因为它把:
“MCP不好用”
拆成了7个可以明确诊断的层级。
十四、从MCP开始,Agent工程真正进入“Tool Engineering”
如果把最近几篇连起来,会发现一个非常明显的变化。
最早关注的是:
Prompt Engineering。
解决:
怎么和模型说。
然后开始关注:
Context Engineering。
解决:
Agent应该持续知道什么。
Skills继续往前:
Workflow Engineering。
解决:
一类任务应该怎样重复执行。
而MCP带来的下一层就是:
Tool Engineering。
解决:
Agent应该拥有哪些能力,以及这些能力怎样被清楚、安全、可验证地调用。
最终变成:
Prompt ↓ Context ↓ Workflow ↓ Tools ↓ Execution ↓ Verification这已经不再是简单的“AI辅助编程”。
它更像是在设计:
Agent Runtime。
最后
MCP接入成功以后Codex仍然不好用,并不奇怪。
因为:
Connection只是第一步。
真正稳定的MCP系统还需要解决:
Tool有没有真正暴露;
模型知不知道什么时候调用;
Description够不够准确;
Server Instructions有没有给出工作边界;
Read、Write和Destructive Action有没有正确区分;
权限到底由Codex还是MCP Server负责;
Tool返回的信息是否适合当前上下文;
最后有没有可靠验证。
所以判断一个MCP是不是“好用”,不能只看:
Connected而应该看:
正确任务 ↓ 选择正确Tool ↓ 使用正确权限 ↓ 输入正确参数 ↓ 返回高质量Context ↓ 产生预期状态变化 ↓ 验证完成当这一条链真正稳定以后,
MCP才不是:
给Codex多装几个插件。
而是:
把外部系统真正变成Agent可以可靠操作的工程能力。
