😏
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
# Tool MCP Servers
|
||||
|
||||
Codex MMO distinguishes two unrelated uses of MCP:
|
||||
|
||||
- **Agent MCP** is the internal `mmo_mesh` server that launches and supervises profile
|
||||
participants.
|
||||
- **Tool MCP** connects Codex agents to third-party tools and context, such as a web-research
|
||||
service or a reverse-engineering application.
|
||||
|
||||
`mmo_mesh` is runtime-owned and reserved. Tool MCP definitions use operator-owned registry files;
|
||||
profile packs contain grants only. This keeps installed profile packs static and prevents one from
|
||||
introducing a local executable or remote endpoint.
|
||||
|
||||
Codex MMO compiles tool definitions to Codex's documented `[mcp_servers.NAME]` configuration.
|
||||
Codex 0.149 supports local STDIO processes and Streamable HTTP endpoints, environment-backed
|
||||
authentication, tool allow/deny lists, startup/tool timeouts, and server/tool approval policy. See
|
||||
the official [Codex MCP documentation](https://developers.openai.com/codex/mcp) and
|
||||
[configuration reference](https://developers.openai.com/codex/config-reference).
|
||||
|
||||
## Operator registry
|
||||
|
||||
Place registry fragments under:
|
||||
|
||||
```text
|
||||
~/.config/codex-mmo/tool-mcp.d/*.toml
|
||||
```
|
||||
|
||||
Fragments load in lexical filename order. When multiple fragments define the same server ID, the
|
||||
later definition replaces the complete earlier entry. Fields are not recursively retained across a
|
||||
transport change.
|
||||
|
||||
This example is illustrative; use the command, URL, and exact tool names documented by the MCP
|
||||
server you install:
|
||||
|
||||
```toml
|
||||
schema_version = 8
|
||||
|
||||
[tool_mcp_servers.firecrawl]
|
||||
transport = "streamable_http"
|
||||
url = "https://mcp.example.invalid/"
|
||||
bearer_token_env_var = "FIRECRAWL_API_KEY"
|
||||
enabled_tools = ["search", "scrape"]
|
||||
default_tools_approval_mode = "writes"
|
||||
startup_timeout_sec = 15
|
||||
tool_timeout_sec = 120
|
||||
|
||||
[tool_mcp_servers.firecrawl.tools.scrape]
|
||||
approval_mode = "prompt"
|
||||
|
||||
[tool_mcp_servers.ida_pro]
|
||||
transport = "stdio"
|
||||
command = "ida-pro-mcp"
|
||||
args = []
|
||||
env_vars = ["IDA_MCP_TOKEN"]
|
||||
enabled_tools = ["list_functions", "decompile"]
|
||||
default_tools_approval_mode = "writes"
|
||||
```
|
||||
|
||||
Every definition requires:
|
||||
|
||||
- A stable lowercase server ID other than `mmo_mesh`.
|
||||
- `transport = "stdio"` plus `command`, or `transport = "streamable_http"` plus `url`.
|
||||
- A non-empty `enabled_tools` array. This is the operator's maximum exposure, including for future
|
||||
profile grants.
|
||||
- An explicit `default_tools_approval_mode`: `auto`, `prompt`, `writes`, or `approve`.
|
||||
|
||||
The STDIO `command` may be a bare executable resolved through `PATH` or an
|
||||
absolute/tilde-expanded path. STDIO definitions may also use `args`, absolute/tilde-expanded `cwd`,
|
||||
non-secret literal `env`, and environment-forwarded `env_vars`. HTTP definitions may use
|
||||
`bearer_token_env_var`, non-secret `http_headers`, and environment-backed `env_http_headers`. Both transports accept
|
||||
`startup_timeout_sec`, `tool_timeout_sec`, `supports_parallel_tool_calls`, and per-tool approval
|
||||
overrides under `tools`.
|
||||
|
||||
The private app-server lifecycle wait is automatically at least 30 seconds longer than the
|
||||
largest enabled `startup_timeout_sec` for that role, and never less than twenty minutes. A valid long
|
||||
MCP startup therefore is not cut off by an unrelated fixed thread-start timeout. The separate
|
||||
`tool_timeout_sec` continues to bound each Tool MCP call; it is not a model-turn deadline.
|
||||
The generated `mmo_mesh` timeout is independently derived from the largest app-server lifecycle
|
||||
reachable through that caller's exact spawn/control grants, plus protocol overhead.
|
||||
|
||||
Schema version 8 rejects OAuth fields, plaintext bearer tokens, recognizable credential-bearing
|
||||
literal environment/header fields, transport-incompatible fields, and unknown fields. OAuth is not
|
||||
copied from the base Codex home because `.credentials.json` can contain credentials for unrelated
|
||||
MCP servers.
|
||||
|
||||
## Credentials
|
||||
|
||||
Put values in the existing operator credential file or the launch environment:
|
||||
|
||||
```bash
|
||||
${EDITOR:-vi} ~/.config/codex-mmo/credentials.env
|
||||
```
|
||||
|
||||
```dotenv
|
||||
FIRECRAWL_API_KEY=replace-me
|
||||
IDA_MCP_TOKEN=replace-me
|
||||
```
|
||||
|
||||
Snapshots and generated TOML contain only environment variable names. At session launch, the
|
||||
runtime forwards only names referenced by a server selected for that Codex process. Missing values
|
||||
are reported by `tool-mcp validate` and `profile doctor`; a profile's `required` policy determines
|
||||
whether Codex treats server startup failure as fatal.
|
||||
|
||||
## Profile grants
|
||||
|
||||
Grant servers independently to each role:
|
||||
|
||||
```toml
|
||||
[agents.researcher.tool_mcp_servers.firecrawl]
|
||||
required = true
|
||||
enabled_tools = ["search"]
|
||||
|
||||
[agents.reverse_engineer.tool_mcp_servers.ida_pro]
|
||||
required = true
|
||||
```
|
||||
|
||||
`required` defaults to `true`. Omitting `enabled_tools` grants the complete operator allowlist;
|
||||
otherwise it must be a non-empty subset. A profile cannot change the command, URL, credentials,
|
||||
headers, timeouts, parallel-call declaration, or approval policy. Omitting a server grant disables
|
||||
that server for the role.
|
||||
|
||||
The compiler stores normalized definitions and grants in the immutable snapshot. Changing a
|
||||
registry definition therefore changes future snapshot identity without changing a running session.
|
||||
|
||||
## Native-role behavior
|
||||
|
||||
Native roles share their parent's Codex process, and Codex recursively merges custom-agent config
|
||||
layers. The generated root config consequently contains the union of servers used by the root and
|
||||
reachable native roles. Each role layer explicitly enables its grants and disables every other
|
||||
server. The operator `enabled_tools` list remains constant, while role-specific narrowing is emitted
|
||||
as `disabled_tools`; this lets a child clear a narrower inherited deny-list without exceeding the
|
||||
operator maximum.
|
||||
|
||||
Tool visibility remains role-scoped, but process environment variables do not. If a native role
|
||||
uses an environment-authenticated MCP, its parent and sibling native agents share the containing
|
||||
process environment. Use a separately launched Agent-MCP participant when strict credential
|
||||
isolation is required.
|
||||
|
||||
## Security boundary
|
||||
|
||||
Codex shell settings do not constrain an external MCP server:
|
||||
|
||||
- `permissions = "read-only"` controls the Codex filesystem sandbox, not whether an MCP tool can
|
||||
mutate an IDA database, browser, SaaS account, or other external state.
|
||||
- `network_access = false` controls sandboxed shell networking, not an HTTP MCP connection or a
|
||||
local MCP process's own networking.
|
||||
- MCP server instructions and tool results are external content and may carry prompt injection.
|
||||
|
||||
Use narrow operator allowlists, conservative approval modes, per-tool `prompt` overrides for
|
||||
mutating operations, role-specific grants, and independent verification of consequential results.
|
||||
|
||||
## Inspection and diagnostics
|
||||
|
||||
These commands validate configuration without launching an MCP server:
|
||||
|
||||
```bash
|
||||
codex-mmo tool-mcp list
|
||||
codex-mmo tool-mcp show firecrawl
|
||||
codex-mmo tool-mcp validate
|
||||
codex-mmo tool-mcp validate firecrawl
|
||||
codex-mmo profile show PROFILE --resolved
|
||||
codex-mmo profile doctor PROFILE
|
||||
```
|
||||
|
||||
Readiness checks report command resolution, working-directory availability, and whether referenced
|
||||
environment variables are present. They never print credential values. Actual protocol/tool
|
||||
behavior remains a live acceptance concern; exercise it through a profile smoke task after reviewing
|
||||
the server and its tool schema.
|
||||
Reference in New Issue
Block a user