MCP Integration
Point Claude Code, Cursor, Claude Desktop, or any MCP-compatible client at your CoachKeeper workspace.
What this is
CoachKeeper exposes its full agent toolset over the Model Context Protocol (MCP) — the open standard that AI clients use to talk to external tools. Any MCP-compatible client can read, search, create, update, and schedule against your workspace as if it were the built-in coach.
Same rules apply on both sides:
- Same authentication boundary — OAuth sign-in with your CoachKeeper account, never a pasted secret
- Same action log — every create / update / delete lands in the shared action log the in-app coach uses
- Same undo — every action taken over MCP is undoable from its line on Today or in the action log, and an undo never overwrites an edit you made after the agent
- Same availability windows respected when scheduling
Why you’d use it
- You already live in Cursor or Claude Code. Let the editor turn a TODO comment into a real todo in your backlog without leaving the IDE.
- You use Claude Desktop every day. Ask it to schedule your week using your CoachKeeper backlog and availability — without copy-pasting.
- You’re building your own agent. Treat CoachKeeper as a managed PKM service it can call.
Connect a client
There is nothing to mint, copy, or paste. CoachKeeper implements the MCP authorization spec (OAuth 2.1): you give your client the server URL, and the first time it connects your browser opens a CoachKeeper consent screen. Sign in (if you aren’t already), click Authorize, and you’re done — the client refreshes its own access from then on. This is the same flow GitHub, Linear, Notion, and Sentry use for their MCP servers.
Claude Code (CLI)
claude mcp add --transport http coachkeeper https://api.coachkeeper.com/api/v1/mcp
Confirm with claude mcp list. On first use it will open your browser to authorize.
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"coachkeeper": {
"type": "http",
"url": "https://api.coachkeeper.com/api/v1/mcp"
}
}
}
Restart Claude Desktop. Look for the 🔌 icon in the input bar — it should list coachkeeper and prompt you to authenticate.
Cursor
Settings → MCP → Add new MCP server, paste the same JSON snippet.
Anything else that speaks MCP
Same JSON shape. Two things matter: type: "http" and the URL. No headers — the client discovers the OAuth endpoints automatically and walks you through consent. The client does need to support MCP OAuth: harnesses whose MCP client only takes static headers (DeepSeek Harness at time of writing, for example) can’t sign in yet.
Teach your agent
Connecting gives your agent the tools; teaching it the house style makes it good with them. Settings → AI Tools (MCP) includes a short copyable briefing — the entities and how they relate, how to search cheaply before listing everything, how notes and todos are formatted, and what to confirm with you before changing things.
- Claude Code: download it as
SKILL.mdand save it under~/.claude/skills/coachkeeper/— it loads automatically whenever you work with CoachKeeper. You only do this once: when the skill changes, your agent notices its copy is out of date and asks to update it for you. - Claude Desktop / ChatGPT / Cursor and others: paste it into the agent’s custom or project instructions.
The server already sends a compact version of this briefing to every client when it connects, and it also serves the full briefing over MCP itself — as the skill prompt (a slash command in Claude Desktop) and as the resource coachkeeper://skill. A client that shows prompts can load it in one click, no pasting; installing the SKILL.md file is still worth it if you pair one agent with CoachKeeper regularly, so it is there before the first tool call.
Connection status at a glance
Once a client is connected, a small plug/agent icon in the app’s top bar turns into a status badge — amber when idle, briefly green whenever the agent makes a change. A small number on its corner counts what waits on you: a task the agent asked about, a finished task to review, or a note changed in two places while you were offline. Click the icon to see that list and the connection, with Settings one click away. Before you’ve connected anything, the chat panel also shows a one-time “bring your own agent” card pointing at the same setup flow.
Managing access
Settings → AI Tools (MCP) lists every client currently connected to your account, with when it connected and when it was last used. Revoke cuts a client off immediately — it would have to go through browser consent again to reconnect.
Under the hood, each authorization issues a short-lived access token plus a rotating refresh token. A connection that goes unused for more than 7 days expires on its own; active clients renew silently and stay connected indefinitely.
Choose what each agent can see
You may not want every agent reading everything — a coding agent has no business in your journal. Each agent can have its own rules, on tags and notebooks:
- Read or Read & write on some tags or notebooks limits the agent to them (child tags included). It changes only what is under Read & write.
- Hide keeps a tag or notebook away from it, and wins over everything else — “everything except my journal”.
- No rules (— everywhere) means full access, as before.
What is outside an agent’s rules does not exist for it: it can’t find it in search, lists, the workspace overview or the chat’s background reading, and a write there is refused. Set the rules on the consent screen when you authorize a new agent (Limit what … can see, optional), or later in Settings → Agent Settings → What each agent can see, which lists the in-app chat and every agent you connected.
One memory for every agent
Each assistant keeps its own memory of you, and none of it travels. CoachKeeper keeps one About me text instead. It lives in Settings → Agent Settings → About me: write it yourself, in plain text, and save. Every connected agent reads it first and adds what it learns there. Each change an agent makes is signed with its name and shows up on Today, where Undo takes it back.
Import memory from another assistant takes the memory Claude or ChatGPT keeps about you (paste it there) and hands it to your own connected agent as a task. The agent proposes additions to About me as a run you review — Discard takes them back out. Every agent can read and add to About me, whatever you allow it to see.
A second agent starts where the first stopped. A connected agent can ask for the hand-off (get_handoff): what other agents changed and asked since it was last here, the questions waiting on you, and what you edited yourself.
What the AI client can do
The server exposes the same tools the in-app coach uses, minus four that are app-specific: undo_last_action, request_include_context, request_approval (your own agent runs its own approval flow), and web_search. At time of writing:
| Domain | Tools |
|---|---|
| Notes | list_notes, get_note, create_note, update_note, delete_note, summarize_note, rewrite_note, graft_notes (merge two notes that say the same thing — one undo takes it back; an evergreen note can’t be merged away) |
| History and links | get_note_history (a note’s earlier versions and who replaced each), get_backlinks (what links to an item), get_related (items like it) |
| Saved links | list_links, save_link, update_link, delete_link |
| Trash | list_trash, restore_item |
| Hand-off and garden | get_handoff (what changed since this agent last looked), lint_garden (duplicates, broken links, unfiled items, stale About me lines, overlapping tags — as proposals), set_recall_prompt (write the recall question Today asks about a note) |
| About me | add_to_about_me (add a line), set_about_me (rewrite the text, when you ask) — the text itself comes with get_workspace_overview |
| Saved searches | list_saved_searches, run_saved_search |
| Notebooks | list_notebooks, get_notebook (table of contents, or the whole book as markdown), create_notebook, update_notebook, delete_notebook |
| Todos | list_todos, get_todo, create_todo, update_todo, delete_todo, complete_recurring_todo |
| Agent runs | list_agent_tasks, claim_todo, report_run, accept_run, revise_run, discard_run, evidence_upload, settle_git |
| Events | list_events, get_event, create_event, update_event, delete_event |
| Sources | list_sources, get_source_content, search_sources (RAG) |
| Search | search_items (cross-entity by title or content, with the same search filters as the app — tag:, is:todo, before:…), semantic_search (meaning-based, not just keyword matches) |
| Tags | list_tags (every tag with live item counts), get_tag_dossier (a tag’s map: a mermaid concept sketch of what’s filed under it plus short state notes, each pointing at real item ids — the same map the Library page shows, including any arrangement you made by hand, which a client is told not to redraw), update_tag (rename, recolor or describe a tag — a rename reaches every item under it), merge_tags (fold one tag into another), delete_tag (items are kept and lose the tag; a tag that still has items is refused until the client confirms with untag_items) |
| Orientation | get_workspace_overview (a snapshot of your workspace — counts, recent activity — for a client to get its bearings before diving in) |
| Scheduling | get_availability |
Notes, todos, and sources read back as properly formatted markdown, not raw JSON blobs. Their list tools (list_notes, list_todos, list_sources) are paginated and filterable — by status, tag, notebook, due window, or title — instead of a flat cap on how many rows come back, so a client can page through a large workspace without missing items. Notes can be tagged the same way todos and events already could.
A todo carries two independent dates, and the tools keep them apart: due_date is the deadline, scheduled_start / scheduled_end is the time blocked out to do the work — which is what your calendar shows. Blocking time means scheduling the todo itself; an agent should never create an event to stand in for a task. list_todos filters on either (due_before / due_after, scheduled_from / scheduled_to) and takes unscheduled: true to find work that still needs a slot.
Two writing conventions worth teaching your agent: a fenced ```mermaid code block in any note renders as a live diagram in the app, and rich material for a todo — briefs, research, diagrams — belongs in a note linked via context_note_ids, which is what the todo page displays.
Notes are richer than plain markdown, and agents write the same forms you do: ==marker==, callouts (> [!note] Title), ::: columns and ::: margin blocks, $math$, ```html live blocks,  to show a file open in the page. A note can also wear a page frame — update_note(frame="folio") — and list_frames, get_frame and save_frame let an agent read the designs and make new ones. The full contract is in the repository’s docs/note-dialect.md.
Each tool returns the same shape as a normal API call and produces the same action log entry. To see the live, authoritative list, call MCP’s standard tools/list from your client.
Tend the garden
Ask a connected agent to lint your garden, or use its Tend the garden prompt (lint_garden). It finds duplicates, broken links, notes and tasks filed nowhere, out-of-date lines in About me, and overlapping tags, and proposes one fix for each. It changes only what you approve, through the normal tools — so every change lands on Today with Undo. A scoped agent lints only what it can see.
Work your agent tasks
Tasks you hand over on the board (the Agent column — see Hand a task to your agent) are worked from your own agent, when you say so. The server ships three prompts for it — slash commands in Claude Code (/mcp__coachkeeper__<name>) and prompts in Claude Desktop:
agent_tasks— My agent tasks: lists what needs you, what’s queued, what’s running and what’s waiting for your review, and lets you choose: work one, work up to three, answer a question, accept, revise or discard. With the CoachKeeper skill installed in Claude Code,/coachkeeperdoes the same.work_task— work one task, by id or title.work_queue— work through the queue, oldest first, up to three.
Each task is worked as a run: the agent claims it (claim_todo — so two agents never take the same task), works, and reports (report_run — done with a summary, or needs input with its questions). Everything it writes in CoachKeeper in between belongs to that run, so the card can show exactly what changed and Discard can undo it as one. accept_run, revise_run and discard_run are your decisions, which the agent relays when you say so — it is told to list what a discard will undo and wait for your yes. There is no chat thread to keep alive — the task is the thread — so a question you answer on Tuesday can be picked up by a different agent session on Thursday.
If a tag has an agent folder (a name, e.g. coachkeeper — never a full path), its tasks carry it, and an agent with file access works only inside it. In a git repository it never touches your open files or your unsaved work, and nothing is ever pushed: each task’s change waits to one side until you decide. When a task needs tests or a build, the agent runs them in a separate copy that it cleans up before it reports. The card shows what changed in plain words, with the technical details folded under Details. A folder missing on the current computer is skipped, so the task waits for the machine that has it. The folder can also hold several repos — a project made of an api and a web repo, say: the agent works in whichever repos the task concerns (asking if it can’t tell). In a folder that isn’t a git repository, the agent writes files directly and tells you first that Discard can’t undo them.
Accept adds it to your project. Discard means it never happened. Your agent carries out the decision the next time it runs on that computer — one line, no questions. If your own changes since get in the way, the task comes back to your review saying why, and Revise has the agent redo it on top. In Claude Code, one permission rule lets these steps run without a prompt each time: Bash(sh .git/ck:*). It never includes pushing.
Evidence. Every report shows before → after — up to three proofs, the strongest first: tests before and after, the key line that changed, or screenshots. Screenshots go from the agent’s shell straight to a short-lived upload link (evidence_upload), never through its context. A run that can’t show proof says why.
Run the queue on a schedule
CoachKeeper never starts an agent by itself; queued tasks wait for a client to come by. If you want that to happen without you, schedule the client. Settings → AI Tools (MCP) → Put the queue on a schedule has the instructions to give it — the server serves the same text as the queue_routine prompt and the resource coachkeeper://queue-routine. They are work_queue made safe for a run nobody is watching:
- It stops at once when the queue is empty, without changing anything — so a frequent schedule costs next to nothing.
- A few tasks per run, oldest first, one at a time. A task an earlier run abandoned mid-way is picked back up after an hour.
- It never asks a question into the void. Anything it can’t decide becomes Agent needs input on the card, with the question written on the task. Answer it on the task or from Today, and the next run resumes where it stopped.
- Every result is a one-pager: a new note linked to the task and filed under its tag — the answer first, then what it found or did, one diagram or table only when the content calls for one, next steps, and sources. The task waits in your Agent column for your review.
Where to schedule it:
- Claude Desktop, on your own computer — Code tab → Routines → New routine → Local. Paste the instructions, choose the folder that holds your projects as the working folder, and pick a schedule. Press Run now once and choose Always allow for each CoachKeeper tool it asks about; later runs then go through without stopping. A local routine only fires while the app is open and the computer is awake — after sleep it catches up with a single run.
- Claude Code — with the server added (
claude mcp add …above), one cron or launchd line run from your projects folder:claude -p "Run the queue_routine prompt from the coachkeeper server". - Claude in the cloud — a cloud routine at claude.ai/code/routines with the CoachKeeper connector runs with your laptop closed, hourly at most. It can research and write; it cannot reach files on your computer.
- ChatGPT — a scheduled task with the CoachKeeper connector and the same instructions. Research and writing only.
- Any other headless agent with an OAuth-capable MCP client works the same way: point it at the server, have it load the
queue_routineprompt, run it on whatever timer you like.
Guardrails still apply: the agent can only do what a person with your account could. What it did while you were away is listed on Today, where each line can be compared or undone.
Things to know
- Streamable HTTP, stateless. No persistent connection — every request carries a short-lived bearer token the client manages for you.
- No per-request rate limiting today. MCP tool calls are exempt from the web rate limiter. Be a good citizen — reasonable limits may be introduced later.
- Legacy static tokens (from before OAuth) keep working until they expire, but you can’t mint new ones. Reconnect via OAuth — it’s less work and it never dies silently.
- Self-hosted CoachKeeper? Same protocol, just point at your own
https://your-host/api/v1/mcp.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Client reports the server is unreachable | Wrong URL — must end in /api/v1/mcp (not /mcp) |
| Browser consent never opens | Your client predates MCP OAuth support — update it |
401 Unauthorized on every call | Connection was revoked or expired from inactivity — reconnect (the client will re-open the consent screen) |
| Tool calls succeed but nothing appears in the app | You authorized while signed in to a different CoachKeeper account — revoke in Settings and reconnect with the right one |
| Client lists no tools | Server reachable but not yet authorized — trigger the auth flow (e.g. /mcp in Claude Code) |
Where the actions show up
Changes made over MCP push to your open CoachKeeper views in real time — a todo created from Cursor appears on your Kanban board instantly, no reload. Each action is also recorded in the same action log the built-in coach uses, so if an external client did something you didn’t want, press Undo on its line on Today — or open the in-app chat and say “undo that”.