MCP auth custody and the tool broker: assess ShannonLink as a reference, and move connector auth to the account
- Dominant language
- Rust
- Stars
- 41k
- Forks
- 3.6k
- Avg merge
- 13h 59m
- Merged PRs (30d)
- 299
Description
Two related questions from the founder, recorded together because they answer
each other: should Codewhale adopt ShannonLink as its default, and should MCP
auth stop living on the local machine and live with the account.
## ShannonLink, as it actually is
`/Volumes/VIXinSSD/CW/shannonlink` — self-hosted, MIT, Python 3.11+. An
independently implemented agent-tool broker in the Composio shape (backend, not
just an SDK; no Composio account or API). Its own README is honest that it is a
development preview: 78 provider action definitions across 12 services, with
schema and rendering tests rather than live-provider certification.
What it has that is worth reading closely:
- **Credential custody**: tenant/user isolation, AES-256-GCM encrypted
credentials and sensitive payloads, multiple accounts per service, bearer /
API-key / basic / OAuth2.
- **OAuth**: authorization-code with PKCE, single-use state, same-browser
callback binding, token refresh, bring-your-own OAuth applications.
- **Sessions**: toolkit/action/account allowlists, call budgets, expiration,
revocation, read-only mode, scoped API keys.
- **Execution**: immutable intent fingerprints, write idempotency, **approval
gating**, bounded concurrency, read-only retries, and an explicit
"uncertain write" outcome rather than a guess.
- **Context**: large results retained as encrypted artifacts with JSON-pointer
selection and paging, and explicitly **no automatic stuffing of whole results
into model context**.
- **Events**: encrypted durable outbox, signed at-least-once delivery, retries,
dead letters, redrive.
- **MCP**: JSON-RPC server core shared by Streamable HTTP and a stdio bridge,
**three protocol versions** (`2025-03-26`, `2025-06-18`, `2025-11-25`),
protocol negotiation, and one catalog serialized to MCP, OpenAI and Anthropic
tool schemas. A small fixed meta-tool surface (`search`, `execute`,
`execute_batch`, `manage_connections`, `read_artifact`, `workbench`) with
`readOnlyHint` / `destructiveHint` / `openWorldHint` annotations.
- One instruction in its own tool descriptions worth quoting: "awaiting_approval
requires a human/operator; **never approve your own action**."
## Recommendation: adopt the patterns, not the process
Adopting it as Codewhale's default would make a second HTTP service the authority
for credentials and tools, which collides with the rule that the Engine is the
sole authority for tools, permissions, receipts and persistence — and adds a
Python runtime to a product shipping as one binary. That trade is not worth it.
But it is the best available reference for exactly the parts of our MCP layer
that are weakest today, and several of its decisions are directly borrowable:
- **Large tool results as artifacts, never auto-stuffed into context.** We route
large output already; the artifact + JSON-pointer paging contract is a better
version of it and would help the context issues.
- **Approval gating keyed on an immutable intent fingerprint.** A stronger
receipt than approving a tool call by name.
- **Session-scoped allowlists, call budgets, revocation, read-only mode.** A
coherent shape for per-session tool permission that we currently spread across
approval modes.
- **Protocol negotiation against a named set of versions** — directly relevant
to #6131 (one negotiated protocol adapter).
- **One catalog, serialized per vendor schema.** Provider-neutral by
construction, which is the standing direction.
- **Explicit "uncertain write" outcomes** instead of assuming a timeout means
failure.
## The second question: connector auth belongs to the account
The founder's point, and it is the right one: the same connectors should follow
the person across web, desktop and CLI, the way they do elsewhere.
Codewhale puts MCP configuration and credentials on the local machine, so the
same person re-authenticates per device and per surface. That is the wrong
authority for an account-scoped fact.
What that implies:
- **MCP credentials and connector authorization become account state** on the
control plane, which `TRANSITION.md` already names as the sole account
authority. The local Engine does not hold provider secrets; it asks for a
usable authorization and uses it.
- The local Engine still owns *which* servers are enabled for a workspace, and
still performs the connection, because that is execution and it stays local.
- The credential half must not become a second config source: one authority per
fact, with the control plane holding the account-scoped half only.
- This interacts with #6192 (a durable mailbox between tasks) and #6168/#6179
(app-server credential and instructions surfaces) — a shared custody model
makes those routes thinner, not thicker.
## What is not established
Nobody has reviewed ShannonLink's security posture, and its own README disclaims
exactly that. No decision is proposed here about whether the control plane
*implements* this custody itself or wraps an existing service; that choice needs
the founder, and it needs the same review any credential store gets.
Contributor guide
Research direction
Read TRANSITION.md and ShannonLink's README, then compare the proposed account-scoped credential boundary with the Engine's tool authority and the related issues #6131, #6192, #6168, and #6179. Done means documenting whether to adopt the reference patterns, which authorization facts belong on the control plane, and what remains local; the payload says founder and security review are still required.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- authentication, backend-api-design, cli, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100