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.
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
- 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
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.
| Surface | Contract |
|---|---|
| Discovery | Eight advertised scopes and nine registered tools. Approved authenticated callers can list the static registry without tool grants; execution remains scope-checked. |
| Connected context | One fixed context supports search, exact read and append-only write. |
| Other contexts | Two registered context families are disconnected and fail closed. One additional scope family is metadata-only, with no tools or storage mapping. |
| Client identity | Client 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
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.
Append evidence. Do not promote trust.
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 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.
| Request | Outcome |
|---|---|
| Same identity + key + exact content | Already committed receipt; no duplicate rows. |
| Same identity + key + changed content | Conflict; no overwrite. |
| New key + same content | A new append, intentionally. |
| Same key, different actor or client | A 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 failure | Boundary | Residual limit |
|---|---|---|
| Unauthenticated caller or wrong-resource token | JWT validation, exact issuer/audience, request bounds. | A stolen valid bearer remains replayable until expiry or policy rejection; no demonstrated instant revocation. |
| Approved caller exceeding grants | Exact scope checks at HTTP and service layers. | Authorization-server issuance policy must also be correct. |
| Caller guessing another context's IDs | Fixed routes and native membership predicates. | Privileged gateway/native compromise crosses these trust boundaries. |
| Prompt-injected or poisoned memory | No arbitrary routing; pending evidence; no promotion API. | Malicious text can still misuse permissions the client already holds. |
| Lost response or duplicate submission | Durable command identity, content digest, transaction lock and uniqueness. | A new key creates a new append; there is no semantic deduplication. |
| Stolen native capability | Separate operation capability and fixed destination. | The holder can act within that authority; actor attribution is trusted from the gateway. |
| Compromised host identity or outage | Protected 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 pattern | Alternative & consequence |
|---|---|
| FastMCP + native Descope integration, tightened verifier | Bespoke OAuth duplicates protocol work; provider defaults alone do not enforce the full resource contract. |
| One resource audience, independent scopes, fixed mappings | Separate resources give stronger domain boundaries but require more registration and lifecycle management. |
| Operation-specific native capabilities | A broad backend credential simplifies setup but expands gateway authority. |
| Native lifecycle and atomic append | A parallel store or retry ledger introduces split authority and synchronization. |
| Pending evidence, no trust promotion | Upsert and promotion are convenient but add mutation and instruction authority. |
| Static tool registry, call-time enforcement | Scope-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.
| Status | What was established |
|---|---|
| Passed | 40 Python and 12 native tests; source review of authentication, scope boundaries, persistence and retry semantics. |
| Corroborated | Authenticated search requests and a durable generated/pending write, with linked native records and no duplicate trust-promoted sidecar. |
| User-reported | Successful client authentication and read experience. Independent logs do not establish the exact contents delivered to the client. |
| Not yet proven | OAuth 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.