Capsid
Provides tools for reading and writing files, creating branches, and opening pull requests on GitHub repositories, using a dedicated GitHub App for authentication and access.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Capsidsearch for documents about deployment"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Capsid
Capsid is a control plane for AI agents working across a portfolio of repositories. It stores structured memory, issues scoped credentials with an audit trail over every write, runs a signed work queue that hands a task from a chat to a machine, and optionally runs a self-improvement loop scored against hidden tests.
It is a single-user Cloudflare Worker. It speaks MCP over Streamable HTTP and exposes 32 tools in five groups: documents, repo access, maintenance, the work queue, and self-improvement. It also serves Resources (every document at capsid://<namespace>/<path>) and Prompts (templates stored as documents).
Every write snapshots the prior version into document_versions and appends to audit_log.
Stack
Cloudflare Worker (TypeScript), stateless MCP via
createMcpHandlerfrom the Agents SDKworkers-oauth-provider wrapping the handler: OAuth 2.1 with PKCE, dynamic client registration, tokens in KV
A GitHub OAuth App for login, locked to one admin account
A separate GitHub App for repo access, minting short-lived installation tokens
D1 for documents, versions, namespaces, jobs, agents and the audit log, with FTS5 search
R2:
MEDIAfor backups, the markdown mirror and CSP reports (the binding name is historical; nothing stores or serves media, and the Worker never reads this bucket back);HOLDOUTfor the loop's hidden test suites, bound separately so attempt code cannot reach itKV, two separate namespaces:
APP_KVfor the Worker's caches,OAUTH_KVfor the provider's clients, grants and tokens. They must not be the same namespace (see Clone setup)
Related MCP server: MCP Knowledge Server
How it works
Memory. Documents are typed (
core,concept,decision,task,episodic,procedural,prompt,sourceand more), stored in D1 with FTS5 search, and grouped into namespaces that map to GitHub repos.writevalidates the type, so an off-schema document cannot escape the consolidation loop. Full model: docs/schema.md.Agents. Every caller resolves to an agent with its own key, scopes and audit identity, through one enforcement point. Scopes are five axes, and the blast-radius flags (merge, direct write, dispatch, workflows, protected paths, money paths, commenting on a pull request) are held one at a time by separate roles.
Repo access. A dedicated GitHub App mints short-lived installation tokens. The Worker reads and writes mapped repositories with no long-lived credential stored. The namespace mapping is the authorization boundary.
The work queue. A job hands a task from a chat that has no shell to a session that has no conversation. Bodies are signed, claims take a four-hour lease, and a job reaching a push, a deploy or a merge blocks with the exact command a human runs.
The self-improvement loop. An optional nightly loop proposes one scoped change at a time, has each repo's own CI score it against hidden tests, and opens a pull request only for changes that improved the repo without regressing an anchor. Off by default, and it never merges.
The console. One admin page at
/consoleshowing every namespace: pauses, job counts, the command each blocked job waits on, the agent inventory and recent activity. It renders what the tools already compute.Backups. A daily cron exports every table to R2 as JSON plus a markdown mirror of every document body.
DrDustinEdwards/capsid-backupsmirrors the dumps off-account; this repo mints that job's credential and sets no schedule for it. Restore is documented and rehearsed weekly against a scratch database.Audit trail. Every write snapshots the prior version into
document_versionsand appends toaudit_log. Every destructive document write asks for confirmation first.
Documentation
docs/auth.md the agent model, the five scope axes, the roles, and the two gated endpoints
docs/repo-access.md how the GitHub App token flow works and which tools read and write repos
docs/work-queue.md the job lifecycle, signing, leases, gates, evidence and agent records
docs/autonomy.md auto-merge, pre-approved gate classes, the nightly driver and the watcher
docs/improve.md the self-improvement loop: how it runs, and what stops it moving its own goalposts
docs/skills.md how an idea abstracted from work that landed is offered to other projects
docs/console.md what the admin page shows, who gets in, and what it cannot do
docs/consolidation.md the wiki maintenance loop, and the confirmation step on destructive writes
docs/backups.md what the daily dump contains, and three restore paths in the order to try them
docs/rollback.md serving the previous Worker version when a deploy shipped a bad one
docs/schema.md the knowledge model, the document types and the tables
docs/bootstrap.md minting agents and removing the operator key
Endpoints
POST /mcpMCP over Streamable HTTP, requires an OAuth access token (admin only)POST /ops/mcpMCP over Streamable HTTP for agents and cron, requires an agent or operator key asAuthorization: Bearer <key>POST /ops/backupruns a backup on demand, requires a write-grant key, returns a JSON summaryGET /authorize,POST /authorize,GET /callbackGitHub OAuth flowGET /console,POST /console,GET /console.json,GET /console/callbackthe admin console, its actions and its JSON twin. Admin session only; a bearer token is refused with 403POST /csp-reportno auth. Content-Security-Policy and COOP violation reports, per-IP rate limitedPOST /improve/scorethe signed score report a roster repo's CI posts backPOST /improve/holdout-credentialmints the one-hour, object-read-only credential the score job reads the holdout suite withPOST /backup/credentialmints the credential the off-account backup writes withPOST /token,POST /registertoken exchange and dynamic client registration (served by the library)GET /.well-known/oauth-authorization-serverandGET /.well-known/oauth-protected-resourcediscovery metadata (served by the library)GET /healthno auth. Reports deploy provenance (git sha, whether the tree was dirty, build time) and probes the store:SELECT 1against D1 plus an FTS5 MATCH pinned to one known document. Either probe failing returns 503 withstatus: "degraded"and astoreobject naming which one. A Worker whose bindings resolved to nothing starts normally and would otherwise answerokwhile every read tool errors.
Clone setup
Install dependencies:
npm installCreate your own Cloudflare resources:
npx wrangler d1 create capsid npx wrangler kv namespace create APP_KV npx wrangler kv namespace create OAUTH_KV npx wrangler r2 bucket create capsid-media npx wrangler r2 bucket create capsid-improve-holdout # only if you run the self-improvement loopCopy the config template and fill in your IDs from step 2.
APP_KVandOAUTH_KVmust be different namespace ids.cp wrangler.jsonc.example wrangler.jsoncThe real
wrangler.jsoncis gitignored. Never commit it.Apply the migrations (idempotent,
IF NOT EXISTSeverywhere):npx wrangler d1 migrations apply capsid --remoteGenerate an operator key and store its sha256 hash as a secret. Keep the raw key safe; headless clients send it as the bearer token on
/ops/mcp:npx wrangler secret put OPERATOR_KEY_HASHThe value is one or more comma-separated lowercase hex sha256 hashes. Prefix an entry with
ro:to make that key read-only, for example<full-key-hash>,ro:<agent-key-hash>. Never store a raw key in the repo. Once agents are minted (docs/bootstrap.md), remove the operator hash.Create a GitHub OAuth App (for login) at https://github.com/settings/developers:
Homepage URL:
https://capsid.<your-subdomain>.workers.devAuthorization callback URLs, both of them, spelled exactly:
https://capsid.<your-subdomain>.workers.dev/callbackfor the MCP flow andhttps://capsid.<your-subdomain>.workers.dev/console/callbackfor the console. Wildcard matching should be off: each redirect is granted for the exact URI it was issued against.
Then set the secrets:
npx wrangler secret put GITHUB_CLIENT_ID npx wrangler secret put GITHUB_CLIENT_SECRET npx wrangler secret put COOKIE_ENCRYPTION_KEY # openssl rand -hex 32 npx wrangler secret put ADMIN_GITHUB_LOGIN # your GitHub username, or your numeric GitHub user idFor repo access, create a GitHub App, separate from the OAuth App. Permissions: Repository contents read and write, Pull requests read and write, Metadata read, Actions read and write, Workflows write (confirmed by probe 2026-09-07: a pull request authoring a workflow file succeeded, and was closed immediately; that probe proves write and says nothing about read, so read is not claimed here). The last two are what let the Worker dispatch a workflow and write under
.github/workflows/; both are gated behind agent flags (can_dispatchandcan_write_workflows), so the App holding the permission does not mean a caller can use it. Install it on the repositories you want reachable. Note its Client ID, generate a private key (.pem), then:# put the App client id in wrangler.jsonc vars as GITHUB_APP_CLIENT_ID npx wrangler secret put GITHUB_APP_PRIVATE_KEY # paste the .pem contentsOnly the private key mints installation tokens; the App client secret is not needed. The installation id is not configured: it resolves from GitHub per owner and repo and is cached for a day, because one pinned id cannot be correct for two owners.
Optional, only for the self-improvement loop:
IMPROVE_SCORE_SECRET(the root of the per-repo score-report keys) and, forapimode,ANTHROPIC_API_KEY. The loop stays off untilimprove_modeis set.npx wrangler secret put IMPROVE_SCORE_SECRET npx wrangler secret put ANTHROPIC_API_KEY # api mode onlyType check and deploy:
npm run check npm run deployConnect claude.ai: Settings, Connectors, Add custom connector, URL
https://capsid.<your-subdomain>.workers.dev/mcp. The connector registers itself and walks you through the GitHub login. Only theADMIN_GITHUB_LOGINaccount gets in.Or test the flow first with the MCP Inspector:
npx @modelcontextprotocol/inspectorSet transport to Streamable HTTP, URL to
https://capsid.<your-subdomain>.workers.dev/mcp, open the Auth tab, and run Quick OAuth Flow.
MCP clients cache the tool list at connect time. After deploying new tools, reconnect the connector or start a new chat to see them.
What's next
The experiment scheduler, once the loop has real nights behind it. Nothing else is planned.
Switches
Three switches, all off by default. Each is turned on separately.
The loop runs only when improve_mode in APP_KV is set to subscription or api, by improve_run action mode. Anything unreadable or unexpected falls back to off.
Auto-merge and pre-approved gates run only when their policy document's enabled field is true and the document has been signed again afterwards with improve_run action sign_policy, which is admin only. Editing without re-signing leaves the policy authorizing nothing.
The nightly driver exists only after node scripts/schedule-drivers.mjs --install --namespace <ns> --apply. The task it creates is disabled until it is enabled by hand.
Security
Independent audits of this surface produced these fixes, now in the code: path traversal closed on every document path, OAuth consent bound to the exact redirect it was granted for, the scorer isolated so attempt code never runs beside a credential, protected paths enforced by a deterministic guard, an Origin allowlist on the browser-facing routes, and a replay cache keyed by a database primary key rather than a read-then-write. Each fix ships with a test observed failing against the code it replaced. The audits live in Capsid, not in this repository.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Cloudflare Workers MCP server: agent-memory
Cloudflare Workers MCP server: agent-workflow-engine
Cloudflare Workers MCP server: api-landing
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables AI agents to search, read, and contribute to a structured markdown knowledge base with citations, freshness tracking, and a safe write path, providing a shared, auditable company memory.5 npmMIT
- FlicenseNot gradedqualityBmaintenanceA remote MCP server that indexes Markdown knowledge from GitHub into Cloudflare KV, enabling AI assistants to perform fast keyword searches and retrieve documents with low latency.1-
- FlicenseNot gradedqualityCmaintenanceA Cloudflare Workers-based MCP server for Notion knowledge base management, enabling intelligent search, automatic recording of code snippets, and statistics analysis through natural language.-
- AlicenseNot gradedqualityCmaintenanceMCP server for a personal knowledge graph running on Cloudflare, enabling note-taking, task management, and cross-domain recall via Claude.MIT