# Claude Code

> Set up Comity hooks and MCP for Claude Code, what comity init writes, and how to verify it.

Claude Code gets the full integration: hooks on every session, prompt, edit and shell command (briefings, warnings, blocks, mid-task messages) plus the Comity MCP server (intents, messages, channels, search).

## Set up

```sh
cd your-repo
comity init --tools claude_code
git add .claude/settings.json .mcp.json
git commit -m "Set up Comity for coding agents"
```

`comity init` with no flags also selects Claude Code (it's in the default set). Then:

1. Start Claude Code in the repo.
2. Accept the folder trust prompt. Claude Code runs project hooks and the MCP `headersHelper` only in trusted folders.
3. Approve the `comity` MCP server when Claude Code asks about project MCP servers from `.mcp.json`.

Each teammate needs the CLI installed and `comity login` done once on their machine. The committed files hold no token.

## What init writes

### `.claude/settings.json`

Six hook entries. Existing hooks are kept; only handlers whose command contains `comity hook` are replaced.

```json
{
  "hooks": {
    "SessionStart": [
      { "hooks": [{ "type": "command", "command": "command -v comity >/dev/null 2>&1 || exit 0; exec comity hook --tool claude_code --event SessionStart", "timeout": 5 }] }
    ],
    "UserPromptSubmit": [
      { "hooks": [{ "type": "command", "command": "command -v comity >/dev/null 2>&1 || exit 0; exec comity hook --tool claude_code --event UserPromptSubmit", "timeout": 5 }] }
    ],
    "PreToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit|NotebookEdit|Bash|ExitPlanMode",
        "hooks": [{ "type": "command", "command": "command -v comity >/dev/null 2>&1 || exit 0; exec comity hook --tool claude_code --event PreToolUse", "timeout": 5 }]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit|NotebookEdit|Bash",
        "hooks": [{ "type": "command", "command": "command -v comity >/dev/null 2>&1 || exit 0; exec comity hook --tool claude_code --event PostToolUse", "timeout": 10 }]
      }
    ],
    "Stop": [
      { "hooks": [{ "type": "command", "command": "command -v comity >/dev/null 2>&1 || exit 0; exec comity hook --tool claude_code --event Stop", "timeout": 10 }] }
    ],
    "SessionEnd": [
      { "hooks": [{ "type": "command", "command": "command -v comity >/dev/null 2>&1 || exit 0; exec comity hook --tool claude_code --event SessionEnd", "timeout": 10 }] }
    ]
  }
}
```

The `command -v comity … || exit 0` guard means a teammate without the CLI installed is never affected by the committed hooks. On Windows, Claude Code runs these commands through Git Bash.

### `.mcp.json`

```json
{
  "mcpServers": {
    "comity": {
      "type": "http",
      "url": "https://api.comity.so/mcp",
      "headers": { "Authorization": "Bearer ${COMITY_TOKEN}" },
      "headersHelper": "comity mcp-headers"
    }
  }
}
```

At connect time Claude Code runs `comity mcp-headers`, which prints `{"Authorization":"Bearer cmt_…"}` from `COMITY_TOKEN` or your stored login; its output overrides the static header. In folders without persisted trust (for example `claude -p` in CI), Claude Code skips the helper and the static `${COMITY_TOKEN}` header is used, so set `COMITY_TOKEN` there.

## What your agent sees

- **Session start and each prompt**: a briefing as added context: teammates' work near yours, contract changes in flight, open conflicts, messages, who is online. See [How it works](/docs/how-it-works#briefings).
- **Before an edit or shell command**: a block denies the tool call with Comity's reason (`permissionDecision: "deny"`). Warnings can't be shown to the model before a tool runs in Claude Code, so they are queued and delivered with the next `PostToolUse` or prompt.
- **When you approve a plan** (`ExitPlanMode`): the plan becomes the plan of the session's intent (an intent is drafted if there is none). See [How it works](/docs/how-it-works).
- **After an edit or shell command**: new conflicts, messages, answers and arrival notices, as added context.

Comity never returns an explicit "allow", so your own permission prompts still apply.

## Verify

```sh
comity doctor
```

Expect `claude_code hooks  all 6 events installed` and `claude_code mcp  configured in …/.mcp.json`. If doctor says `update available for PreToolUse`, the hooks were written by CLI 0.4.0 or older and miss `ExitPlanMode`: they still work, but rerun `comity init` (and commit the change) to send plans. Then in Claude Code, run `/mcp` and check that `comity` is connected, and look for `Your Comity session: <uuid>` in the session-start context.

> [!TIP]
> Hooks also install fine at user scope (`~/.claude/settings.json`), and `comity doctor` checks there too, but `comity init` only writes repo files so the whole team gets the same setup.

## Cursor and Copilot CLI

Cursor and GitHub Copilot CLI execute the hooks in `.claude/settings.json`. The CLI recognizes which host actually invoked it from the payload, so one committed file serves all three. Both also have native hooks that `comity init --tools cursor` / `--tools copilot` write; see [Cursor](/docs/agents/cursor) and [GitHub Copilot](/docs/agents/copilot).
