-
-
Notifications
You must be signed in to change notification settings - Fork 1
Agent CLI and MCP
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.
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.
- 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.
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.
{
"version": 1,
"repo": "/absolute/path/to/repository",
"source": {
"kind": "repository",
"scope": { "type": "staged" }
},
"options": {
"conventional": true,
"includeBranchName": true,
"previousCommitCount": 3
}
}coco agent commit-draft --input request.jsonprintf '%s\n' '{
"version": 1,
"source": {
"kind": "summary",
"summary": "Added root-constrained MCP tools and structured agent responses.",
"files": [
{ "path": "src/mcp/server.ts", "status": "added" },
{ "path": "src/operations/agent/schemas.ts", "status": "added" }
],
"provenance": { "generatedBy": "calling-agent" }
}
}' | coco agent changelog --input - --repo /absolute/path/to/repositoryEach operation has a strict input schema and an operation-specific output schema:
coco agent schema --task commit-draft
coco agent schema --task review
coco agent schema --task changelog
coco agent schema --task recapThe schema command does not call a model or require repository changes. It prints:
{
"version": 1,
"operation": "review",
"input": { "type": "object" },
"output": { "oneOf": [] }
}The abbreviated objects above represent full JSON Schemas in real output.
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.
Add a local stdio server entry to your client's MCP configuration:
{
"mcpServers": {
"coco": {
"command": "coco",
"args": [
"mcp",
"--repo",
"/absolute/path/to/repository"
]
}
}
}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:
{
"mcpServers": {
"coco-api": {
"command": "/absolute/path/to/coco",
"args": ["mcp", "--repo", "/work/api"]
},
"coco-web": {
"command": "/absolute/path/to/coco",
"args": ["mcp", "--repo", "/work/web"]
}
}
}Restart or reconnect the server from the MCP client after changing its configuration.
| 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.
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.
Every operation accepts the same top-level request:
{
version?: 1
repo?: string
source?: ChangeSource
options?: AgentOptions
}Unknown fields are rejected at every level. Defaults are applied when fields are omitted:
{
"version": 1,
"source": {
"kind": "repository",
"scope": { "type": "staged" }
},
"options": {
"conventional": false,
"includeBranchName": false,
"previousCommitCount": 0,
"author": false,
"trustRepositoryConfig": false
}
}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.
This is the default and safest repository-derived source:
{
"source": {
"kind": "repository",
"scope": { "type": "staged" }
}
}It reads git diff --cached with external diff drivers and text conversion disabled.
{
"source": {
"kind": "repository",
"scope": { "type": "worktree" }
},
"options": {
"trustRepositoryConfig": true
}
}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.
{
"source": {
"kind": "repository",
"scope": {
"type": "branch",
"base": "origin/main",
"head": "HEAD"
}
}
}head defaults to HEAD. Both references must resolve to commits.
{
"source": {
"kind": "repository",
"scope": {
"type": "range",
"from": "v0.82.0",
"to": "HEAD"
}
}
}Revisions cannot begin with - or contain NUL bytes. coco verifies them with an end-of-options boundary before using them in a diff.
Use this when the calling agent already has the exact patch:
{
"source": {
"kind": "patch",
"patch": "diff --git a/src/a.ts b/src/a.ts\n...",
"baseRevision": "origin/main",
"headRevision": "0123456789abcdef"
}
}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.
{
"source": {
"kind": "files",
"files": [
{
"path": "src/new.ts",
"status": "added",
"summary": "Adds a typed agent operation dispatcher."
},
{
"path": "src/old.ts",
"oldPath": "src/legacy.ts",
"status": "renamed",
"patch": "diff --git ..."
}
],
"provenance": {
"headRevision": "0123456789abcdef",
"generatedBy": "calling-agent"
}
}
}Each file requires path, status, and either patch or summary.
Allowed status values are:
modifiedrenamedaddeddeleteduntrackedunknown
A request can include at most 500 file entries.
This is the most token-efficient choice when the caller has already inspected the change:
{
"source": {
"kind": "summary",
"summary": "Adds four read-only generation tools over a shared typed operation layer.",
"files": [
{ "path": "src/mcp/server.ts", "status": "added" }
],
"provenance": {
"generatedBy": "calling-agent"
}
}
}A summary can list up to 500 affected paths. Those file entries do not contain patch content.
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:
{
"meta": {
"kind": "summary",
"digest": "sha256:...",
"verification": "provided-unverified"
}
}| 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.
{
"version": 1,
"ok": true,
"operation": "commit-draft",
"status": "completed",
"data": {
"title": "feat(agent): expose structured generation tools",
"body": "Add JSON and MCP transports over a shared typed operation layer.",
"formatted": "feat(agent): expose structured generation tools\n\nAdd JSON and MCP transports over a shared typed operation layer.",
"validationErrors": []
},
"warnings": [],
"meta": {
"kind": "repository",
"digest": "sha256:...",
"repositoryHead": "0123456789abcdef",
"verification": "repository-derived"
}
}Operation data shapes:
-
commit-draft:title,body,formatted,validationErrors[] -
review:findings[], where each item hastitle,summary,severity(1-10),category, andfilePath -
changelog:title,content -
recap:title,summary
{
"version": 1,
"ok": false,
"operation": "review",
"error": {
"code": "NO_CHANGES",
"message": "No changes were found for the requested source.",
"retryable": false
}
}Validation failures may include a details field. Callers should branch on ok and error.code, not parse human-readable messages.
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.
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:
# Force local recording on at the default user-cache path
COCO_USAGE_LOG=1 coco mcp --repo /work/api
# Force it off
COCO_USAGE_LOG=0 coco agent review --input request.json
# Use an explicit local ledger path
COCO_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.
The agent CLI could not parse the input file or stdin. Validate it before calling coco:
jq . request.jsonThe 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.json--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-toplevelThe 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.
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.
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}'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 }
}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.
The selected Git source has no changes, or supplied context is blank. Verify the staged diff:
git diff --cached --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.
The selected provider requires credentials. Run coco init, set the provider-specific environment variable, and verify with coco doctor.
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.
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.