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):
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. |
{
"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"
}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 |
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. |
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. |
{ "to": "channel:acme/api", "body": "Heads-up: renaming user_id to owner_id in /v1/invoices responses. Clients in web/ need updating." }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.
{ "wait_seconds": 60 }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. |
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.
history_search
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. |