feat: compose authenticated stdio MCP with explicit runtime tool mapping
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / pytest-smoke (push) Failing after 3s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e747-8f27-7242-8df8-8bc44f88c929
This commit is contained in:
tegwick 2026-09-28 12:38:04 +02:00
parent 1ece969f59
commit 3c5cbfbafe
14 changed files with 465 additions and 81 deletions

View file

@ -152,3 +152,56 @@ query strings are cleared before response-time application access logging, but
reverse proxies and tracing collectors must independently suppress callback
queries, cookies and authorization headers. No public listener is enabled by
these source changes.
## MCP caller composition and backend mapping
The standalone CLI now registers only four tools with equivalent runtime APIs:
| MCP tool | Runtime GET route |
| --- | --- |
| `query_repository_navigation` | `/ports/projections/repository-navigation/repositories` |
| `get_repository_navigation_facet` | `/ports/projections/repository-navigation/facets/{facet_kind}/{facet_value}` |
| `query_workloads` | `/ports/projections/workloads` |
| `resolve_workload_reference` | `/ports/projections/workloads/resolve` |
These use exact paths without redirect-based slash normalization. The other 27
generic tools require embedded host APIs: state/domain orientation, message
read/write/reply, capabilities/requests, repo/DOI operations, service/TPSC and
legacy progress operations. They remain available in the SDK's default
`backend_profile="embedded"`; they are not advertised by the standalone runtime
profile. Native message/event commands are not equivalent replacements for legacy
thread, recipient, author or event semantics. The inventory records each tool's
backend profiles. Host-specific routing and caller admission remain T04/T05 work.
For a **private, single-principal stdio process**, an operator can project an
already admitted Hub-audience credential and run:
```sh
HUB_CORE_ENV=production hub-core mcp --transport stdio \
--api-base https://hub.example --token-file /run/secrets/hub-mcp-caller
```
The file is reread for every request, with bounded size and sanitized errors.
Missing, invalid or expired credentials cannot fall back to anonymous/shared-root
access. Expiry, issuer, audience and current grants are checked by the Hub API.
The CLI neither obtains nor refreshes credentials; the projecting owner controls
rotation. This example is a composition interface, not an issued grant or live
acceptance. Do not share this process between principals or use an operator/root
token as an automated workload identity.
Enforced CLI network transports refuse startup: a shared MCP endpoint needs a
host that authenticates callers. `--token-file` is rejected for every network
transport, including development. The host SDK composition supplies
`token_provider=current_invocation_hub_credential`, `require_credentials=True`,
and an explicit backend profile. The provider must resolve the authenticated
invocation's **Hub-audience** credential; forwarding an MCP-audience token or
putting a static root token in the callback is not an admitted composition.
The SDK does not implement token exchange, delegation or host authentication.
Authenticated outbound requests require non-local HTTPS, never follow redirects,
and ignore proxy environment variables. Tools never accept credentials as model
arguments. Facet path segments reject traversal/separator/query injection.
Tests exercise actual FastMCP tool invocation with distinct concurrent caller
contexts, file rotation/removal, route-catalog admission for all four runtime
tools, enforced backend denial and CLI transport restrictions. They do not claim
that an external MCP consumer or workload has been admitted.