Skip to content

[v0.8 MCP 5] enforce project MCP trust boundaries - #1337

Open
sethkarten wants to merge 2 commits into
core02-host-request-dispatcherfrom
v080/mcp-split-m5-project-trust
Open

[v0.8 MCP 5] enforce project MCP trust boundaries#1337
sethkarten wants to merge 2 commits into
core02-host-request-dispatcherfrom
v080/mcp-split-m5-project-trust

Conversation

@sethkarten

@sethkarten sethkarten commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Replacement scope

This PR reconstructs and supersedes the unique implementation delta reviewed in #1263 without rewriting that historical branch. The original PR remains the immutable discussion record: #1263

  • Base: core02-host-request-dispatcher
  • Replacement branch: v080/mcp-split-m5-project-trust
  • Replacement commit: a3ef6b6697d867a6740eaf8e8592ca85487b4f86
  • Propagation/reconciliation merge commits are intentionally excluded.
  • fix(mcp): make cleanup failures observable #1264 is intentionally omitted from the replacement stacks because its declared-base-to-head tree delta is empty.
  • Frozen feat(kernel): dispatch host requests as capabilities #1243 (77b188b92dc91365cb2bc41bdb46a50669d104a8) is the shared foundation. For reconstructed deltas it is a proven tree-compatible base, not an ancestry claim about the historical PR stack.

Validation

  • Biome 2.5.5 on the exact changed paths: pass
  • root tsgo --noEmit: pass
  • Core focused suite on the final Core tip with live daemon/RLM environment removed and single-worker execution: 11 files, 388 tests passed
  • MCP focused suite on the final MCP tip: 9 files, 106 tests passed
  • Independent Terra tree/delta review: pass

No original PR was retargeted, closed, merged, or otherwise mutated.


Note

High Risk
Changes security-sensitive project filesystem access, trust policy, and MCP wiring at CLI/SDK startup; misconfiguration or stale bindings fail closed by omitting project declarations rather than surfacing errors in some paths.

Overview
Introduces declarative MCP endpoint records (name, HTTP(S) URL, enabled) separate from legacy mcpServers, plus a new prime-agent mcp command family for list/inspect/preview/test/add/enable/disable/remove on user or --project scope. Commands only mutate declarations, redact sensitive output, and test returns an offline initialize probe—no runtime or auth.

Project scope is gated by a global mcpProjectTrustPolicy (allowed directories + revision). The CLI loads global settings only before admitting project work; denied or malformed policy never opens project settings. Admitted access uses opaque admission tokens, a pinned-directory trust authority (retained root FD + binding validation), and descriptor-relative reads/writes of .prime/agent/settings.json via a bounded Python helper.

Session/SDK startup composes admission before full SettingsManager project load, builds an immutable runtime declaration snapshot (user first; project merged only when admission stays valid; name/endpoint collisions drop the whole project contribution), and passes it to McpManager via getDeclarationSnapshot() while host handlers still use global-only legacy servers. Injected McpManager instances are left untouched.

Reviewed by Cursor Bugbot for commit 15f003a. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Enforce MCP project trust boundaries with admission-gated declaration snapshots

  • Introduces a McpProjectTrustAuthority that pins project directories via retained file descriptors and issues opaque, revocable bindings; bindings are validated before and after use to detect identity changes (ABA, symlink swaps, root replacement).
  • Adds ProjectMcpDeclarationAdmission as a capability token gating all project MCP declaration reads and writes; admission is derived from a global trust policy and released after session initialization.
  • Builds a single immutable McpRuntimeDeclarationSnapshot combining user and (admission-gated) project declarations, with collision detection, deterministic code-point ordering, and a SHA-256 revision digest; McpManager exposes this via getDeclarationSnapshot().
  • Adds a ProjectSettingsOpenat class that reads/writes .prime/agent/settings.json through a sandboxed stdlib-only Python helper over a dirfd, enforcing size/time limits and cooperative locking without exposing project paths.
  • Extends the CLI with an mcp command group (list, inspect, preview, test, add, enable, disable, remove) that enforces project trust policy for --project scope and outputs redacted JSON.
  • Risk: project MCP declarations are silently omitted (fail-closed) whenever admission is absent, invalid, or revoked — including mid-session identity changes to the project root directory.

Macroscope summarized 15f003a.

Reconstruct the unique net delta from PR #1263, excluding propagation merges.
Comment thread packages/coding-agent/src/cli/command-registry.ts
Register every supported MCP child command and describe declaration tests as offline previews.
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