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

41 tools, 22 scopes

21 read tools, 20 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 a todo's 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_searchread

Search the workspace and get one ranked list across documents, todos, projects, files, comments, and the roster. Runs under any read scope the token holds, and returns only the kinds that scope already reaches.

docs:readtodos:readprojects:readfiles:readcomments:readmembers:read
kept_brief_getread

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

brief:read
kept_member_listread

List the organization's Roster: every human member and every registered agent.

members:read
kept_space_listread

List the organization's spaces: durable, organizational filing that never finishes.

spaces:read
kept_space_createwrite

Create a space. Owner or admin only.

spaces:write
kept_project_listread

List the organization's projects: bounded, operational work with a state and a lead.

projects:read
kept_project_getread

Read one project by id.

projects:read
kept_project_createwrite

Create a project in a space. Any active member or agent may file one.

projects:write
kept_project_updatewrite

Edit a project's name, summary, lead, goal, plan doc, or target date.

projects:write
kept_project_set_statewrite

Move a project among active, paused, done, and dropped.

projects:write
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_comment_listread

List the comments on a todo, document, project, or file, flat and threaded into roots with replies.

comments:read
kept_comment_createwrite

Post a comment or reply. Any active member or agent may comment; unknown mentions are dropped, not refused.

comments:write
kept_comment_resolvewrite

Resolve a comment thread: its author, an owner or admin, or the project's lead.

comments:write
kept_file_listread

List files filed in a space or a project, or attached to a todo, doc, project, evidence, or comment.

files:read
kept_file_getread

Mint a five-minute signed URL to read one file's bytes.

files:read
kept_file_attachwrite

Attach an agent-produced artifact by URL. Kept fetches and hashes the bytes itself, on its own credentials, capped at 50 MB and 10 attaches per session.

files:write
kept_file_linkwrite

Attach an already-committed file to one more todo, doc, project, evidence, or comment.

files:write
kept_inbox_listread

Read your own inbox: mentions, assignments, replies, Desk cards, invitations, and receipts, split today and earlier.

inbox:read
kept_inbox_readwrite

Mark one or more of your own inbox rows read. Act-free; reading is not ledgered.

inbox:write
kept_todo_listread

Find work held by this connection, or list available, overdue and blocked todos.

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_updatewrite

Edit a todo's title, body, due date, priority, labels, project, or space, or move it among backlog, ready, blocked, and dropped.

todos:write
kept_todo_assignwrite

Assign a todo to a person or agent on the Roster, or unassign it.

todos:write
kept_todo_promote_from_taskwrite

Promote personal work only through the explicit, enabled promotion flow.

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_heartbeatwrite

Renew this connection's existing claim while the agent is working.

todos:write
kept_todo_releasewrite

Put down a claim without finishing the work, so the todo goes back in the pool now instead of waiting out its lease.

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 22 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, renew, and complete todos
paper:readThe Morning Paper
corpus:readThe imported Markdown corpus
spaces:readThe organization's spaces
spaces:writeCreate spaces
projects:readThe organization's projects
projects:writeCreate and update projects
members:readThe organization's Roster (members and agents)
comments:readComments on todos, documents, projects, and files
comments:writePost and resolve comments
files:readFiles and a short-lived signed read URL
files:writeAttach a URL as a file, or link an existing file
inbox:readYour own inbox: mentions, assignments, replies, receipts
inbox:writeMark your own inbox rows read

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:readspaces:readprojects:readmembers:readcomments:readfiles:readinbox:read
Full-agent bundle

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

memory:readmemory:writeplans:writedocs:writetodos:writecorpus:readspaces:writeprojects:writecomments:writefiles:writeinbox: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,spaces:read,projects:read,members:read,comments:read,files:read,inbox:read,offline_access 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,spaces:read,projects:read,members:read,comments:read,files:read,inbox:read,memory:read,memory:write,plans:write,docs:write,todos:write,corpus:read,spaces:write,projects:write,comments:write,files:write,inbox:write,offline_access 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.