﻿---
title: "插件 MCP 的 OAuth 写 camelCase，不要抄 config.toml 的蛇形键"
summary: "mcp.json 里是 clientId、callbackUrl、callbackPort。callbackUrl 里的端口不会改监听口；没写 callbackPort 就走全局或临时端口。带 clientId 但回调缺 ID 时，这份 URL 会被忽略。"
category: mcp
level: advanced
surfaces: [cli, app]
tags: ["plugins", "MCP", "OAuth"]
canonical: /tips/plugin-mcp-oauth-json/
---

# 插件 MCP 的 OAuth 写 camelCase，不要抄 config.toml 的蛇形键

mcp.json 里是 clientId、callbackUrl、callbackPort。callbackUrl 里的端口不会改监听口；没写 callbackPort 就走全局或临时端口。带 clientId 但回调缺 ID 时，这份 URL 会被忽略。

用户 `~/.codex/config.toml` 用蛇形：`client_id`、`callback_url`、`callback_port`。插件自带的 HTTP MCP 写在根目录 `mcp.json` 或 `.mcp.json`，字段是 camelCase。抄成 `client_id` 不会被当成插件 OAuth。

```json
{
  "mcpServers": {
    "sample": {
      "type": "http",
      "url": "https://mcp.example.com/mcp",
      "oauth": {
        "clientId": "my-pre-registered-client",
        "callbackUrl": "http://127.0.0.1/callback/registered",
        "callbackPort": 4321
      }
    }
  }
}
```

可移植 Agent Plugins 包还可以给文件加 `$schema`，并把 `type` 写成 `streamable-http`。OAuth 对象规则一样。密钥不要写进这份 json。

`callbackUrl` 里的端口不会选择监听口。要固定本机回环端口，`callbackUrl` 和 `callbackPort` 写成同一个数，例如 `http://127.0.0.1:4321/callback/registered` 配 `"callbackPort": 4321`。插件的 `callbackPort` 盖过全局 `mcp_oauth_callback_port`；两边都空就用操作系统临时端口。代理入口的 URL 端口和本机监听口可以故意不同。

插件给了 `clientId`、授权服务器又不广告 issuer-bound 回调、而且 `callbackUrl` 缺少这台服务器的 callback ID 时，Codex 会忽略这份 URL，改用 `mcp_oauth_callback_url`（未设则 `http://127.0.0.1/callback`）再拼上 callback ID。磁盘里的 `callbackUrl` 不会被改写，所以看起来「清单写对了却登不上」。登录时登记终端打印出的完整回调，不要只抄清单。

用户侧仍只能改开关和审批，改不了插件 MCP 的启动命令：

```toml
[plugins."sample@test".mcp_servers.sample]
enabled = true
default_tools_approval_mode = "prompt"
```

兼容布局里，根上的 `.mcp.json` 还要在 overlay 把 `mcpServers` 指到 `./.mcp.json`，否则这份 OAuth 根本不会被导入。Admin 导入带 MCP 的插件仍是 Desktop only。

## 来源

- [OpenAI · Model Context Protocol](https://learn.chatgpt.com/docs/extend/mcp)
