PRIVATE CONTEXT / MCPPublic architecture
Architecture guide · 01

Useful context.
Bounded authority.

How an MCP client authenticates, accesses a fixed memory context, and appends evidence without acquiring trust-promotion authority.

Architecture snapshot · October 7, 2026 · Sanitized public edition

One system of record. Three decisions.

Claude Code uses OAuth to access a Python/FastMCP resource server. Descope owns authentication and token issuance; Cloudflare supplies public TLS ingress. A fixed adapter connects the gateway to a narrow native OB1 route using a separate server-side capability.

01 / IDENTITYWho is calling?Cryptographically verified token, exact resource audience, and approved subject.
02 / AUTHORITYMay this tool run?The exact read or write OAuth scope, enforced at HTTP and service boundaries.
03 / MEMBERSHIPWhich records?Fixed native destination, operation capability, and database membership predicates.
A successful login is not permission for every tool. A listed tool is not proof its backend is connected. An accepted write is not a trusted instruction.

This edition explains behavior without live service URLs, deployment identifiers, account details, credentials, operational runbooks or private records. Context names below are generic labels, not an endpoint catalog.

Components & trust boundaries

Components and trust boundariesMCP client to Public gateway: TLS ingress + resource-bound OAuth bearer. Public gateway to Native adapter: Verified actor + exact tool grant. Native adapter to Native storage: Fixed route + separate operation capability. Native storage to MCP client: Bounded result or accepted receiptMCP clientPublic gatewayNative adapterNative storageTLS ingress + resource-bound OAuth bearerVerified actor + exact tool grantFixed route + separate operation capabilityBounded result or accepted receipt
1 / Topology. Descope issues the client token; Cloudflare provides TLS ingress. The OAuth bearer stops at the gateway. OB1 remains the system of record.
  • Authorization server: login, consent, client registration, codes, tokens and refresh policy.
  • Gateway: bearer validation, approved subject, tool authorization, bounded requests and fixed adapters.
  • Native worker: operation-specific capability validation, bounded projection, native persistence and embeddings.
  • OB1: existing memory tables, provenance, review state and lifecycle. No shadow datastore or parallel retry ledger.

The OAuth bearer is not forwarded downstream. The native route trusts actor attribution from the authenticated gateway. TLS termination is part of the infrastructure trust boundary; loopback and an encrypted host-to-host link do not isolate a compromised gateway OS identity.

OAuth & independent grants

OAuth authorization and discoveryMCP client to Resource server: Request without a valid bearer. Resource server to MCP client: 401 + protected-resource metadata location. MCP client to Descope: Discovery + authorization request + PKCE. Descope to User: Authentication and consent. User to Descope: Approve requested grant. Descope to MCP client: Authorization code via registered redirect. MCP client to Descope: Code + verifier. Descope to MCP client: Resource-bound access token. MCP client to Resource server: Initialize / tool calls with bearerMCP clientResource serverDescopeUserRequest without a valid bearer401 + protected-resource metadata locationDiscovery + authorization request + PKCEAuthentication and consentApprove requested grantAuthorization code via registered redirectCode + verifierResource-bound access tokenInitialize / tool calls with bearer
2 / OAuth. Protocol responsibilities, not a captured login trace. Refresh tokens depend on authorization-server policy; refresh behavior is not yet independently verified.

The resource server verifies a signed RS256 JWT using a trusted configured JWKS endpoint, exact issuer and resource audience, an approved subject, and bounded issued/expiry times. Tokens belong in the Authorization header. Public OAuth discovery metadata does not grant tool access.

Read and write grants are independent. Write-only access cannot search or read; read-only access cannot append. No tool argument selects a workspace, project, backend URL or arbitrary route.

SurfaceContract
DiscoveryEight advertised scopes and nine registered tools. Approved authenticated callers can list the static registry without tool grants; execution remains scope-checked.
Connected contextOne fixed context supports search, exact read and append-only write.
Other contextsTwo registered context families are disconnected and fail closed. One additional scope family is metadata-only, with no tools or storage mapping.
Client identityClient ID is attribution and retry identity, not a separate resource-server client allowlist. Client-to-scope issuance policy belongs at the authorization server.

Transport: stateless JSON Streamable HTTP. Protected requests authenticate individually; an MCP session is not an authorization credential.

Search & exact read

Scoped search and exact readMCP client to Gateway: Search query or exact record ID + bearer. Gateway to Native worker: Read grant checked twice; fixed read capability. Native worker to Database: Fixed membership + lifecycle + visibility predicates. Database to Native worker: Only eligible records. Native worker to Gateway: Bounded fields + provenance + use policy. Gateway to MCP client: MCP resultMCP clientGatewayNative workerDatabaseSearch query or exact record ID + bearerRead grant checked twice; fixed read capabilityFixed membership + lifecycle + visibility predicatesOnly eligible recordsBounded fields + provenance + use policyMCP result
3 / Read. Membership predicates apply before record IDs or content are returned. Exact reads and search use the same boundaries.

Search is lexical, not semantic: PostgreSQL full-text matching with deterministic recent-first ordering. Write embeddings preserve compatibility with other native semantic recall paths; they do not make this connector's search vector-based.

The database filters exact destination membership, project visibility, active lifecycle, eligible review state, evidence permission and freshness before exposing IDs or content. Exact read applies the same rules. A guessed out-of-context ID is unavailable.

  • Search: nonblank query, at most 300 characters; 1–10 results.
  • Read: one record ID; the native route requires a UUID.
  • Result: bounded content, provenance, review state and use policy—not unrestricted storage metadata.
Pending evidence can be readable without being instruction-grade. The client must preserve that distinction when using retrieved content.

Append evidence. Do not promote trust.

Append-only evidence writeMCP client to Gateway: Content + UUIDv4 idempotency key + bearer. Gateway to Native worker: Write grant + fixed capability + verified actor. Native worker to Database: Check committed command identity. Database to Native worker: Replay / conflict / needs embedding. Native worker to Database: For new command: embedding + atomic transaction. Database to Native worker: Commit generated / pending evidence. Native worker to Gateway: Accepted only after commit or identical replay. Gateway to MCP client: Accepted receipt; no content or record IDMCP clientGatewayNative workerDatabaseContent + UUIDv4 idempotency key + bearerWrite grant + fixed capability + verified actorCheck committed command identityReplay / conflict / needs embeddingFor new command: embedding + atomic transactionCommit generated / pending evidenceAccepted only after commit or identical replayAccepted receipt; no content or record ID
4 / Write. For a new command the worker obtains an embedding before the final transaction. The transaction links memory, thought, source attribution and audit atomically.

A write accepts bounded content and a canonical UUIDv4 idempotency key. Its native transaction creates one generated/pending memory, one linked embedded thought, source attribution and an audit event. Evidence use is allowed; instruction use is disallowed and confirmation is required.

The memory is reserved before the thought is inserted so native linkage reuses the pending row rather than producing a second, trusted sidecar. This is a bounded native extension using existing tables and lifecycle—not a replacement memory system.

  • Content: at most 8,000 characters and 16,000 UTF-8 bytes.
  • Successful application receipt: {"status":"accepted"}, only after commit or an identical committed replay.
  • No record ID, content echo, implicit read, overwrite or promotion authority.
  • Separate read authorization is required to retrieve contents.

Content heuristics reject detected credential/private-key, raw-transcript and large-code patterns. They are not comprehensive DLP or a semantic prompt-injection defense.

Retry the command, not a new append.

Retry after an uncertain write outcomeMCP client to Gateway: Content A + key K. Gateway to Native transaction: Commit command identity + digest A. Native transaction to Gateway: Accepted; client response may be lost. MCP client to Gateway: Retry identical identity + K + A. Gateway to Native transaction: Look up committed command. Native transaction to MCP client: Accepted; no duplicate append. MCP client to Native transaction: Same identity + K, changed content B. Native transaction to MCP client: Conflict; nothing overwrittenMCP clientGatewayNative transactionContent A + key KCommit command identity + digest AAccepted; client response may be lostRetry identical identity + K + ALook up committed commandAccepted; no duplicate appendSame identity + K, changed content BConflict; nothing overwritten
5 / Retry. Arrows simplify the response path. Public backend failures are bounded MCP tool errors; internal conflict status is not exposed as a public HTTP 409.

Retry identity binds the fixed context, destination, verified issuer, subject, client ID (or explicit null) and caller UUID. Content has a separate exact digest. Native locking and uniqueness serialize matching commands; the post-embedding transaction checks again.

RequestOutcome
Same identity + key + exact contentAlready committed receipt; no duplicate rows.
Same identity + key + changed contentConflict; no overwrite.
New key + same contentA new append, intentionally.
Same key, different actor or clientA different command identity.

After a timeout, the outcome may be unknown. Retry only with the original key and exact content. The gateway does not automatically retry writes. A committed replay can succeed without the embedding service.

Attacker model & residual limits

Attacker or failureBoundaryResidual limit
Unauthenticated caller or wrong-resource tokenJWT validation, exact issuer/audience, request bounds.A stolen valid bearer remains replayable until expiry or policy rejection; no demonstrated instant revocation.
Approved caller exceeding grantsExact scope checks at HTTP and service layers.Authorization-server issuance policy must also be correct.
Caller guessing another context's IDsFixed routes and native membership predicates.Privileged gateway/native compromise crosses these trust boundaries.
Prompt-injected or poisoned memoryNo arbitrary routing; pending evidence; no promotion API.Malicious text can still misuse permissions the client already holds.
Lost response or duplicate submissionDurable command identity, content digest, transaction lock and uniqueness.A new key creates a new append; there is no semantic deduplication.
Stolen native capabilitySeparate operation capability and fixed destination.The holder can act within that authority; actor attribution is trusted from the gateway.
Compromised host identity or outageProtected configuration, encrypted link, dedicated processes.Process separation is not OS-user isolation; bounded concurrency is not global rate limiting.

Application audits omit bearer tokens, queries and memory contents. Subject/client attribution is still identifying data and needs restricted access and retention. A successful HTTP status alone proves neither a useful tool result nor a durable write.

Decisions & trade-offs

Recommendation: retain the bounded, single-context design and prove the remaining client lifecycle behavior before expanding record membership or authority.

Selected patternAlternative & consequence
FastMCP + native Descope integration, tightened verifierBespoke OAuth duplicates protocol work; provider defaults alone do not enforce the full resource contract.
One resource audience, independent scopes, fixed mappingsSeparate resources give stronger domain boundaries but require more registration and lifecycle management.
Operation-specific native capabilitiesA broad backend credential simplifies setup but expands gateway authority.
Native lifecycle and atomic appendA parallel store or retry ledger introduces split authority and synchronization.
Pending evidence, no trust promotionUpsert and promotion are convenient but add mutation and instruction authority.
Static tool registry, call-time enforcementScope-filtered discovery improves UX; it never replaces execution authorization.

Consequences: predictable bounded access and durable evidence, at the cost of adapter/SQL maintenance, lexical-only connector search, explicit membership configuration and deployment-dependent availability.

Evidence, without overclaiming.

This page is an architecture snapshot, not a live status dashboard. Verification results below summarize the internal review; private logs, storage identifiers and test fixtures are intentionally not published.

StatusWhat was established
Passed40 Python and 12 native tests; source review of authentication, scope boundaries, persistence and retry semantics.
CorroboratedAuthenticated search requests and a durable generated/pending write, with linked native records and no duplicate trust-promoted sidecar.
User-reportedSuccessful client authentication and read experience. Independent logs do not establish the exact contents delivered to the client.
Not yet provenOAuth refresh and expiry recovery, JWKS rotation, authorization-server client-to-scope issuance policy, an independently captured live tool listing, and read-result delivery.

Standards & implementation references

These define protocol expectations; linking them is not a claim of exhaustive conformance testing.