Skip to content

Align MCP origin defaults and credential selection - #80

Merged
SaladDay merged 5 commits into
mainfrom
codex/mcp-credential-selection
Sep 23, 2026
Merged

SaladDay merged 5 commits into
mainfrom
codex/mcp-credential-selection

Conversation

@SaladDay

@SaladDay SaladDay commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

The minimal pinned-SDK MCP tool {type, server_label, transport} now works on Core, as it does officially. Session MCP credential selection now projects and reports errors like the official service. The pinned baseline is unchanged (SDK 3.13.0 / d7c41ef / agents=v1).

Behavior

  • Omitted or null connection_origin on HTTP transport:
    • It is saved and projected as "service" for saved Agents, inline Session agents and per-Session replacements.
    • The stored and frozen configuration is byte-identical to an explicit service declaration, so execution is unchanged.
    • Explicit environment and non-HTTP transports stay rejected, now with an accurate message.
  • Selected credential projection:
    • An MCP tool without an explicit credential_id shows the implicitly selected attached credential's ID in Session retrieve, list and the created, in-progress and idle event snapshots.
    • The ID is shown only when the frozen binding's Vault is among the Session's vault_ids.
    • It stays after the credential is deleted.
    • Anonymous and unmatched tools stay null.
    • The stored caller intent and retry rules are unchanged; the old "frozen private selections never populate an omitted public credential_id" rule is replaced.
  • Selection errors (checked after the none input requirement, before any write; caller values echoed only under the shared bounded-echo rule):
    • credential_id without vault_ids: 400 "MCP credential_id requires an attached vault".
    • Missing, foreign-tenant, unattached or malformed ID: one uniform 400 "MCP credential_id was not found in an attached vault", byte-identical across these cases.
    • An attached credential for another URL: 400 "MCP credential_id does not match server_url ".
    • Several implicit matches: 409 conflict_error "multiple attached vault credentials match MCP server_url ; specify credential_id".
    • An unknown Vault is still 404.
  • Security: the credential lookup is tenant-scoped and limited to attached, owned Vaults. Only non-secret IDs are shown; no token or ciphertext is read. Dispatch credential resolution is unchanged and stays fail-closed.

Evidence

  • MV-01..03 (campaign scan 6: owned official Sessions, Agents, Vaults and credentials, all deleted).
  • Recorded in credentials.md, both READMEs, official-semantics-alignment.md and operation-evidence.md (register MV).

Validation

  • Independent acceptance, written from the requirements only: real Core with PostgreSQL, raw HTTP and the pinned SDK, 551 checks, no official or model calls.

    Row main candidate
    M1 origin default FAIL PASS 104/104
    M2 selected credential projection FAIL PASS 69/69
    M3 no attached Vault FAIL PASS 32/32
    M4 uniform not-found FAIL PASS 82/82
    M5 URL mismatch FAIL PASS 24/24
    M6 ambiguous selection FAIL PASS 28/28
    M7 unknown Vault, M8 ordering and no write, M9 dispatch, tenant B PASS PASS

    The script was unchanged between runs (same sha256).

  • Live Turn: real Core, the daemon, native Codex and Kimi K3 on environment: none, images built from each tree, with a new local MCP test server fixture.

    • On main, the minimal tool without connection_origin is rejected with 400 and nothing is created.
    • On the candidate, it runs a Turn with a completed mcp_call returning the fixture marker, and the Session shows connection_origin: "service".
    • All 29 events and reads pass the pinned SDK's strict parse. Cleanup and secret scans passed.
  • Tests: Go API, execution and store tests, including a real-PostgreSQL public test for tenants A and B, byte-identical not-found bodies and headers, and a whole-database no-write digest. Also the pinned-SDK official client suite and the TS client and Core Web tests.

  • Server gate: all make check targets, plus Web typecheck, core-doctor, unit tests and build, pass. The Playwright browser cases were not run on the server (no Google Chrome; the user approved the skip). make openapi and make sqlc-generate are byte-identical.

  • Independent blind review by a fresh Claude Code subagent (the user-approved replacement for GPT-6 Astra). It found no blockers and confirmed:

    • tenant scoping;
    • indistinguishable not-found cases;
    • byte-identical origin defaults;
    • projection limited to attached Vaults;
    • unchanged fail-closed dispatch.

    Its follow-ups are fixed in the last commits: the stdio message, the fixture cleanup, key order and a test guard. They were verified by focused tests and the gate without a new review, per the user's rule.

Not in this change: input after an attached credential is deleted (MV-04) and MCP configuration validation (MV-05/06). No full protocol compatibility is claimed.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

The official service stores an omitted or null connection_origin on an
HTTP MCP tool as "service" (MV-01). Default it before the existing checks,
so saved Agents, inline Session agents and per-Session replacements store
exactly the explicit declaration and execution is unchanged. The
environment origin and other transports keep their rejection.
Session reads, lists and event snapshots now show the credential that
creation implicitly selected for an MCP tool without an explicit
credential_id (MV-02), also after it is deleted. Only the response changes:
the stored caller intent, retries and dispatch are unchanged, and only a
binding whose Vault the Session attached is shown.

Selection errors use the official fields (MV-03): a reference without
vault_ids, outside the attached Vaults or for another server_url is a 400
invalid_request_error, and several implicit matches a 409 conflict_error.
Missing, foreign-tenant and unattached references share one message, and
caller values are echoed only within the shared bound.
Update the handler annotations, OpenAPI, CONTRIBUTING, the service README,
credentials guide, contract README, the dated alignment section and the
operation evidence register (MV).
A stdio tool with an omitted origin reported the explicit-origin error,
although explicit service is rejected for it too. Non-HTTP transports now
report that only HTTP transport is supported, with the same status, type
and code. The official MCP script also deletes its reference Agent.
The projection re-marshalled the tool through a map and reordered its
members. Replace only the credential_id value in document order. The unit
test checks the order; the stored caller intent is covered by the
PostgreSQL storedNull guard.
@SaladDay
SaladDay merged commit d10ccfc into main Sep 23, 2026
2 of 3 checks passed
@SaladDay
SaladDay deleted the codex/mcp-credential-selection branch October 7, 2026 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant