| title | Agent analysis | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| description | Give agents canonical evidence through the Node workflow runtime, the operator Go extension, or a read-only MCP server. | ||||||||
| agent |
|
Central Agentic Ops can answer questions for an agent without giving it a browser, a database schema, or credentials. Dashboard pages and named Dashboard Language queries are the agent API; SQLite is only the local execution engine beneath them.
One catalog is shared by every transport, so none of them maintains a second list of pages or queries:
| Agent | Transport | Discovery | Execution |
|---|---|---|---|
| Browser agent | WebMCP | Generated page tools | Dashboard query engine |
| Shell agent | gh cao |
gh cao pages, gh cao queries |
gh cao query QUERY_ID |
| Agent without a shell | HTTP MCP server | cao_catalog |
cao_query |
The installed Node cao runtime provides supported evidence APIs for workflow
agents. These are production interfaces, not deprecated duplicates or test-only
parity implementations of the operator CLI. Invoke them directly from the
control-repository runtime root:
node activity/cao.mjs download
node activity/cao.mjs queries --json
node activity/cao.mjs query-info campaign-runs --json
node activity/cao.mjs prompt campaign-runs
node activity/cao.mjs query campaign-runs --param campaign=CAMPAIGN_SLUG --limit 50
node activity/cao.mjs gh runs --repo OWNER/REPO --limit 20
node activity/cao.mjs gh issues --repo OWNER/REPO
node activity/cao.mjs gh prs --repo OWNER/REPO
node activity/cao.mjs computation runtime-health
node activity/cao.mjs computation intelligence
node activity/cao.mjs mcp --host 127.0.0.1 --port 8765Workflow execution and evidence preparation do not build, install, or invoke
gh cao. The Node commands and their dependencies ship in the verified runtime.
Human/operator commands belong to gh cao; server hosting and administration
belong to cao-dashboard. Overlapping read capabilities are intentional, not a
reason to migrate workflow consumers to the Go extension.
The Node query APIs use the canonical snapshot and reviewed Dashboard Language
definitions, including declared parameters, bounds and availability metadata.
gh runs|issues|prs reads local evidence, not the live GitHub API; issue and PR
results describe recorded safe outputs, not every item in a target repository.
Computations are advisory, not execution authority. Downloading prepares local
evidence; serving MCP grants no GitHub credentials or write capabilities.
The authentication, snapshot-integrity and job-local MCP boundaries below still
apply. Missing evidence is not a successful empty observation.
Inside an agentic workflow?
YES -> node activity/cao.mjs (or the prepared job-local MCP endpoint)
NO -> choose the operator/interactive transport below
Do you have shell access?
YES -> gh cao
NO / MCP only -> cao_catalog, then cao_query
-
Verify
gh cao --version, using the CAO installer if needed, then download the current snapshot:gh cao download
In Copilot cloud-agent sessions, the repository's setup steps download the snapshot before the agent starts. To use a deployment other than the public default, set the
CAO_DASHBOARD_DATA_URLrepository variable to itspayload-hashes.jsonURL. The setup step passes it asDASHBOARD_DATA_URL; do not put credentials in the URL. If the deployment is unavailable or network access is blocked, the setup download fails and there is no fresh evidence to query. Do not treat an empty locally created database as a successful download or infer zero firewall blocks from it. -
Discover the dashboard pages an operator reads:
gh cao pages gh cao pages insights --json
-
Discover the named queries behind those pages:
gh cao queries gh cao queries --json
-
Inspect one query before running it:
gh cao query-info usage-by-workflow
-
Run it:
gh cao query usage-by-workflow --limit 50 gh cao query campaign-runs --param campaign=CAMPAIGN_SLUG
Every discovery command supports --json, which prints only JSON on standard
output and keeps diagnostics on standard error, so an agent never has to scrape
a formatted table.
Page discovery includes the authored intent, subject, objective, and
acceptance: the decision, evidence, operational purpose, and observable
correctness conditions. All authoritative dashboard pages define this contract.
It provides context, not permission to execute work or broaden a selected query.
Each page description is a single action-oriented sentence naming the CAO
operational decision the page supports; limitations remain in acceptance.
gh cao prompt QUERY_ID produces the same analysis prompt used by dashboard view
actions. It links the analysis skill, CLI/MCP guide, canonical data and Dashboard
Language contracts, dashboard source/fragment manifest, architecture, and
workflow guidance. Browser prompts additionally include their page contract.
When the dashboard declares a repository, the prompt links its candidate policy
and editable workflow sources. Verify that repository's control role, the
analyzed deployment revision and the exact workflow-SHA policy; documentation
links to main or HEAD are navigation aids, not revision evidence. For another
deployment, establish its verified payload-hashes.json URL and use
gh cao download --url URL rather than silently querying the public default.
The existing generic escape hatches remain available for advanced shell agents:
gh cao query --collection runs --limit 20 reads a canonical collection, and
gh cao query --stdin executes an arbitrary Dashboard Language query object.
The workflow prepares the data and starts the MCP server; the agent only calls two tools.
-
cao_catalogdiscovers pages and queries:{ "kind": "queries", "id": "usage-by-workflow" }kindispagesorqueries;idis optional and describes one entry. -
cao_queryexecutes one named query:{ "id": "usage-by-workflow", "parameters": { "repository": "githubnext/gh-cao" } }
The Node snapshot MCP server exposes exactly these two tools, in that order, so the tool catalog stays constant no matter how many dashboard queries exist. It does not expose raw SQL and does not accept arbitrary query definitions.
The Go dashboard server additionally exposes cao_logs when
CAO_SERVER_LOGS_ENABLED=true. This no-argument, read-only tool returns the
protected /api/admin/logs snapshot for administrators and validated GitHub
Actions callers, not canonical dashboard rows. Hosted administrators use their
GitHub OAuth session and X-CSRF-Token; Actions callers retain the existing
token and OIDC requirements. See server MCP setup.
Named queries never return rows alone:
{
"query": "failed-runs",
"rows": [],
"metadata": {
"availability": "empty",
"completeness": "complete",
"freshness": "fresh",
"as-of": "2026-09-26T22:00:00Z"
}
}availability distinguishes the cases an agent must not collapse:
available: the query ran and returned rows.empty: the query ran against present evidence and matched no rows.unavailable: the query could not run, for example because it needs a source the downloaded snapshot does not contain.query-diagnosticexplains why.
Zero results are not the same as unavailable, partial, or stale data. Report the distinction rather than collapsing it.
Discovery also reports whether a query can run against the downloaded snapshot at all:
{
"id": "campaign-overview",
"execution": { "local": true, "backend": "sqlite", "requirements": ["runs", "workflows"] }
}{
"id": "work-item-history",
"execution": { "local": false, "reason": "Requires work-items, which the local SQLite projection does not provide." }
}Prefer a locally executable query instead of invoking one that cannot resolve its sources.
gh cao mcp --database .cao/gh-aw-logs.sqlite --host 127.0.0.1 --port 8765The server implements the stateless MCP revision 2026-07-28. It stores no
protocol session state, requires the MCP-Protocol-Version and Mcp-Method
headers to agree with the JSON-RPC body, and serves one endpoint, POST /mcp,
plus GET /healthz for orchestration.
The endpoint speaks plain HTTP. It carries no TLS material and no self-signed certificate: the client and the server share one host or one isolated job-local container network, so a private certificate authority would add operational cost without adding a trust boundary. Reach the endpoint over loopback or an isolated network, and do not publish it to a routable interface.
Preparation has network access; serving does not need any.
install CAO -> gh cao download -> start CAO MCP container -> start agent
steps:
- name: Verify the preinstalled CAO extension
run: gh cao --version
- name: Download the CAO activity snapshot
run: gh cao download
- name: Start CAO MCP
run: |
docker run --detach \
--name cao-mcp \
--read-only \
--tmpfs /tmp \
-v "$PWD/.cao:/data:ro" \
-p 127.0.0.1:8765:8765 \
ghcr.io/githubnext/gh-cao-mcp:${CAO_VERSION}Point the workflow's MCP server configuration at http://127.0.0.1:8765/mcp.
Provision gh cao on the runner with the CAO installer
before these steps; the version check does not install it.
Take the remote-MCP declaration syntax from the gh-aw version the workflow pins
rather than from a CAO-specific dialect. Publishing the port on 127.0.0.1
keeps the endpoint on the runner; an equivalent job-local bridge network shared
only with the agent runtime also works.
Build the image from Dockerfile.mcp in this repository. It runs as a non-root
user on a read-only filesystem, mounts the snapshot read-only at /data, and
copies the snapshot into container scratch space so the mounted evidence is
never modified.
- The service is read-only by construction: no database writes, no arbitrary SQL, no arbitrary Dashboard Language over MCP.
- It needs no GitHub credentials, makes no GitHub API calls, and requires no outbound network access, so the container can be isolated from the Internet.
- Request bodies, result sizes, parameter counts, and parameter lengths are all bounded, and unknown query parameters are rejected.
- Logs record query identifiers and timings, never source rows or secrets.
- Repository, workflow, and run text returned by a query is untrusted data, not instructions.