Canonry/canonry

Agent-first AI SEO (AEO/GEO) operating platform

TypeScript

145

1,014 commits

updated Sep 22, 2026

See the code

See what people are saying (1)

SourceMessageScoreDate

Open-source "PostHog" for AI visibility

1

Sep 22, 2026

README

Canonry Canonry canary icon

License: MIT npm version

Canonry is an agent-first (CLI, MCP, API), open-source AEO operating platform with a comprehensive web UI. Track AI visibility over time, investigate changes across search and traffic, and measure progress after you or your agent acts.

Self-hosted, using SQLite, with your own (BYOK) provider keys. The web UI and your agent see the same evidence.

Live UI Demo · Quick start · Evidence · Actions · Integrations · Docs · Support

AI, search, analytics, and traffic sources feed Canonry on schedules or on demand. Historical evidence across multiple domains and portfolios runs from baseline through the latest checks. Your agent reads evidence and sends commands to Canonry tools, while using its own tools for code and content. Canonry publishes to WordPress, submits to Google and Bing, and supplies the dashboard, reports, and webhooks. Site changes loop back into measurement.

Quick start

Start with your agent

Copy the first-time setup request
Help me set up Canonry for my public site.

Use the official Canonry docs:
- Agent quickstart: https://github.com/Canonry/canonry#or-use-any-shell-capable-coding-agent
- CLI reference: https://github.com/Canonry/canonry/blob/main/skills/canonry/references/canonry-cli.md
- Plugin setup: https://github.com/Canonry/canonry/blob/main/docs/plugins.md
- MCP setup: https://github.com/Canonry/canonry/blob/main/docs/mcp.md

Pick one path and stay on it. Use connected Canonry tools (plugin or MCP) only if you have them and I have not pointed you at a specific install. A connected tool runs in its own process and never sees `CANONRY_CONFIG_DIR`, `CANONRY_PORT`, or anything else you export in a shell, so it always acts on my default install. If I named a config directory, a port, or a sandbox, that is the shell path: use `cnry` and tell me which path you chose. Never mix the two in one run, and never create a duplicate project. The `cnry` and `canonry` commands are interchangeable.

1. Ask for my public domain, country, and language. Do not create or scan anything yet. Country and language are only applied when a project is created, so if you reuse an existing project, report its country and language instead of changing them.
2. Shell path only: confirm `cnry` is on PATH, then run `cnry --version`. If Canonry is missing, propose `npm install -g @canonry/canonry` and wait for approval. Then run `cnry doctor --format json`, which is the command that says whether config, database, and server are in place. `cnry --version` does not read config and succeeds on a completely unconfigured install, so it cannot answer this. If config is missing, run `cnry bootstrap` yourself: it is not interactive, takes about a second, and is safe to rerun. Do not hand it to me and wait. The interactive command is `cnry init`, which is optional provider and OAuth setup that Page Health does not need. Bootstrap prints an API key, so do not repeat its output back to me, and never ask me to paste passwords, API keys, OAuth credentials, or command output.
3. Confirm the API is reachable. `cnry doctor --format json` reports it, and any project read exits non-zero with `CONNECTION_ERROR` when it is not. If it is unreachable, propose `cnry start` and wait for approval. Use `cnry start`, which is the background daemon, and not `cnry serve`, which runs in the foreground and will block you until I stop it, even though some error messages suggest it. Stop anything you started with `cnry stop`.
4. List projects with the connected project tool or `cnry project list --format json`, and reuse one whose domain matches. Confirm the proposed name is not already assigned to a different domain. To find out whether a project has already been scanned, run `cnry technical-aeo score <project> --format json` with no `--run-id`, which reports the latest run. Read the `hasData` field, not the score: this command exits 0 and reports `aggregateScore: 0` for a project that has never been scanned, so reading the score alone would have you tell me my site scored zero. If `hasData` is true and `runStatus` is `completed` or `partial`, read that scan instead of starting a new one. If no project matches, show the exact create operation and wait for approval.
5. Propose a bounded Site Health scan: `--max-pages 100` for a first look, plus whether dead-link checking is on (it is off unless you pass `--check-dead-links`). Show the connected operation or the exact `cnry technical-aeo run <project> --max-pages 100 --wait --format json` command with the project name filled in, and wait for separate approval before scanning. `--wait` polls for up to 15 minutes and returns only the run id and status. If the status it returns is still `queued` or `running`, the scan has not finished: do not rerun it or report results, poll `cnry technical-aeo progress <project> --run-id <run-id> --format json` until it is terminal. If `--wait` outruns your own tool timeout first, recover the run id with `cnry technical-aeo score <project> --format json` and poll the same way.
6. When the run is `completed` or `partial`, read `cnry technical-aeo crawl <project> --run-id <run-id> --format json` first. It is the only one of these commands that carries `termination` and `complete`; the score and pages commands do not. Then read `cnry technical-aeo score <project> --run-id <run-id> --format json` and `cnry technical-aeo pages <project> --run-id <run-id> --sort score-asc --limit 10 --format jsonl`. Tell me the termination reason in plain words and whether the scan covered the whole site or stopped at a page, link, depth, or time limit. A `partial` run scored the pages it reached and not my site, so never present it as a full-site result. If it stopped early, the fix depends on the reason, so say which: a page or depth limit needs a larger budget, a time limit needs a smaller scan (a lower `--max-pages` or `--max-depth`). If the run failed or was cancelled, inspect the run error and stop.
7. Summarize only completed evidence, then propose AI Visibility setup. Ask before you add queries, connect providers, start a provider-backed or quota-consuming run, edit files, or publish.

Or Use Official Claude and Codex Plugins

Connect the Agent Plugin or MCP adapter to your own agent.

Or start it locally yourself

  1. Install Canonry.

    npm install -g @canonry/canonry
    
  2. Initialize Canonry.

    cnry bootstrap
    
  3. Start Canonry.

    cnry serve
    
  4. Open http://127.0.0.1:4100/setup and follow the setup to scan your site.

The crawl saves a Page Health baseline. AI Visibility is optional and has a separate setup.

Scan and read results from the terminal

Keep cnry serve active. In a second terminal, create a project and start a bounded scan:

cnry project create my-site --domain example.com --country US --language en
cnry technical-aeo run my-site --max-pages 100 --wait --format json

Read the run ID and status from the output. If the status is completed or partial, read evidence from that run:

cnry technical-aeo score my-site --run-id <run-id> --format json
cnry technical-aeo pages my-site --run-id <run-id> --sort score-asc --limit 10 --format jsonl

--wait polls for up to 15 minutes. If the scan remains active, use cnry technical-aeo progress <project> --run-id <id> --format json. If the scan fails or is cancelled, read the error with cnry run show <run-id> --format json.

Explore the evidence

Your agent and dashboard use the same project API. The dashboard makes trends, exact answers, and site findings available for human review.

AI visibility

Track brand mentions and citations over time, by query and answer engine. Find answers that cite competitors but omit your site.

Canonry AI Visibility mention share trend across answer engines

Track your share of answer-engine brand mentions over time.

Canonry AI Visibility citation map across queries and answer engines

The citation map shows mention and citation coverage across queries and engines. Rank cited domains and pages, then inspect the exact answers and URLs behind each result.

Configure a provider and run visibility checks

For an existing project, configure a provider with your own key.

ProviderKey sourceEnvironment variable
GeminiGoogle AI StudioGEMINI_API_KEY
OpenAIOpenAI PlatformOPENAI_API_KEY
ClaudeAnthropic ConsoleANTHROPIC_API_KEY
PerplexityPerplexity settingsPERPLEXITY_API_KEY
Local modelAny OpenAI-compatible endpointLOCAL_BASE_URL

Add the queries that matter to your project:

cnry query add my-site "your first query" "your second query"
cnry run my-site --wait
cnry visibility-stats my-site --by-provider

Why Canonry uses direct provider APIs

Canonry uses direct provider APIs to capture answers, citations, and available search details that model routers can omit. This richer data helps us measure brand mentions and website citations accurately and explain changes in your visibility. Read more about accuracy and why we chose models and direct provider API adapters individually.

Discover questions or run one-off research

Expand your tracked questions. Run cnry discover run <project> --icp "...". This does not change the tracked questions. Preview a completed session with cnry discover promote preview <project> <session-id>. Promote only after approval.

Research without changing tracking. Run cnry research run <project> "query one" "query two" --wait. For a configured portfolio destination, select one --market <key> or --property <key>; Canonry saves the destination with the answers without changing the query. Add paired --template-id <id> --template-version <version> only to preserve an already-expanded template's provenance. Research never adds queries to the tracked questions.

Portfolios and competitors

Use versioned measurement plans for portfolios of locations, products, or site sections.

  • Properties: Assign queries, engines, models, and locations to each property. Keep branded and non-brand coverage separate.
  • Market groups: Organize overlapping sets of properties, each with its own competitors.
  • Comparisons: Compare properties, groups, engines, and locations. Open the exact answers and cited URLs behind each result.

Search, traffic, and site health

Investigate visibility changes with evidence from search and local performance, crawler visits, AI page fetches, referrals, and conversions. Site audits show technical findings alongside that evidence.

Canonry Site Map graph

Map crawlable pages and the internal links that connect them.

Act on the evidence

Your agent coordinates the work through Canonry and its own tools.

An example job for your connected agent:

Find where competitors get cited and we don't. Use search data and the site audit to prepare a pull request or WordPress draft for review. After it ships, rerun checks and report what changed.

Integrations

Connect the sources you use. Each integration adds evidence or tools to the same project workflow.

AreaSupported integrations
AI answersChatGPT · Claude · Gemini · Perplexity · OpenAI-compatible local models
Search and localGoogle Search Console · Bing Webmaster Tools · Google Business Profile
AnalyticsGoogle Analytics 4
Conversion measurementGoogle Ads + Google Tag Manager: read-only snapshots and declared conversion contracts
Server trafficCloudflare · Vercel · Cloud Run · WordPress
BacklinksCommon Crawl hyperlink releases, queried locally with DuckDB
Publishing and indexingWordPress · JSON-LD · sitemap and URL submissions
ChatGPT AdsCampaign measurement, paused campaign editing, approved activation, and operation reconciliation

Self-hosting and API

Canonry is single-tenant. Run one instance for one operator or team. Keep unrelated teams on separate instances.

The CLI and REST API are the primary interfaces. They expose measurements, diagnoses, actions, reports, and schedules. OpenAPI is available at GET /api/v1/openapi.json.

See the deployment guide for reverse proxies, daemon mode, Docker, systemd, and Tailscale.

Documentation

Troubleshoot installation, scans, and visibility results
ProblemNext step
Site scan is still activeRead exact counters with cnry technical-aeo progress <project> --run-id <id> --format json.
Site scan failedRead the error with cnry run show <run-id> --format json. Read the last phase and counters with the progress command.
No visibility resultsInspect existing work with cnry runs <project> --format json, then cnry run show <run-id> --format json. This does not start another paid run.
npm install fails on node-gypInstall build tools for better-sqlite3 (guide).

Support

Join the Canonry Discord for support and questions about Canonry.

Contributing

git clone https://github.com/Canonry/canonry.git && cd canonry
pnpm install && pnpm run typecheck && pnpm run test && pnpm run lint

See CONTRIBUTING.md.

License

MIT, starting with Canonry 5.0.0. Use, modify, self-host, redistribute, and build commercial products with Canonry. Keep the copyright and permission notice with copies or substantial portions of the software.

Earlier releases retain their original licenses, including any future-license grants. Dependencies and bundled assets retain their own licenses; see third-party notices.

aeo
agent
ai-search
ai-visibility
answer-engine-optimisation
answer-engine-optimization
brand-monitoring
cli
generative-engine-optimization
geo
geo-optimization
google-analytics
local-first
mcp
self-hosted
seo
seo-optimization
server-side-tracking
sqlite
web-analytics

Contributors

arberx

1,007 commits

claude

3 commits

evolv3ai

2 commits

bosinupebi

1 commits

Canonry/canonry

Agent-first AI SEO (AEO/GEO) operating platform

TypeScript

145

1,014 commits

updated Sep 22, 2026

See the code

See what people are saying (1)

SourceMessageScoreDate

Open-source "PostHog" for AI visibility

1

Sep 22, 2026

README

Canonry Canonry canary icon

License: MIT npm version

Canonry is an agent-first (CLI, MCP, API), open-source AEO operating platform with a comprehensive web UI. Track AI visibility over time, investigate changes across search and traffic, and measure progress after you or your agent acts.

Self-hosted, using SQLite, with your own (BYOK) provider keys. The web UI and your agent see the same evidence.

Live UI Demo · Quick start · Evidence · Actions · Integrations · Docs · Support

AI, search, analytics, and traffic sources feed Canonry on schedules or on demand. Historical evidence across multiple domains and portfolios runs from baseline through the latest checks. Your agent reads evidence and sends commands to Canonry tools, while using its own tools for code and content. Canonry publishes to WordPress, submits to Google and Bing, and supplies the dashboard, reports, and webhooks. Site changes loop back into measurement.

Quick start

Start with your agent

Copy the first-time setup request
Help me set up Canonry for my public site.

Use the official Canonry docs:
- Agent quickstart: https://github.com/Canonry/canonry#or-use-any-shell-capable-coding-agent
- CLI reference: https://github.com/Canonry/canonry/blob/main/skills/canonry/references/canonry-cli.md
- Plugin setup: https://github.com/Canonry/canonry/blob/main/docs/plugins.md
- MCP setup: https://github.com/Canonry/canonry/blob/main/docs/mcp.md

Pick one path and stay on it. Use connected Canonry tools (plugin or MCP) only if you have them and I have not pointed you at a specific install. A connected tool runs in its own process and never sees `CANONRY_CONFIG_DIR`, `CANONRY_PORT`, or anything else you export in a shell, so it always acts on my default install. If I named a config directory, a port, or a sandbox, that is the shell path: use `cnry` and tell me which path you chose. Never mix the two in one run, and never create a duplicate project. The `cnry` and `canonry` commands are interchangeable.

1. Ask for my public domain, country, and language. Do not create or scan anything yet. Country and language are only applied when a project is created, so if you reuse an existing project, report its country and language instead of changing them.
2. Shell path only: confirm `cnry` is on PATH, then run `cnry --version`. If Canonry is missing, propose `npm install -g @canonry/canonry` and wait for approval. Then run `cnry doctor --format json`, which is the command that says whether config, database, and server are in place. `cnry --version` does not read config and succeeds on a completely unconfigured install, so it cannot answer this. If config is missing, run `cnry bootstrap` yourself: it is not interactive, takes about a second, and is safe to rerun. Do not hand it to me and wait. The interactive command is `cnry init`, which is optional provider and OAuth setup that Page Health does not need. Bootstrap prints an API key, so do not repeat its output back to me, and never ask me to paste passwords, API keys, OAuth credentials, or command output.
3. Confirm the API is reachable. `cnry doctor --format json` reports it, and any project read exits non-zero with `CONNECTION_ERROR` when it is not. If it is unreachable, propose `cnry start` and wait for approval. Use `cnry start`, which is the background daemon, and not `cnry serve`, which runs in the foreground and will block you until I stop it, even though some error messages suggest it. Stop anything you started with `cnry stop`.
4. List projects with the connected project tool or `cnry project list --format json`, and reuse one whose domain matches. Confirm the proposed name is not already assigned to a different domain. To find out whether a project has already been scanned, run `cnry technical-aeo score <project> --format json` with no `--run-id`, which reports the latest run. Read the `hasData` field, not the score: this command exits 0 and reports `aggregateScore: 0` for a project that has never been scanned, so reading the score alone would have you tell me my site scored zero. If `hasData` is true and `runStatus` is `completed` or `partial`, read that scan instead of starting a new one. If no project matches, show the exact create operation and wait for approval.
5. Propose a bounded Site Health scan: `--max-pages 100` for a first look, plus whether dead-link checking is on (it is off unless you pass `--check-dead-links`). Show the connected operation or the exact `cnry technical-aeo run <project> --max-pages 100 --wait --format json` command with the project name filled in, and wait for separate approval before scanning. `--wait` polls for up to 15 minutes and returns only the run id and status. If the status it returns is still `queued` or `running`, the scan has not finished: do not rerun it or report results, poll `cnry technical-aeo progress <project> --run-id <run-id> --format json` until it is terminal. If `--wait` outruns your own tool timeout first, recover the run id with `cnry technical-aeo score <project> --format json` and poll the same way.
6. When the run is `completed` or `partial`, read `cnry technical-aeo crawl <project> --run-id <run-id> --format json` first. It is the only one of these commands that carries `termination` and `complete`; the score and pages commands do not. Then read `cnry technical-aeo score <project> --run-id <run-id> --format json` and `cnry technical-aeo pages <project> --run-id <run-id> --sort score-asc --limit 10 --format jsonl`. Tell me the termination reason in plain words and whether the scan covered the whole site or stopped at a page, link, depth, or time limit. A `partial` run scored the pages it reached and not my site, so never present it as a full-site result. If it stopped early, the fix depends on the reason, so say which: a page or depth limit needs a larger budget, a time limit needs a smaller scan (a lower `--max-pages` or `--max-depth`). If the run failed or was cancelled, inspect the run error and stop.
7. Summarize only completed evidence, then propose AI Visibility setup. Ask before you add queries, connect providers, start a provider-backed or quota-consuming run, edit files, or publish.

Or Use Official Claude and Codex Plugins

Connect the Agent Plugin or MCP adapter to your own agent.

Or start it locally yourself

  1. Install Canonry.

    npm install -g @canonry/canonry
    
  2. Initialize Canonry.

    cnry bootstrap
    
  3. Start Canonry.

    cnry serve
    
  4. Open http://127.0.0.1:4100/setup and follow the setup to scan your site.

The crawl saves a Page Health baseline. AI Visibility is optional and has a separate setup.

Scan and read results from the terminal

Keep cnry serve active. In a second terminal, create a project and start a bounded scan:

cnry project create my-site --domain example.com --country US --language en
cnry technical-aeo run my-site --max-pages 100 --wait --format json

Read the run ID and status from the output. If the status is completed or partial, read evidence from that run:

cnry technical-aeo score my-site --run-id <run-id> --format json
cnry technical-aeo pages my-site --run-id <run-id> --sort score-asc --limit 10 --format jsonl

--wait polls for up to 15 minutes. If the scan remains active, use cnry technical-aeo progress <project> --run-id <id> --format json. If the scan fails or is cancelled, read the error with cnry run show <run-id> --format json.

Explore the evidence

Your agent and dashboard use the same project API. The dashboard makes trends, exact answers, and site findings available for human review.

AI visibility

Track brand mentions and citations over time, by query and answer engine. Find answers that cite competitors but omit your site.

Canonry AI Visibility mention share trend across answer engines

Track your share of answer-engine brand mentions over time.

Canonry AI Visibility citation map across queries and answer engines

The citation map shows mention and citation coverage across queries and engines. Rank cited domains and pages, then inspect the exact answers and URLs behind each result.

Configure a provider and run visibility checks

For an existing project, configure a provider with your own key.

ProviderKey sourceEnvironment variable
GeminiGoogle AI StudioGEMINI_API_KEY
OpenAIOpenAI PlatformOPENAI_API_KEY
ClaudeAnthropic ConsoleANTHROPIC_API_KEY
PerplexityPerplexity settingsPERPLEXITY_API_KEY
Local modelAny OpenAI-compatible endpointLOCAL_BASE_URL

Add the queries that matter to your project:

cnry query add my-site "your first query" "your second query"
cnry run my-site --wait
cnry visibility-stats my-site --by-provider

Why Canonry uses direct provider APIs

Canonry uses direct provider APIs to capture answers, citations, and available search details that model routers can omit. This richer data helps us measure brand mentions and website citations accurately and explain changes in your visibility. Read more about accuracy and why we chose models and direct provider API adapters individually.

Discover questions or run one-off research

Expand your tracked questions. Run cnry discover run <project> --icp "...". This does not change the tracked questions. Preview a completed session with cnry discover promote preview <project> <session-id>. Promote only after approval.

Research without changing tracking. Run cnry research run <project> "query one" "query two" --wait. For a configured portfolio destination, select one --market <key> or --property <key>; Canonry saves the destination with the answers without changing the query. Add paired --template-id <id> --template-version <version> only to preserve an already-expanded template's provenance. Research never adds queries to the tracked questions.

Portfolios and competitors

Use versioned measurement plans for portfolios of locations, products, or site sections.

  • Properties: Assign queries, engines, models, and locations to each property. Keep branded and non-brand coverage separate.
  • Market groups: Organize overlapping sets of properties, each with its own competitors.
  • Comparisons: Compare properties, groups, engines, and locations. Open the exact answers and cited URLs behind each result.

Search, traffic, and site health

Investigate visibility changes with evidence from search and local performance, crawler visits, AI page fetches, referrals, and conversions. Site audits show technical findings alongside that evidence.

Canonry Site Map graph

Map crawlable pages and the internal links that connect them.

Act on the evidence

Your agent coordinates the work through Canonry and its own tools.

An example job for your connected agent:

Find where competitors get cited and we don't. Use search data and the site audit to prepare a pull request or WordPress draft for review. After it ships, rerun checks and report what changed.

Integrations

Connect the sources you use. Each integration adds evidence or tools to the same project workflow.

AreaSupported integrations
AI answersChatGPT · Claude · Gemini · Perplexity · OpenAI-compatible local models
Search and localGoogle Search Console · Bing Webmaster Tools · Google Business Profile
AnalyticsGoogle Analytics 4
Conversion measurementGoogle Ads + Google Tag Manager: read-only snapshots and declared conversion contracts
Server trafficCloudflare · Vercel · Cloud Run · WordPress
BacklinksCommon Crawl hyperlink releases, queried locally with DuckDB
Publishing and indexingWordPress · JSON-LD · sitemap and URL submissions
ChatGPT AdsCampaign measurement, paused campaign editing, approved activation, and operation reconciliation

Self-hosting and API

Canonry is single-tenant. Run one instance for one operator or team. Keep unrelated teams on separate instances.

The CLI and REST API are the primary interfaces. They expose measurements, diagnoses, actions, reports, and schedules. OpenAPI is available at GET /api/v1/openapi.json.

See the deployment guide for reverse proxies, daemon mode, Docker, systemd, and Tailscale.

Documentation

Troubleshoot installation, scans, and visibility results
ProblemNext step
Site scan is still activeRead exact counters with cnry technical-aeo progress <project> --run-id <id> --format json.
Site scan failedRead the error with cnry run show <run-id> --format json. Read the last phase and counters with the progress command.
No visibility resultsInspect existing work with cnry runs <project> --format json, then cnry run show <run-id> --format json. This does not start another paid run.
npm install fails on node-gypInstall build tools for better-sqlite3 (guide).

Support

Join the Canonry Discord for support and questions about Canonry.

Contributing

git clone https://github.com/Canonry/canonry.git && cd canonry
pnpm install && pnpm run typecheck && pnpm run test && pnpm run lint

See CONTRIBUTING.md.

License

MIT, starting with Canonry 5.0.0. Use, modify, self-host, redistribute, and build commercial products with Canonry. Keep the copyright and permission notice with copies or substantial portions of the software.

Earlier releases retain their original licenses, including any future-license grants. Dependencies and bundled assets retain their own licenses; see third-party notices.

aeo
agent
ai-search
ai-visibility
answer-engine-optimisation
answer-engine-optimization
brand-monitoring
cli
generative-engine-optimization
geo
geo-optimization
google-analytics
local-first
mcp
self-hosted
seo
seo-optimization
server-side-tracking
sqlite
web-analytics

Contributors

arberx

1,007 commits

claude

3 commits

evolv3ai

2 commits

bosinupebi

1 commits

Languages

TypeScript

96.2%

HTML

2.5%