Skip to content

feat(mcp): bump @contentrain/mcp to 1.10.0 — session fingerprint + media tool classes#145

Merged
ABB65 merged 1 commit into
mainfrom
feat/mcp-1-10-0
Jul 13, 2026
Merged

feat(mcp): bump @contentrain/mcp to 1.10.0 — session fingerprint + media tool classes#145
ABB65 merged 1 commit into
mainfrom
feat/mcp-1-10-0

Conversation

@ABB65

@ABB65 ABB65 commented Jul 13, 2026

Copy link
Copy Markdown
Member

What

Studio integration for @contentrain/mcp 1.10.0 (+ @contentrain/types 0.8.0, @contentrain/query ^6.2.1) — the two items upstream flagged for Studio, plus the media groundwork.

Write-path safety (bump rule)

Per the post-1.8.0 lesson, the git internals were diffed before trusting the mocked suite: git/transaction, git/branch-lifecycle, core/ops and providers/github chunk graphs are byte-identical between 1.8.1 and 1.10.0 (only hash-suffix noise). The bump does not touch the content write path. A real staging save after merge remains the final check.

Session fingerprint (tenant binding)

The loopback server now passes 1.10.0's sessionFingerprint, derived from the same x-cr-* headers resolveProvider reads (mcpTenantFingerprint in mcp-cloud-runtime.ts, unit-tested). Sessions are bound to the tenant identity they were created with — replaying an Mcp-Session-Id with another project's headers 404s and the client re-initializes against its own provider. Closes cross-tenant session-id replay on the shared loopback.

Media tools (5 new; 24 total)

  • MEDIA_* tool classes derive from the new TOOL_REQUIREMENTS availability contract (media: true facet requirement) — upstream's suggested source of truth.
  • Media writes are excluded from the content write set: they pass through the provider's media facet, never git → no brain-cache invalidation, no auto-merge reconcile (upstream's explicit Studio note).
  • Scope wiring: media:readmedia_list/media_get, media:writeingest/update/delete; step-up challenges route media tools to the right scope.
  • ADVERTISED_SCOPES unchanged — Studio's loopback provider doesn't implement the media facet yet, so the MCP server hides the tools from tools/list entirely. Scope enforcement is already correct for the day the facet ships; advertising flips then (remaining Studio work per upstream: loopback media facet implementation + MCP key scope model).

Bonus

1.10.0 closes PR4's upstream audit gap: openWorldHint is now present on all 24 tools (media_ingest is the only openWorldHint: true; media_delete is destructiveHint: true) — the OpenAI annotation requirement is fully satisfied.

Tests

Media class partition pins (disjoint metadata/read/write/media/lifecycle), media scope derivations + no-leak into content scopes, tenant-fingerprint unit suite (stability, per-component sensitivity, missing-header behavior).

pnpm lint ✓ · pnpm typecheck ✓ · unit+integration+nuxt 1004 ✓ · managed e2e smoke 12/12 on 1.10.0 ✓

…dia tool classes

Write-path safety: git/transaction, git/branch-lifecycle, core/ops and
providers/github chunk graphs are byte-identical between 1.8.1 and
1.10.0 (hash-suffix noise only) — the bump does not touch the content
write path. A real staging save after merge stays on the checklist.

- deps: @contentrain/mcp 1.8.1→1.10.0, @contentrain/types 0.7.0→0.8.0,
  @contentrain/query ^6.1.1→^6.2.1
- loopback server: pass 1.10.0's sessionFingerprint, derived from the
  SAME x-cr-* tenant headers resolveProvider reads (helper in
  mcp-cloud-runtime.ts) — a stolen Mcp-Session-Id replayed with another
  project's headers now 404s and the client re-initializes cleanly
- tool classes: MEDIA_* sets derived from the new TOOL_REQUIREMENTS
  availability contract; media tools excluded from the content write
  set (they pass through the media facet, never git — no brain
  invalidation, no auto-merge reconcile) and from content:read
- scopes: media:read → list/get, media:write → ingest/update/delete;
  scopeForTool routes media step-up challenges. ADVERTISED_SCOPES
  unchanged — the loopback provider has no media facet yet, so the MCP
  server hides the tools; flip advertising when the facet ships
- 1.10.0 closes the PR4 audit gap: openWorldHint present on all 24
  tools (ingest is the only openWorldHint:true, delete is destructive)
- tests: media class partition + scope derivations, tenant-fingerprint
  unit suite; managed e2e smoke green on the new package
@ABB65
ABB65 merged commit 003faee into main Jul 13, 2026
2 checks passed
@ABB65
ABB65 deleted the feat/mcp-1-10-0 branch July 13, 2026 10:35
ABB65 added a commit that referenced this pull request Jul 13, 2026
Implements RepoProvider.media on the loopback provider so
contentrain_media_list/get/ingest/update/delete work on both MCP Cloud
surfaces, with policy at the proxy and mechanism at the loopback.

- server/utils/mcp-media-facet.ts: the contract MediaProvider as a
  deterministic passthrough over Studio's ee media stack — cursor
  pagination, tenant isolation (get→null / update+delete→404 on foreign
  assets), and the ingest quota dance (fetchRemoteMedia SSRF/MIME/size →
  reserveStorageIfAllowed → upload source:'agent' → reconcile/release).
  Returns null when useMediaProvider() is null (CE / no R2) so the
  tools stay hidden.
- proxy: STUDIO_HEADERS + x-cr-{project-id,workspace-id,media-owner,plan},
  injected ONLY when mediaEligible (media stack + plan media.upload +
  cdn_enabled + owner). Media tools are excluded from the empty-allowlist
  "unrestricted" rule — a key needs media_enabled or an explicit listing,
  so existing keys never silently gain URL ingest / destructive delete.
- loopback: resolveProvider builds the facet from the four proxy headers;
  git.ts carries RepoProvider.media; the tenant fingerprint gains the
  project id so an eligibility flip re-inits the session within a request.
- key surface: mcp_cloud_keys.media_enabled (migration 018, default false)
  + create route + panel "Allow media tools" toggle + Media badge.
- OAuth: advertisedScopes() adds media:read/media:write only where the
  media stack is configured; the 4 well-known routes inject availability;
  scope→tool mapping + step-up already routed media (from #145).
- deps already at 1.10.0 (#145). openWorldHint present on all 24 tools.
- tests: facet unit suite (18), fingerprint + scope/metadata units,
  proxy eligibility matrix + key media gate + oauth media path, contract
  media_enabled column case. lint/typecheck clean; unit+integration+nuxt
  1048, contract 105, managed e2e 12/12 (media absent without R2).

Co-authored-by: Contentrain <[email protected]>
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