Kept Workplace · for agents

Connect your agents to Kept Workplace.

One MCP server your team’s agents write into: Claude Code, Codex, and anything else that speaks MCP. A person approves the connection and the exact access it gets. Nothing reaches done without proof, checked by Kept, not narrated by the agent.

OAuth 2.1 + PKCE, or a labeled PATScoped & revocablehttps://mcp.enterprise.kept.do/mcp
What an agent gets

Eighteen tools, eleven scopes

12 read tools, 6 write tools. Every call is scope-checked at dispatch, rate-limited, and written to the Ledger. There is no delete tool and no tool that sets state directly · the evidence gate below is the only door to done.

searchread

Search documents, plans, todos, the Brief, and attention items for ChatGPT and other read clients.

brief:readplans:readdocs:readtodos:readpaper:read
fetchread

Fetch one search result by stable id with complete text and a user-openable source URL.

brief:readplans:readdocs:readtodos:readpaper:read
kept_brief_getread

Read the org's Sealed Brief, the standing context Kept keeps, at session start.

brief:read
kept_memory_rememberwrite

Write one durable statement into organization memory, with provenance. Lands quarantined until a human promotes it.

memory:write
kept_memory_recallread

Retrieve promoted, ambient-truth memory, before answering from your own recollection.

memory:read
kept_memory_investigateread

Escalate into unpromoted, unconfirmed memory once recall has abstained. Ledgered and billed to the org's meter.

memory:read
kept_plan_createwrite

Create a plan and file its todos in one call, so the writing and the work never drift apart.

plans:writetodos:write
kept_plan_getread

Read a plan: its sections, and the live state of every todo filed under each one.

plans:readtodos:read
kept_doc_getread

Read one exact document revision, with every block's identity and revision addressable.

docs:read
kept_doc_apply_opswrite

Apply block-addressed edits against an exact base revision. Rebase is tried first; conflicts come back with full context.

docs:write
kept_doc_blameread

See who last changed each block, when, and under what intent, without scanning history.

docs:read
kept_todo_listread

List todos with derived status: overdue, blocked, ready to claim.

todos:read
kept_todo_createwrite

File one todo. Kept fixes its evidence class from the work it describes; a weaker request is ignored.

todos:write
kept_todo_claimwrite

Claim a todo on a lease before working it, so two sessions never double-work the same row.

todos:write
kept_todo_complete_with_evidencewrite

The only door to done. Submit receipts; Kept fetches every ref on its own credentials and computes its own hashes.

todos:write
kept_paper_getread

Read the Morning Paper: orphaned work, decisions waiting, what ran overnight. No model in its path.

paper:read
kept_corpus_listread

List the organization's imported document corpus before asking a person something it already wrote down.

corpus:read
kept_corpus_getread

Read one imported document, whole or one block subtree deep.

corpus:read

The eleven scopes

brief:readThe Sealed Brief
memory:readPromoted organization memory
memory:writeNew memory writes, always quarantined
plans:readPlans and their sections
plans:writeCreate plans and their todos
docs:readDocument revisions and block blame
docs:writeBlock-addressed document edits
todos:readTodo state and lists
todos:writeCreate, claim, and complete todos
paper:readThe Morning Paper
corpus:readThe imported Markdown corpus

memory:write is deliberately left off both default bundles below: every memory write lands quarantined no matter who wrote it, so granting the scope by default would not do anything for you · it would just make the consent screen longer.

Read-only bundle

What a cold session needs to orient itself. Nothing here can change a row.

brief:readplans:readdocs:readtodos:readpaper:read
Full-agent bundle

Read-only, plus the write scopes: plan, file and claim todos, and edit documents.

memory:writeplans:writedocs:writetodos:write
Two lanes in

However your agent authenticates

Lane 1 · recommendedOAuth 2.1, with dynamic client registration

The agent registers itself, then a person approves it in a browser. No pre-shared credential ever touches a config file.

  • PKCE (S256), refresh-token rotation, and reuse detection on every grant.
  • The consent screen names the client, its callback host, and the exact scopes requested.
  • Bound to an active organization membership and its human Roster principal, never to a model-supplied identity.
  • Verified end to end against Codex CLI on 2026-08-16, including DCR, PKCE, refresh rotation, and revocation.
Lane 2 · the labeled PATA personal access token, minted by an owner

Shaped kept_ent_<random>. Minted locally by a human operator, never by an agent, for principals that need a static credential (a scripted job, a CI runner).

  • The plaintext prints exactly once, to the operator's terminal. Kept stores only its sha256.
  • Every token carries a label and a scope list chosen at mint time, full, read, or a custom comma list.
  • Lost it? Mint another and revoke the old one. That is the rotation path working, not a recovery gap.
  • Adding a new scope later does not widen an existing token. It reads the scopes it was minted with until reminted.

Minting a PAT is an operator action, run locally, never by an agent:

pnpm --filter kept-enterprise-mcp mint -- \
  --org <org-uuid> --principal <principal-uuid> \
  --label "claude-code laptop" --scopes full --days 90
Connect your agent

Exact commands, by client

The server is https://mcp.enterprise.kept.do/mcp for all of them.

Fast path: paste one sentence to your agent, then approve its bounded read grant in the browser.

Fetch https://kept.do/workplace/agent-setup/prompt.md and follow its instructions to connect Kept Workplace to this agent over MCP.

Open the one-paste setup page for a human-readable copy of the same instructions.

Claude (claude.ai and Desktop)

Settings → Connectors → Add custom connector. Paste the server URL, leave the OAuth Client ID and Client Secret fields empty, then Add and Connect.

https://mcp.enterprise.kept.do/mcp

The empty credential fields are correct, not an omission. Kept registers Claude automatically and accepts public clients only, so a pasted secret is refused. One connector covers claude.ai, Claude Desktop, and mobile.

Claude opens Kept’s sign-in page. Sign in with a Workplace account holding an active seat, pick the organization if you hold seats in more than one, then read the consent screen: it names the client, the hostname its callback returns to, the organization, and every scope in plain words, and it carries the disclosure Kept supplies standing context (the Imperative Brief) to this agent. with a link to read the current Brief before you approve.

A Claude connector is read-only unless you widen it. Kept asks for the read-only bundle and nothing else. Writing, filing, and claiming work require the organization to grant the write scopes deliberately.

On Team or Enterprise, an Owner can add it once for everyone at https://claude.ai/admin-settings/connectors(Add → Custom → type Web, same URL); members then connect from their own https://claude.ai/customize/connectors.

Verified: discovery and OAuth shape.Every document Claude looks for answers, the unauthenticated refusal carries the exact challenge Anthropic documents, Claude’s callback registers, and the full sign-in, consent, token, and refresh flow completes against this server. Not yet verified: a real connection made from inside claude.ai.

Claude Code

claude mcp add --transport http kept-workplace https://mcp.enterprise.kept.do/mcp

Then, inside the session, sign in:

/mcp

A browser opens for OAuth. Approve the scopes shown, then Claude Code can call Kept Workplace tools for the rest of the session.

Codex

codex mcp add --url https://mcp.enterprise.kept.do/mcp kept_workplace

Read-only login, enough for a session to orient:

codex mcp login --scopes brief:read,plans:read,docs:read,todos:read,paper:read kept_workplace

Or, for an agent that also files and claims work:

codex mcp login --scopes brief:read,plans:read,docs:read,todos:read,paper:read,memory:write,plans:write,docs:write,todos:write kept_workplace

Verified end to end against Codex CLI 0.147.0-alpha.6.5 on 2026-08-16: dynamic registration, the consent page, and a bounded read-only tool call all completed.

Cursor

In .cursor/mcp.json (or global ~/.cursor/mcp.json), add under "mcpServers":

"kept-workplace": { "url": "https://mcp.enterprise.kept.do/mcp" }

Not yet verified against Kept Workplace. This is the standard MCP config shape; Kept has not run an end-to-end connection test with Cursor against this server.

ChatGPT

Documented, not yet verified end to end.In ChatGPT, open Settings → Apps → Advanced settings, enable Developer mode, then create an app with the server URL below. Kept supports OAuth dynamic client registration and PKCE S256. It registers ChatGPT as a public client with token_endpoint_auth_method: none and accepts the callback below.

https://mcp.enterprise.kept.do/mcp

ChatGPT OAuth callback:

https://chatgpt.com/connector_platform_oauth_redirect

The connector discovers two read tools: search returns stable ids, titles, snippets, and source URLs. fetch accepts one returned id and returns complete text with the same source URL. Optional Apps SDK metadata is not required for this read connector.

The refusal is the product

Nothing reaches done without proof

kept_todo_complete_with_evidence is the only door to done. Kept fetches every reference on its own credentials and computes its own hashes. Narrative is stored as activity, but it is never evidence, and it never closes a box.

A submission that does not hold up bounces back to the agent rather than closing. Every rejected item carries the same four fields, so a bounce is something an agent can repair, not a dead end:

admissibletrue or false. The one bit that decides whether the todo closes.
ruleWhich admissibility rule made the call, by name.
reasonWhy this specific submission failed that rule.
repairWhat the agent can actually do about it. Never "try again."

The lease stays open when a submission bounces, so the same agent can read the repair and try again with a better receipt · it is not locked out by its own failed attempt.

What every connection discloses

The consent screen shows this line, word for word, before anyone approves a connection:

Kept supplies standing context (the Imperative Brief) to this agent.

It links to a fenced preview of the current Brief, so the person approving can read exactly what the agent is about to receive before they click approve.

What we do not have yet, said plainly
  • SSO
  • Scope-level step-up after connecting (a client asks once, for everything it wants)
  • claude.ai custom connectors, ChatGPT, and Cursor connected end to end by a person. The server meets every published requirement for all three, and for claude.ai the discovery documents, the refusal challenge, dynamic registration, consent, and token refresh are all proven against this server. Only Claude Code and Codex have actually been driven against it by this fleet.

Questions before you connect an agent? jessie@kept.do.