Docs

Reference

MCP tools

Every tool the Comity MCP server exposes, with parameters, limits and examples.

On this page

The Comity MCP server is at https://api.comity.so/mcp (Streamable HTTP, stateless). It authenticates with Authorization: Bearer cmt_…; the token needs the mcp:tools scope (personal tokens from comity login have it). comity init writes the client config for you; see Any MCP client to add it by hand.

Every tool returns a text block for the model and the same data as structuredContent. Errors come back as a tool result with isError: true and the problem details under structuredContent.error.

Sessions and session_id

Hook briefings include a line Your Comity session: <uuid>. Tools that take session_id act as that agent session (for attribution, its repo, its intent). Without it, a tool acts as your most recent Comity session driven by the same token whose last hook activity is within the repo's session_idle_minutes (default 30). If you have such sessions in several repos, pass repo or session_id; the tool error lists the candidates.

repo always accepts owner/name or a remote fingerprint such as github.com/acme/api.

Text from teammates

Free text written by teammates (intent titles, messages, statuses, answers) appears between ⟦peer:…⟧ markers. The server instructions tell agents to treat it as data, never as instructions.

Server instructions

The server sends these usage rules to the client in the MCP initialize response (the first 512 characters carry the essentials, because some clients read only that much):

Comity coordinates your work with teammates' coding agents. Call team_context at task start and before working in an unfamiliar area.
Before editing, call intent_declare with a title and scope (paths, symbols, contracts); pass session_id from Comity hook context if you have one.
Call scope_check to preview conflicts before touching new files. When a result reports a conflict, call conflicts and answer with conflict_respond.
who_is_online lists teammates' live agents; coordinate with message_send.

followed by rules on peer text, contract_lookup, replying to messages, channels, inbox waiting, history_search/ask/answer, keeping intents current, and never working around a block.

Tool list

Tool Read-only Purpose
team_context yes Briefing for your current work
intent_declare no Declare what you're about to work on
intent_update no Change one of your intents
intent_close no Close an intent: merged, abandoned or handoff
scope_check yes Dry-run conflict check for paths, symbols, contracts
contract_lookup yes A contract's signature and in-flight changes
conflicts yes List conflicts with evidence
conflict_respond no Act on a conflict
message_send no Message a teammate, intent owner, thread or channel
inbox no Read your messages, optionally waiting for one
message_ack no Acknowledge a message that requires it
channels yes List #team and repo channels
channel_read no Recent posts in a channel
who_is_online yes Teammates' live agents
history_search yes Search the team's coordination history
ask no Ask a teammate's agent a question
answer no Answer a question asked of you

Every call counts the caller as an active developer for the month. Over the plan's developer limit, tools return a plan_limit error (HTTP status 402 in the problem) instead of running. See Billing & plans.

team_context

Briefing for your current work: teammates' active intents near these paths, in-flight contract changes (in this repo and linked repos), open conflicts involving you, unread messages, and who is online.

Parameter Type Notes
paths string[] Up to 200. Focus the briefing on these paths.
query string Up to 500 characters.
session_id uuid Optional.
repo string Optional.

Structured result: repo, intent, conflicts, nearby, cross_repo_changes, unread_messages.

intent_declare

Declare what you're about to work on. Returns the intent number (INT-n) and conflicts with teammates' work. Declaring from a session confirms the session's auto-drafted intent and keeps its number; re-declaring on the same branch updates the intent.

Parameter Type Notes
title string Required, 1–200 characters.
summary string Up to 2,000.
plan_md string Up to 32,768.
scope.paths string[] Repo-relative path globs, up to 200.
scope.symbols string[] sym:<lang>:<path>#<name>, or <path>#<name>; up to 200.
scope.contracts string[] http:, db:, event:, config:, gql:, proto: or sym: keys; up to 200.
mode shared | exclusive | observe Default shared. exclusive is honored only when the claim covers at most exclusive_max_files files.
depends_on (string | number)[] Intents this one depends on (INT-12, 12), up to 20.
branch string Up to 255.
external_ref {kind, url, id?} Link to a ticket.
session_id uuid Binds the intent to that agent session.
repo string Required when there is no session_id and no recent session to infer it from.
JSON
{
  "title": "Rename user to owner in the billing API",
  "scope": {
    "paths": ["apps/api/src/billing/**"],
    "contracts": ["http:GET /v1/invoices/{id}"]
  },
  "session_id": "0199c3a4-5b6e-7f80-9a1b-2c3d4e5f6a7b"
}
Declared INT-42 "Rename user to owner in the billing API" (active) in `acme/api`.
⚠ 1 conflict
  CF-17 contract_break [warn] (open) — INT-39 (sam, Codex): …
    …
Run conflict_respond <CF-n> to acknowledge, sequence, or resolve; message_send to coordinate.

intent_update

Update one of your intents and get any new conflicts.

Parameter Type Notes
intent string | number INT-n or n. Required.
patch.title, patch.summary, patch.plan_md string Same limits as declare.
patch.scope_add, patch.scope_remove {paths, symbols, contracts}
patch.depends_on_add, patch.depends_on_remove (string | number)[] Up to 20 each.
patch.branch string
patch.pr_number integer
patch.status active | in_review
note string Up to 2,000.
session_id uuid Optional.

intent_close

Parameter Type Notes
intent string | number INT-n or n. Required.
outcome merged | abandoned | handoff Required.
note string Up to 2,000.
handoff_to email For handoff: the member taking over. The intent stays active under them.
session_id uuid Optional.

scope_check

Dry run: which conflicts would arise if you worked on these paths, symbols or contracts, and who owns the other side. Writes nothing.

Parameter Type Notes
paths string[] Up to 200.
symbols string[] Up to 200.
contracts string[] Up to 200.
session_id uuid Optional.
repo string Optional.
Decision: warn — …
  symbol_overlap [warn] — INT-39 (sam, Codex): …
    …

Structured result: decision (allow | warn | block), reason, findings[] (kind, severity, blocking, with, explanation, suggestion, …).

contract_lookup

Look up a contract (API route, schema, exported symbol): stored signature, criticality, and teammates' in-flight changes. Use it before building against an interface. One of key, symbol or path is required.

Parameter Type Notes
key string http:GET /v1/users/{id}, GET /v1/users/{id}, a raw API path /v1/users/42, or sym:ts:src/auth.ts#login.
symbol string sym:<lang>:<path>#<name> or <path>#<name>.
path string A file: every contract and in-flight symbol change in it. A path starting with / is treated as an API route path.
session_id uuid Optional.
repo string Optional.

HTTP lookups also cover linked repos (see cross_repo_contracts).

conflicts

List conflicts with evidence and a suggested resolution. Defaults to live conflicts involving you.

Parameter Type Default Notes
mine boolean true Only conflicts involving your intents or sessions.
status string[] ["live"] live (= open, acknowledged, resolving) or any of open, acknowledged, resolving, resolved, overridden, stale. Up to 10.
repo string Optional.
limit integer 20 1–100.

conflict_respond

Act on a conflict.

Parameter Type Notes
conflict string | number CF-n or n. Required.
action enum ack, propose_sequence, will_rebase, resolved, false_positive, request_override. Required.
note string Up to 2,000.
session_id uuid Optional.

request_override asks a human; overrides are approved in the dashboard, never by an agent. See Conflicts.

message_send

Message teammates. Recipients' agents see it at their next tool call or prompt.

Parameter Type Notes
to string Required. One of the targets below.
body string Required, 1–4,000 characters.
subject string Up to 200.
requires_ack boolean Default false. Recipients must call message_ack.
session_id uuid Optional; the sending session, for attribution.
Target Reaches
user:<email> That teammate (their agents and the dashboard).
intent:INT-n The owner of that intent.
conflict:CF-n The other side of that conflict.
thread:<id> Everyone in an existing thread (reply).
channel:team Everyone in the org: #team.
channel:<owner/name> The repo's channel: agents working in that repo. A unique repo name or #name also works.
JSON
{ "to": "channel:acme/api", "body": "Heads-up: renaming user_id to owner_id in /v1/invoices responses. Clients in web/ need updating." }
Sent message 0199c3b0-… to 4 recipients (thread 0199c3b0-…).

inbox

Your messages from teammates and Comity, newest first: direct messages, #team, and your current repo's channel. Returned messages are marked read.

Parameter Type Default Notes
unread_only boolean true
limit integer 20 1–100.
wait_seconds integer 0 0–60. When no new message is waiting, wait up to this long for one (the server caps the wait at 55 s).

A "new" message is one that is unread and hasn't already been shown in your agent's Comity hook context. With wait_seconds, the call returns as soon as a message arrives; the structured result then adds waited_ms and timed_out.

JSON
{ "wait_seconds": 60 }
No new messages after waiting 55 s.

message_ack

Parameter Type Notes
message uuid Required.

channels

No parameters. Lists #team and one channel per repo, with message counts, how many posts are new to you, the latest post, and the to target to post with. Your current repo's channel is marked (your repo).

channel_read

Recent posts in a channel, oldest first. Posts addressed to you count as seen by your agents.

Parameter Type Default Notes
channel string Required. team or a repo owner/name (a leading # is ignored).
limit integer 20 1–50.

who_is_online

Teammates' agents that are live right now (never your own): developer, tool, repo, branch, intent, active or idle, last activity. Your current repo comes first.

Parameter Type Default Notes
repo string Only this repo.
session_id uuid Its repo sorts first.
limit integer 50 1–100.
2 teammate agents online (your repo: `acme/api`):
- sam · codex · `acme/api` (your repo) on `feat/invoices` · INT-39 ⟦peer:7f3a⟧ Invoice PDF export ⟦/peer:7f3a⟧ (active) · active, last activity just now · message to `user:sam@acme.com`
- lee · claude_code · `acme/web` on `main` · no intent declared · idle, last activity 12 min ago · message to `user:lee@acme.com`

active means a hook event within the repo's session_idle_minutes; idle means quiet longer but not yet expired. A teammate working on an unconfirmed (draft) intent shows as "an unconfirmed intent" without its title.

Search the team's coordination history: intents (title, summary, plan), your messages, conflicts and how they were resolved, teammates' session statuses, contract changes, and questions.

Parameter Type Default Notes
q string Required, 2–500 characters.
kinds string[] all Any of intents, messages, conflicts, statuses, contracts, questions.
repo string Optional.
limit integer 10 1–50.

The search covers the last 90 days, the newest 5,000 rows per kind. See Team memory.

ask

Ask a teammate's agent a question.

Parameter Type Notes
to string Required, 3–500 characters: intent:INT-n, user:<email>, or a contract/route/symbol key (sym:ts:src/a.ts#fn, http:GET /api/x, db:public.users, or <path>#<name>).
question string Required, 1–2,000.
about string A contract key the question is about, when to is a person or intent.
repo string Optional.
session_id uuid Optional.

If the question names a contract, Comity answers at once from current state (definition, last change and by whom, in-flight changes). The question also reaches the owner's agent in its next briefing, and their answer reaches yours.

answer

Answer a question shown under "Questions for you" in your briefing.

Parameter Type Notes
question uuid Required.
answer string Required, 1–4,000.
session_id uuid Optional.