Agent CLI and MCP Integration
coco exposes its Git-aware AI generation as a versioned, structured interface for coding agents, IDEs, automation, and Model Context Protocol clients. The integration supports four operations:
| Operation | Agent CLI value | MCP tool | Result |
|---|---|---|---|
| Commit draft | commit-draft | coco_commit_draft | Title, body, formatted message, and safe built-in Conventional Commits validation when requested |
| Code review | review | coco_review | Structured findings sorted by severity |
| Changelog | changelog | coco_changelog | Changelog title and content |
| Work recap | recap | coco_recap | Recap title and summary |
Both transports call the same typed operation layer and return the same protocol-v1 success or failure envelopes. They generate drafts and analysis only. They do not create commits, write repository files, post comments, or mutate a forge.
When to use each transport
Use the agent CLI when the caller can run a one-shot process, needs a stable JSON/stdin contract, or does not support MCP. Use the local stdio MCP server when the client supports tool discovery, JSON Schema, cancellation, and filesystem roots.
Do not wrap the interactive coco commands and scrape their terminal output. The agent interfaces are designed for machine callers and keep stdout protocol-safe.
Requirements and installation
- Node.js
22.22.2or newer in a supported release line - Git
- A configured
cocoAI provider and credentials - An MCP-capable client only when using the MCP transport
Install globally:
npm install -g git-coco@latest
coco initOr run the one-shot agent CLI without a global install:
npx git-coco@latest agent schema --task reviewVerify the installed commands:
coco agent --help
coco mcp --help
coco agent schema --task commit-draftThe normal provider configuration applies. See Config Overview, Using Ollama, and Dynamic Model Routing.
Agent CLI
The command shape is:
coco agent <commit-draft|review|changelog|recap> --input <file|-> [--repo <dir>]--input <file>reads one JSON request from a file.--input -reads one JSON request from stdin.- When stdin is a TTY and
--inputis omitted, the request defaults to{}. --reposelects the repository from the command line and takes precedence overrepoin the request.- stdout contains only the JSON result. Diagnostics do not get mixed into the response.
- A failed operation emits a versioned failure envelope and exits non-zero.
SIGINTcancels repository and model work, emits aCANCELLEDfailure, and exits with status 130.
File request
1{
2 "version": 1,
3 "repo": "/absolute/path/to/repository",
4 "source": {
5 "kind": "repository",
6 "scope": { "type": "staged" }
7 },
8 "options": {
9 "conventional": true,
10 "includeBranchName": true,
11 "previousCommitCount": 3
12 }
13}coco agent commit-draft --input request.jsonstdin request
1printf '%s\n' '{
2 "version": 1,
3 "source": {
4 "kind": "summary",
5 "summary": "Added root-constrained MCP tools and structured agent responses.",
6 "files": [
7 { "path": "src/mcp/server.ts", "status": "added" },
8 { "path": "src/operations/agent/schemas.ts", "status": "added" }
9 ],
10 "provenance": { "generatedBy": "calling-agent" }
11 }
12}' | coco agent changelog --input - --repo /absolute/path/to/repositoryPublish the schemas
Each operation has a strict input schema and an operation-specific output schema:
1coco agent schema --task commit-draft
2coco agent schema --task review
3coco agent schema --task changelog
4coco agent schema --task recapThe schema command does not call a model or require repository changes. It prints:
1{
2 "version": 1,
3 "operation": "review",
4 "input": { "type": "object" },
5 "output": { "oneOf": [] }
6}The abbreviated objects above represent full JSON Schemas in real output.
MCP server
Start one local stdio server for one repository:
coco mcp --repo /absolute/path/to/repositoryThe server writes MCP messages to stdout and startup information to stderr. It remains bound to the normalized Git top-level directory for its lifetime.
Generic MCP client configuration
Add a local stdio server entry to your client's MCP configuration:
1{
2 "mcpServers": {
3 "coco": {
4 "command": "coco",
5 "args": [
6 "mcp",
7 "--repo",
8 "/absolute/path/to/repository"
9 ]
10 }
11 }
12}If coco is not on the MCP client's PATH, use the absolute path to the binary. Find it with:
command -v cocoFor multiple repositories, configure a separate server entry and process for each repository:
1{
2 "mcpServers": {
3 "coco-api": {
4 "command": "/absolute/path/to/coco",
5 "args": ["mcp", "--repo", "/work/api"]
6 },
7 "coco-web": {
8 "command": "/absolute/path/to/coco",
9 "args": ["mcp", "--repo", "/work/web"]
10 }
11 }
12}Restart or reconnect the server from the MCP client after changing its configuration.
Available tools
| Tool | Description |
|---|---|
coco_commit_draft | Generate a commit-message draft. With conventional: true, validate it against coco's built-in Conventional Commits rules without loading repository configuration. Never creates a commit. |
coco_review | Return structured code-review findings. Never posts comments. |
coco_changelog | Generate changelog content. Never writes CHANGELOG.md. |
coco_recap | Summarize the supplied or repository-derived changes. |
All tools publish strict input and output schemas. The output schema exposes explicit success and failure alternatives. Successful calls return both MCP text content and structuredContent; failed calls set isError and return the same structured failure envelope used by the agent CLI.
The tools advertise readOnlyHint: true and destructiveHint: false. Generation is intentionally not marked idempotent because model output can vary between calls.
MCP roots
If a client advertises the MCP roots capability, the bound repository must be inside one of the file roots returned by that client. Otherwise the tool returns REPOSITORY_OUTSIDE_ROOT.
A request may omit repo, which is recommended for MCP. If it provides repo, the path must normalize to the server's existing bound repository. A tool call cannot switch the server to another repository.
Protocol-v1 request
Every operation accepts the same top-level request:
1{
2 version?: 1
3 repo?: string
4 source?: ChangeSource
5 options?: AgentOptions
6}Unknown fields are rejected at every level. Defaults are applied when fields are omitted:
1{
2 "version": 1,
3 "source": {
4 "kind": "repository",
5 "scope": { "type": "staged" }
6 },
7 "options": {
8 "conventional": false,
9 "includeBranchName": false,
10 "previousCommitCount": 0,
11 "author": false,
12 "trustRepositoryConfig": false
13 }
14}Even supplied patch/summary calls run in a Git repository because the repository provides the coco configuration and model context. Supplied sources do not inspect repository changes, and they do not read HEAD unless the request includes a head revision for provenance verification.
Change sources
Staged repository changes
This is the default and safest repository-derived source:
1{
2 "source": {
3 "kind": "repository",
4 "scope": { "type": "staged" }
5 }
6}It reads git diff --cached with external diff drivers and text conversion disabled.
Worktree changes
1{
2 "source": {
3 "kind": "repository",
4 "scope": { "type": "worktree" }
5 },
6 "options": {
7 "trustRepositoryConfig": true
8 }
9}Worktree inspection can invoke repository-defined clean filters. It is therefore rejected by default with UNSAFE_SOURCE.
- The one-shot agent CLI can opt in with
trustRepositoryConfig: truefor a repository the caller explicitly trusts. - MCP always rejects
trustRepositoryConfigwithUNSAFE_OPTION. Supply a patch, file summaries, or a consolidated summary instead.
A trusted worktree source combines staged, unstaged, and untracked-file information.
Branch comparison
1{
2 "source": {
3 "kind": "repository",
4 "scope": {
5 "type": "branch",
6 "base": "origin/main",
7 "head": "HEAD"
8 }
9 }
10}head defaults to HEAD. Both references must resolve to commits.
Explicit range
1{
2 "source": {
3 "kind": "repository",
4 "scope": {
5 "type": "range",
6 "from": "v0.82.0",
7 "to": "HEAD"
8 }
9 }
10}Revisions cannot begin with - or contain NUL bytes. coco verifies them with an end-of-options boundary before using them in a diff.
Supplied patch
Use this when the calling agent already has the exact patch:
1{
2 "source": {
3 "kind": "patch",
4 "patch": "diff --git a/src/a.ts b/src/a.ts\n...",
5 "baseRevision": "origin/main",
6 "headRevision": "0123456789abcdef"
7 }
8}baseRevision and headRevision are provenance fields. When headRevision exactly matches the repository's current HEAD, the response metadata reports head-matched; otherwise supplied data remains provided-unverified.
Supplied files
1{
2 "source": {
3 "kind": "files",
4 "files": [
5 {
6 "path": "src/new.ts",
7 "status": "added",
8 "summary": "Adds a typed agent operation dispatcher."
9 },
10 {
11 "path": "src/old.ts",
12 "oldPath": "src/legacy.ts",
13 "status": "renamed",
14 "patch": "diff --git ..."
15 }
16 ],
17 "provenance": {
18 "headRevision": "0123456789abcdef",
19 "generatedBy": "calling-agent"
20 }
21 }
22}Each file requires path, status, and either patch or summary.
Allowed status values are:
modifiedrenamedaddeddeleteduntrackedunknown
A request can include at most 500 file entries.
Supplied summary
This is the most token-efficient choice when the caller has already inspected the change:
1{
2 "source": {
3 "kind": "summary",
4 "summary": "Adds four read-only generation tools over a shared typed operation layer.",
5 "files": [
6 { "path": "src/mcp/server.ts", "status": "added" }
7 ],
8 "provenance": {
9 "generatedBy": "calling-agent"
10 }
11 }
12}A summary can list up to 500 affected paths. Those file entries do not contain patch content.
Context limits and digest
Supplied patch/summary fields are limited to 2 MiB, and the fully formatted aggregate context is checked again against the same 2 MiB limit. If the aggregate is too large, consolidate it before calling coco.
Every successful response includes a SHA-256 digest of the exact resolved change context:
1{
2 "meta": {
3 "kind": "summary",
4 "digest": "sha256:...",
5 "verification": "provided-unverified"
6 }
7}Options
| Option | Type/default | Used by | Behavior |
|---|---|---|---|
language | string, optional | all operations | Writes the generated result in the requested language. |
additionalContext | string, max 32 KiB | commit draft, changelog | Adds caller-provided guidance to the generation prompt. |
conventional | boolean, false | commit draft | Requests Conventional Commits formatting and validates the result against coco's built-in rules without loading repository config. |
includeBranchName | boolean, false | commit draft | Includes the current branch name in generation context. |
previousCommitCount | integer 0-20, 0 | commit draft | Includes this many previous commits for style/context. |
author | boolean, false | changelog | Includes author attribution only when present in supplied context. |
timeframe | string, optional | recap | Labels the period represented by the supplied changes. |
trustRepositoryConfig | boolean, false | agent CLI only | Enables repository-defined prompt/commitlint config and permits worktree inspection. MCP always rejects it. |
Repository-defined custom prompts and executable commitlint configuration are disabled unless the one-shot agent CLI explicitly opts into trustRepositoryConfig.
Responses
Success envelope
1{
2 "version": 1,
3 "ok": true,
4 "operation": "commit-draft",
5 "status": "completed",
6 "data": {
7 "title": "feat(agent): expose structured generation tools",
8 "body": "Add JSON and MCP transports over a shared typed operation layer.",
9 "formatted": "feat(agent): expose structured generation tools\n\nAdd JSON and MCP transports over a shared typed operation layer.",
10 "validationErrors": []
11 },
12 "warnings": [],
13 "meta": {
14 "kind": "repository",
15 "digest": "sha256:...",
16 "repositoryHead": "0123456789abcdef",
17 "verification": "repository-derived"
18 }
19}Operation data shapes:
commit-draft:title,body,formatted,validationErrors[]review:findings[], where each item hastitle,summary,severity(1-10),category, andfilePathchangelog:title,contentrecap:title,summary
Failure envelope
1{
2 "version": 1,
3 "ok": false,
4 "operation": "review",
5 "error": {
6 "code": "NO_CHANGES",
7 "message": "No changes were found for the requested source.",
8 "retryable": false
9 }
10}Validation failures may include a details field. Callers should branch on ok and error.code, not parse human-readable messages.
Safety model
The machine interfaces use stricter defaults than an interactive developer session:
- The MCP server is local stdio, not a remote network service.
- One MCP process is bound to one real, normalized Git repository root.
- Client filesystem roots are enforced when the client advertises them.
- Repository switching is rejected per tool call.
- Git commands disable optional locks and filesystem monitors.
- Diff collection disables external diff drivers and text conversion.
- Revisions are validated and passed after an end-of-options boundary.
- Worktree reads are rejected unless the one-shot agent CLI explicitly trusts repository configuration.
- MCP never enables repository-defined prompts or executable commitlint configuration.
- Supplied patches, summaries, and file data are framed as untrusted data in model prompts. Instructions inside repository content must not alter the operation or output format.
- Model cancellation propagates through MCP request signals and through
SIGINTin the agent CLI. - The four operations generate data only. They do not create commits, write files, post review comments, open pull requests, or call forge mutation APIs.
readOnlyHint refers to repository and forge behavior. If local usage analytics are enabled, coco can append a metadata-only record to its user cache as described below.
Local usage analytics and privacy
Agent and MCP calls participate in the same local usage ledger as normal coco commands when usage recording is already enabled.
Machine transports never show a consent prompt and never write a configuration preference. They only honor:
COCO_USAGE_LOG, when set; otherwise- the existing
telemetry.usagepreference.
The environment variable wins in both directions:
1# Force local recording on at the default user-cache path
2COCO_USAGE_LOG=1 coco mcp --repo /work/api
3
4# Force it off
5COCO_USAGE_LOG=0 coco agent review --input request.json
6
7# Use an explicit local ledger path
8COCO_USAGE_LOG=/tmp/coco-usage.jsonl coco agent recap --input request.jsonEach JSONL row contains metadata only:
- timestamp
- command/task label
- surface:
cli,agent-cli, ormcp - provider and model identifiers
- estimated prompt tokens and provider-reported completion tokens, when available
- elapsed milliseconds
- a readable repository tag, when available
The ledger does not store prompts, patches, diffs, source code, generated responses, filenames, request options, or API keys. It is bounded, remains on the local machine, and is never written into the repository.
Review it with:
coco doctor --cost
coco doctor --cost --jsonThe report aggregates by task, model, surface, and repository. Delete it with:
coco doctor --clearSee Config Overview: local usage stats for the general preference behavior.
Troubleshooting
INVALID_JSON
The agent CLI could not parse the input file or stdin. Validate it before calling coco:
jq . request.jsonINVALID_INPUT
The request does not match protocol version 1. Common causes are unknown fields, an unsupported operation option, an invalid status value, or a context field over its limit.
Print the current schema and validate against it:
coco agent schema --task review > review-schema.jsonINVALID_REPOSITORY
--repo, request repo, or the current directory is not a Git repository. Use an existing directory and an absolute path for MCP configuration.
git -C /absolute/path/to/repository rev-parse --show-toplevelREPOSITORY_OUTSIDE_ROOT
The requested repository is outside the MCP client's advertised filesystem roots. Add the repository to the client's workspace/root configuration, reconnect the server, or start a server for an allowed repository.
REPOSITORY_MISMATCH
The request attempted to use a different repository from the MCP server's bound root. Omit repo from MCP tool input or start a second server process for that repository.
INVALID_REVISION
A branch/range reference is unsafe or does not resolve to a commit. Verify it without treating it as an option:
git rev-parse --verify --end-of-options 'origin/main^{commit}'UNSAFE_SOURCE
An untrusted call requested worktree inspection. Prefer staged changes or supply a patch/summary. For a repository you explicitly trust, only the one-shot agent CLI can set:
{
"options": { "trustRepositoryConfig": true }
}UNSAFE_OPTION
An MCP call set trustRepositoryConfig: true. MCP does not allow this option. Remove it and use a staged, branch, range, patch, files, or summary source.
NO_CHANGES
The selected Git source has no changes, or supplied context is blank. Verify the staged diff:
git diff --cached --CONTEXT_TOO_LARGE
The resolved context exceeds 2 MiB. Have the calling agent consolidate the change into a summary and affected-file list, then send a summary source.
AUTHENTICATION_REQUIRED
The selected provider requires credentials. Run coco init, set the provider-specific environment variable, and verify with coco doctor.
CANCELLED
The MCP client cancelled the request or the agent CLI received SIGINT. This is not retryable automatically; retry only when the user or calling agent intends to restart the operation.
GENERATION_FAILED or OPERATION_FAILED
The model call, parser, or commit-message validation failed. Check provider connectivity and configuration:
coco doctor
coco doctor --costIf the client shows no tools, run the server command directly and inspect stderr, verify the absolute coco path, then reconnect the MCP client:
/absolute/path/to/coco mcp --repo /absolute/path/to/repositoryFor more general provider, installation, and Git issues, see Troubleshooting.