# goose

> Set up Comity for goose with native hooks through a project plugin, AGENTS.md instructions and the MCP extension.

goose runs Comity's hooks from a project plugin on session start, prompts, shell commands and file edits, stop and session end. A hook can block a tool call. goose gives hooks no way to add context for the model, so briefings and warnings reach the agent only through the MCP tools and the AGENTS.md instructions.

## Set up

```sh
cd your-repo
comity init --tools goose
git add .agents/plugins/comity AGENTS.md
git commit -m "Set up Comity for goose"
```

Then add the MCP extension to your **user** config, `~/.config/goose/config.yaml` (`%APPDATA%\Block\goose\config\config.yaml` on Windows). It runs the [stdio bridge](/docs/agents/mcp-clients#stdio-bridge-comity-mcp), so there's no token anywhere: `comity login` is enough. `comity init` prints this entry:

```yaml
extensions:
  comity:
    name: comity
    type: stdio
    cmd: node
    args: ["-e", "const c=require('child_process').spawn('comity '+process.argv.slice(1).join(' '),{stdio:'inherit',shell:true});c.on('error',()=>process.exit(1));c.on('exit',(k)=>process.exit(k===null?1:k))", "mcp"]
    enabled: true
    timeout: 300
```

The `node -e` launcher runs `comity mcp` through your shell and works the same on every OS. Node must be on PATH, which the CLI needs anyway.

goose keeps extensions only in the user config ([Using Extensions](https://goose-docs.ai/docs/getting-started/using-extensions)), so init doesn't write this into the repo.

Start goose from the repo root so it finds the project plugin.

## What init writes

### `.agents/plugins/comity/`

An [Open Plugins](https://goose-docs.ai/docs/guides/context-engineering/plugins) plugin: `plugin.json` and `hooks/hooks.json`. Shown for one event:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "^(shell|write|edit)$",
        "hooks": [
          {
            "type": "command",
            "command": "command -v comity >/dev/null 2>&1 || exit 0; exec comity hook --tool goose --event PreToolUse",
            "timeout": 5
          }
        ]
      }
    ]
  }
}
```

| goose event | Matcher | Timeout (s) |
|---|---|---|
| `SessionStart` | | 5 |
| `UserPromptSubmit` | | 5 |
| `PreToolUse` | `^(shell\|write\|edit)$` | 5 |
| `PostToolUse` | `^(shell\|write\|edit)$` | 10 |
| `Stop` | | 10 |
| `SessionEnd` | | 10 |

goose runs hooks with `sh -c`. On a machine without the CLI the hook exits 0 and goose carries on.

### `AGENTS.md`

Comity's coordination instructions in a block marked `<!-- comity:start -->` … `<!-- comity:end -->`. goose loads `AGENTS.md` and `.goosehints` by default ([goosehints](https://goose-docs.ai/docs/guides/context-engineering/using-goosehints)).

## What your agent sees

- **Before a shell command or file edit**: a block answers `{"decision":"block","reason":"…"}` and goose returns the reason to the model as a policy denial.
- **Session start, prompts, after tool calls**: Comity records the session, the prompt and the edits, but goose shows hook output to nobody. Warnings appear only when the agent calls `team_context` or `inbox`.

## Verify

```sh
comity doctor
```

Expect `goose hooks  .agents/plugins/comity/hooks/hooks.json` and `goose mcp  comity extension in goose config.yaml`. If you listed `comity` in `disabledPlugins`, doctor warns.

## Limits

- No model-visible context from hooks (goose's [hook docs](https://goose-docs.ai/docs/guides/context-engineering/hooks) define no context output): briefings and warnings come only through the MCP tools.
- A hook that fails or times out lets the tool call through.
