Persist call-correlated MCP tool-contract provenance on completed tool calls
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Problem
Codex persists useful MCP tool-call provenance after execution—call ID, server, tool, thread/turn context, status, and result—but does not persist the exact effective tool contract that was bound to that completed call.
That leaves historical interpretation ambiguous when a provider's tool schema changes, a cache refreshes, the same server/tool name is reused with a different contract, or an offline/cached contract was used. Current metadata/status surfaces describe current/latest state rather than the exact contract used by the historical call; some status enumeration paths can also initialize enabled MCP servers, so they are not a passive provenance substitute.
Related issues cover adjacent pieces:
- #36297 — negotiated server identity / tools-schema fingerprinting
- #36298 — preserving structured MCP schemas in the host-visible catalog
- #36994 — immutable provenance propagated into tool execution context
This request is specifically about binding the exact effective tool contract to the completed historical MCP call.
Requested behavior
When Codex has already prepared an MCP call, persist optional bounded provenance derived from that exact prepared contract on the completed call item:
- a versioned, deterministic contract fingerprint;
- optionally a privacy-safe bounded contract snapshot;
- correlation through the existing completed call/thread/turn identifiers;
- equivalent support in legacy and paginated rollout representations and app-server history.
The snapshot should be produced from contract state already bound in memory for the call. It should perform no additional server initialization, tools/list, resource enumeration, authentication, network/provider request, or tool execution.
Persistence should remain best-effort: canonicalization, fingerprinting, attachment, or rollout-write failure must not alter the tool result, turn success, or task completion, and should not introduce retries.
Privacy / security boundary
The durable representation should include only a privacy-approved structural contract. It should exclude raw tool arguments/results, prompts/transcripts, auth/configuration state, credentials, unrestricted _meta, defaults/examples, external-reference contents, provider URLs/identifiers or other arbitrary value-bearing fields not required for safe structural provenance.
The persisted fingerprint should be computed from that same safe retained representation, rather than acting as a hash oracle over material intentionally excluded from persistence.
Tool annotations remain untrusted hints; persisting them must not make them authoritative.
Why this is useful
Call-correlated contract provenance would improve:
- reproducibility of historical tool calls;
- schema-drift diagnosis;
- MCP debugging;
- audit/provenance;
- incident analysis;
- thread/history interpretation without consulting mutable current provider state.
Implementation feasibility evidence
I validated the seam against public codex-rs source. The natural point is the already-bound PreparedMcpCall / ToolInfo, before completion persistence, so the host already has the exact contract used for execution and does not need to re-enumerate the provider.
A local provider-neutral reference implementation was prepared against public Codex source and audited/forward-reviewed for upstream quality. The implementation is not installed or submitted. It demonstrated:
- versioned bounded
ToolContractSnapshotV1+ SHA-256 fingerprinting; - exact
PreparedMcpCallbinding and catalog-revision protection; - no extra provider operations;
- best-effort/fail-open provenance construction and persistence;
- legacy and paginated rollout persistence;
- thread history/resume and app-server v2 projection;
- backward-compatible optional fields;
- privacy-safe fingerprinting derived only from the persisted safe structural snapshot;
- deterministic same-contract fingerprints and drift-sensitive structural fingerprints.
Focused validation on the reference implementation passed:
codex-mcp: 195/195codex-protocol: 276/276codex-app-server-protocol: 290 passed, 1 platform-gated skipcodex-thread-store: 222/222codex-rollout: 120/120- focused app-server integration: 3/3
- forced persistence-failure regression: passed
- stable/experimental schema generation/equivalence: passed
- scoped Clippy and Rust formatting: passed
Broader workspace-wide validation was limited by unrelated local environment gaps (missing helper binaries / unavailable Bazel-Python formatting tooling), so I am not claiming the full workspace suite is green.
If useful, I can provide a compact implementation sketch or exact affected source seams, but the main request is for the generic provenance capability rather than review of a downstream-specific integration.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the already-bound PreparedMcpCall and ToolInfo seam in codex-rs, then trace completed-call persistence through legacy and paginated rollouts, thread history, and app-server v2. Review the codex-mcp, codex-protocol, codex-app-server-protocol, codex-thread-store, and codex-rollout tests; done means bounded privacy-safe provenance is persisted without extra provider operations and failures remain best-effort.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100