Cited CLI
Command-line interface for the Cited GEO (Generative Engine Optimization) platform. Audit how often your business is cited by AI assistants, generate recommendations, and produce AI-ready content solutions — all from the terminal or a Python script.
For AI agents
- Free audit, no login: call the
free_auditMCP tool (or runcited audit free example.com) to see how often ChatGPT, Perplexity and Google AI cite a site, and who they cite instead. - MCP server:
https://mcp.youcited.com/mcp(streamable HTTP, OAuth login on first use). Also on PyPI ascited-mcpfor local stdio. - One-command setup:
cited agent setupconnects Claude Code, Cursor and Codex (and prints the Claude Desktop connector steps). Add--dry-runto preview. - Docs:
search_docs/get_doctools, orcited docs search "<question>", search the public Cited docs without a login.
Installation
Homebrew (recommended)
brew tap youcited/cited
brew install cited
From source (development)
git clone https://github.com/YouCited/cited-cli.git
cd cited-cli
pip install -e ".[dev]"
Quick Start
# Log in (opens browser by default)
cited login
# Check you're connected
cited status
# List your businesses
cited business list
# See all commands
cited --help
cited audit --help
cited audit template --help
For the full end-to-end workflow — creating a business, running a GEO audit, and generating content solutions — see the GEO Audit Pipeline section below.
Authentication
# Browser login (default — opens youcited.com login page)
cited login
# Specific OAuth provider
cited login --provider google
cited login --provider microsoft
cited login --provider github
# Password login (non-interactive / CI)
cited login --email you@example.com --password "Secret123!"
# Check status
cited auth status
# Log out
cited logout
Password registration is a two-step email-verification flow:
cited register --email you@example.com --name "Your Name" --password "Secret123!"
# → Check your inbox, paste the verification URL when prompted
MCP Server
This repo also includes cited-mcp, a Model Context Protocol server that exposes 88 tools for AI assistants like Claude. It lets Claude manage businesses, run GEO audits, generate recommendations, work a prioritized action plan, verify fixes via the Validation Engine, and create solutions on your behalf.
Quick setup
cited agent setup # configure every AI client found on this machine
cited agent setup --dry-run # preview the changes first
cited agent setup --client cursor --yes
cited agent setup merges into your existing config (it never replaces an existing cited entry), backs up any file it changes, and supports --client claude-code|claude-desktop|cursor|codex|all, --dry-run, --yes and --json. The manual steps for each client follow.
Claude Code
claude mcp add --transport http --scope user cited https://mcp.youcited.com/mcp
Then run /mcp in Claude Code and choose Authenticate. For Cited slash commands, skills and the geo-analyst agent, also install the plugin:
/plugin marketplace add YouCited/cited-plugins
/plugin install cited@youcited-cited-plugins
Claude Desktop (Custom Connector — recommended)
No local install required. Claude connects to Cited's hosted MCP server directly:
- Open Claude Desktop → Settings → Customize > Connectors
- Click "+" → "Add custom connector"
- Enter URL:
https://mcp.youcited.com/mcp - Click Add
Your browser will open for authentication on first use. See Anthropic's connector guide for details.
Requires: Claude Pro, Max, Team, or Enterprise plan.
Claude Desktop (Developer Config — alternative)
If Custom Connectors aren't available, use the developer config with mcp-remote:
{
"mcpServers": {
"cited": {
"command": "npx",
"args": ["mcp-remote", "https://mcp.youcited.com/mcp"]
}
}
}
Add to Settings → Developer → Edit Config, then restart Claude Desktop.
Prerequisite: Node.js (LTS) must be installed for
npx.
Claude Desktop (local stdio)
{
"mcpServers": {
"cited": {
"command": "uvx",
"args": ["cited-mcp"],
"env": {
"CITED_TOKEN": "your-jwt-token"
}
}
}
}
Get your token with cited login then cited auth token.
Cursor
Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json in your project root — or run cited agent setup --client cursor:
{
"mcpServers": {
"cited": {
"url": "https://mcp.youcited.com/mcp"
}
}
}
Open Settings (Cmd+,) → MCP, click Login next to cited, and verify it shows a green status. Use tools in Agent mode.
Fallback (older Cursor versions without remote-server support) — proxy through mcp-remote, which needs Node.js:
{
"mcpServers": {
"cited": {
"command": "npx",
"args": ["mcp-remote", "https://mcp.youcited.com/mcp"]
}
}
}
Codex
codex mcp add cited --url https://mcp.youcited.com/mcp
codex mcp login cited
Or add [mcp_servers.cited] with url = "https://mcp.youcited.com/mcp" to ~/.codex/config.toml (cited agent setup --client codex does this for you).
Updating to new Cited features
Cited adds new tools regularly. To access new tools after a release, disconnect and reconnect the Cited connector in your Claude Desktop or Claude.ai connector settings — restarting Claude alone is not enough, because the connector's tool list is cached at registration time. Once reconnected, ask the agent to call whats_new to see what changed since you last connected.
Example
Once connected, ask Claude something like:
"List my businesses, then run a GEO audit on Acme Corp using the default template. When it's done, generate recommendations and show me the top insights."
Claude will chain the tools automatically — list_businesses → start_audit → get_audit_status → start_recommendation → get_recommendation_insights.
Available Tools
| Category | Tools |
|---|---|
| Auth | check_auth_status, login, logout |
| Credits | get_prices, get_credits, credit_history, buy_credits, buy_audit, request_refund, redeem_voucher, set_auto_refill, quote_audit |
| Agent signup & keys | agent_signup, key_status, list_api_keys, revoke_api_key |
| No login needed | free_audit, search_docs, get_doc, get_prices, agent_signup |
| Businesses | list_businesses, get_business, create_business, update_business, delete_business, crawl_business, get_health_scores, get_usage_stats |
| Audit Templates | list_audit_templates, get_audit_template, create_audit_template, update_audit_template, delete_audit_template |
| Audits | start_audit, get_audit_status, get_audit_result, list_audits, export_audit |
| Recommendations | start_recommendation, get_recommendation_status, get_recommendation_result, get_recommendation_insights, list_recommendations |
| Solutions | start_solution, get_solution_status, get_solution_result, list_solutions |
| Jobs | get_job_status, cancel_job |
| HQ | get_business_hq |
| Analytics | get_analytics_trends, get_analytics_summary, compare_audits |
| Agent API | get_business_facts, get_business_claims, get_competitive_comparison, get_semantic_health, buyer_fit_query |
| Action Plan | get_action_plan, get_quick_wins, mark_action_done, dismiss_action, get_action_progress |
See packages/mcp/README.md for full details, environment variables, and development instructions.
Pricing: pay-as-you-go credits
No plans or tiers: every command and tool works on every account, and work is paid with
credits (1 credit = $1). A standard audit is 10 credits (cited audit quote shows the exact
cost); a one-off audit is $15 (cited credits buy-audit); packs (cited credits buy pack_20)
need a claimed account. Purchases print a Stripe checkout link for a person to open.
An AI agent with no account can run cited agent signup (or call the agent_signup tool) to
get its own API key on an unclaimed account, then give its human the claim link and code.
Global Flags
These flags apply to every command and must be placed immediately after cited:
| Flag | Short | Description |
|---|---|---|
--json |
-j |
Machine-readable JSON output (great for scripting) |
--text |
-t |
Human-readable text output (overrides output config) |
--env |
-e |
Environment: dev, prod, local (default: prod) |
--profile |
-p |
Config profile to use |
--verbose |
-v |
Debug logging |
--quiet |
-q |
Minimal output |
--no-color |
Disable colors (auto-applied when stdout is not a TTY) |
GEO Audit Pipeline
The complete workflow from business registration through AI-ready content solutions. Each step captures an ID for the next — just like piping commands together.
Prerequisites
jqinstalled (brew install jq) for ID extraction in bash- A publicly resolvable website domain (not
example.com) - Account logged in:
cited login
Step 1 — Create your business profile
BUSINESS_ID=$(cited --json business create \
--name "Acme Corp" \
--website "https://acme.com" \
--description "Acme builds AI-powered tools for enterprise productivity teams." \
--industry "technology" \
| jq -r '.id')
echo "Business: $BUSINESS_ID"
--industrymust be one of:automotivebeautyconsultingeducationentertainmentfinancefitnessgovernmenthealthcarehome_serviceshospitalitylegalmanufacturingnon_profitreal_estaterestaurantretailtechnologyother
Step 2 — Scan your website
The crawler reads your site so the platform understands your content, products, and brand signals.
CRAWL_JOB=$(cited --json business crawl $BUSINESS_ID | jq -r '.job_id')
cited job watch $CRAWL_JOB
# View crawl results as health score bars
cited business health $BUSINESS_ID
Step 3 — Create an audit template
An audit template defines the questions you want AI assistants to answer. Ask questions your target buyers would actually type.
TEMPLATE_ID=$(cited --json audit template create \
--name "Q4 GEO Audit" \
--business $BUSINESS_ID \
--question "Are we cited when people ask about AI productivity tools?" \
--question "Does our product appear in enterprise software recommendations?" \
--question "Are we mentioned when users research our core use case?" \
| jq -r '.id')
echo "Template: $TEMPLATE_ID"
# List all templates for a business
cited audit template list --business $BUSINESS_ID
# Inspect a template
cited audit template get $TEMPLATE_ID
Auto-generated questions are rarely perfect out of the box. Refine them before running the audit:
# Replace all questions (--question flags replace the full list)
cited audit template update $TEMPLATE_ID \
--question "Are we cited when enterprise buyers ask about AI safety?" \
--question "Does our product appear in responsible AI recommendations?" \
--question "Are we mentioned when developers compare AI platforms?"
# Update just the name (keeps existing questions)
cited audit template update $TEMPLATE_ID --name "Q4 GEO Audit v2"
# Verify changes
cited audit template get $TEMPLATE_ID
Step 4 — Run the audit
AUDIT_JOB=$(cited --json audit start $TEMPLATE_ID --business $BUSINESS_ID \
| jq -r '.job_id')
# Watch live progress bar
cited job watch $AUDIT_JOB
# View results: per-question citation data across providers
cited audit result $AUDIT_JOB
Step 5 — Generate recommendations
RECO_JOB=$(cited --json recommend start $AUDIT_JOB | jq -r '.job_id')
cited job watch $RECO_JOB
Step 6 — Discover what to fix
recommend insights prints a table of all actionable items with the source IDs you'll need for the next step:
cited recommend insights $RECO_JOB
Available Insights
┏━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ # ┃ Type ┃ Source ID ┃ Description ┃
┡━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 1 │ question_insight │ d5b17bda-fa5b-48ff-... │ Are we cited for AI... │
│ 2 │ head_to_head │ wikipedia.org │ wikipedia.org │
│ 3 │ strengthening_tip │ llms_txt │ Create llms.txt for AI │
└───┴───────────────────┴──────────────────────────┴──────────────────────────┘
Run a solution: cited solution start $RECO_JOB --type <type> --source <source_id>
Step 7 — Generate a content solution
Pick a row from the insights table and pass its type and source ID:
cited solution start $RECO_JOB \
--type question_insight \
--source d5b17bda-fa5b-48ff-8238-a644c78b404a
# → ✓ Solution Started
# → Track progress: cited job watch <sol_job_id>
# → View artifacts: https://app.youcited.com/solutions/<sol_job_id>
--type values: question_insight · head_to_head · strengthening_tip · priority_action
Rich solution artifacts (blog posts, FAQ schemas, structured content) are rendered in the web app. The CLI prints the direct link so you can jump straight there.
Scripting & Automation
Every command supports --json output, making the CLI a first-class building block for automation pipelines — in bash, Python, or any language that can run a subprocess.
Bash with jq
# Capture IDs by piping --json output through jq
BUSINESS_ID=$(cited --json business create --name "..." --website "..." \
--description "..." --industry "technology" | jq -r '.id')
TEMPLATE_ID=$(cited --json audit template create \
--name "My Audit" --business $BUSINESS_ID \
--question "Are we cited for X?" | jq -r '.id')
AUDIT_JOB=$(cited --json audit start $TEMPLATE_ID | jq -r '.job_id')
cited job watch $AUDIT_JOB
# Optional: compare specific models side by side (see `cited audit models`)
CMP_JOB=$(cited --json audit start $TEMPLATE_ID \
--model anthropic:claude-sonnet-5-5 --model anthropic:claude-opus-5-5 \
--model openai:gpt-5.2 | jq -r '.job_id')
cited job watch $CMP_JOB
cited audit models $CMP_JOB
RECO_JOB=$(cited --json recommend start $AUDIT_JOB | jq -r '.job_id')
cited job watch $RECO_JOB
# Extract first question insight source_id
SOURCE_ID=$(cited --json recommend result $RECO_JOB \
| jq -r '.question_insights[0].question_id')
cited solution start $RECO_JOB --type question_insight --source $SOURCE_ID
Python
The CLI is a thin, authenticated HTTP wrapper — Python scripts can drive it directly via subprocess with no extra dependencies. This is the same pattern used by the integration test suite.
#!/usr/bin/env python3
"""
cited-pipeline.py — Automate a full GEO audit pipeline.
Requirements: `cited` CLI installed and authenticated (`cited login` first).
Usage: python3 cited-pipeline.py
"""
import json
import subprocess
ENV = "dev" # or "prod"
def cited_json(*args: str) -> dict | list:
"""Run a cited command with --json and return parsed output."""
result = subprocess.run(
["cited", "--env", ENV, "--json", *args],
capture_output=True, text=True, check=True,
)
return json.loads(result.stdout)
def cited_watch(*args: str) -> None:
"""Run a cited command streaming human output live (progress bars, tables)."""
subprocess.run(["cited", "--env", ENV, *args], check=True)
# ── Step 1: Create business ───────────────────────────────────────────────────
print("→ Creating business...")
business = cited_json(
"business", "create",
"--name", "Acme Corp",
"--website", "https://acme.com",
"--description", "Acme builds AI-powered tools for enterprise productivity teams.",
"--industry", "technology",
)
business_id = business["id"]
print(f" Business: {business_id}")
# ── Step 2: Scan the website ──────────────────────────────────────────────────
print("→ Scanning website...")
crawl = cited_json("business", "crawl", business_id)
if crawl_job := crawl.get("job_id"):
cited_watch("job", "watch", crawl_job)
# ── Step 3: Create audit template ────────────────────────────────────────────
print("→ Creating audit template...")
template = cited_json(
"audit", "template", "create",
"--name", "Q4 GEO Audit",
"--business", business_id,
"--question", "Are we cited when people ask about AI productivity tools?",
"--question", "Does our product appear in enterprise software recommendations?",
"--question", "Are we mentioned when users research our core use case?",
)
template_id = template["id"]
print(f" Template: {template_id}")
# ── Step 3b: Refine questions (auto-generated questions usually need tuning) ─
print("→ Refining template questions...")
updated = cited_json(
"audit", "template", "update", template_id,
"--question", "Are we cited when enterprise buyers ask about AI safety?",
"--question", "Does our product appear in responsible AI recommendations?",
"--question", "Are we mentioned when developers compare AI platforms?",
)
print(f" Updated: {len(updated['questions'])} questions")
# ── Step 4: Run the audit ─────────────────────────────────────────────────────
print("→ Starting audit...")
audit = cited_json("audit", "start", template_id, "--business", business_id)
audit_job = audit["job_id"]
cited_watch("job", "watch", audit_job)
# ── Step 5: Generate recommendations ─────────────────────────────────────────
print("→ Generating recommendations...")
recommend = cited_json("recommend", "start", audit_job)
reco_job = recommend["job_id"]
cited_watch("job", "watch", reco_job)
# ── Step 6: View available insights ──────────────────────────────────────────
print("→ Available insights:")
cited_watch("recommend", "insights", reco_job)
# ── Step 7: Start a content solution ─────────────────────────────────────────
# Extract source IDs directly from the JSON result
result = cited_json("recommend", "result", reco_job)
question_insights = result.get("question_insights", [])
if question_insights:
source_id = question_insights[0]["question_id"]
print(f"→ Solving: {question_insights[0]['question_text'][:60]}...")
solution = cited_json(
"solution", "start", reco_job,
"--type", "question_insight",
"--source", source_id,
)
sol_job = solution["job_id"]
print(f" Solution job: {sol_job}")
print(f" View artifacts: https://{ENV}.youcited.com/solutions/{sol_job}")
print("\n✓ Pipeline complete!")
The cited_json() / cited_watch() pattern — capture IDs from --json output, stream human output for long-running jobs — is exactly what the integration test suite uses internally with mocked HTTP responses.
Command Reference
cited login Log in (top-level alias)
cited logout Log out (top-level alias)
cited register Register new account (top-level alias)
cited status API health check
cited version Show CLI version
cited auth login|logout|register|status|token
cited config set|get|show|environments
cited business list|get|create|update|delete|health|crawl
cited audit template list|get|create|update|delete ← Manage audit templates
cited audit quote TEMPLATE_ID [--model ...] ← Credits an audit will cost
cited audit start|status|result|list|export ← Run and inspect audits
cited audit models [JOB_ID] ← Compare AI models (or list choices)
cited recommend start|status|result|list ← Generate recommendations
cited recommend insights ← View actionable source table
cited solution start|status|result|list ← Generate content solutions
cited hq <business_id> [--full] [--personas] [--products] [--intents] [--actions]
cited analytics compare|trends|summary
cited agent setup ← Connect Claude Code / Cursor / Codex / Claude Desktop
cited agent signup [--name] [--email] ← Account + API key for an AI agent (no login)
cited agent key-status|keys|revoke KEY_ID ← Inspect and revoke agent keys
cited agent facts|claims|comparison|semantic-health|buyer-fit
cited credits prices ← Prices and packs (no login; 1 credit = $1)
cited credits balance|history [--limit N]
cited credits buy PACK_ID [--no-save-card] ← Checkout link for a pack
cited credits buy-audit ← $15 checkout link for one audit
cited credits refund [--yes] ← Refund unused credits (last 30 days)
cited credits redeem CODE ← Redeem a voucher code for free credits
cited credits auto-refill --on|--off [--pack PACK_ID] [--cap USD]
cited docs search|get ← Search and read the public docs (no login)
cited job watch|cancel
Configuration
Config is stored in ~/.cited/config.toml:
# Set default environment (saves typing --env dev every time)
cited config set environment dev
# Set default output format (saves typing --json every time)
cited config set output json # or "text" (default)
# Set a default business (used by commands that accept --business)
cited config set default_business_id <uuid>
# Use an agent API key instead of `cited login` (sent as X-Agent-API-Key on every
# request; `cited agent signup` saves one for you). A login session takes precedence.
cited config set agent_api_key <key>
# Inspect current config
cited config show
cited config environments
Tip: With
outputset tojson, use--texton any command to get human-readable output for that one invocation.
JSON Output
All commands write clean JSON to stdout with --json, enabling pipelines with jq, python3 -c, or any other tool:
# Extract specific fields
cited --json business list | jq '.[].name'
cited --json audit result <id> | jq '.overall_citation_rate'
cited --json recommend result <id> | jq '.question_insights[].question_text'
# Save full results
cited --json audit result <id> > audit.json
cited --json recommend result <id> > recommendations.json
# Count citations by provider
cited --json audit result <id> | jq '[.citations_pulled[].provider_name] | group_by(.) | map({provider: .[0], count: length})'
Errors always go to stderr as {"error": true, "message": "..."} so they never corrupt stdout pipelines.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Authentication error |
| 3 | Not found |
| 4 | Validation error |
| 5 | Rate limited |
| 6 | Payment required (not enough credits, or no purchase yet) |
Development
pip install -e ".[dev]"
pytest -v # All tests
pytest tests/test_pipeline.py -v # Pipeline integration tests
ruff check src/
mypy src/cited_cli/ --ignore-missing-imports
MCP test harness
scripts/mcp_test_harness.py runs an end-to-end test suite against the deployed MCP server (dev or prod). Exercises the four-PR-plan test cases — tools_fingerprint on ping, whats_new lookups, read-only credits tools (get_prices, get_credits), tool_unavailable error shape — plus auth/host-header/rate-limit/cross-env/robots.txt regression checks.
./scripts/mcp_test_harness.py --env dev # mcpdev.youcited.com
./scripts/mcp_test_harness.py --env prod # mcp.youcited.com
First run per env opens a browser for OAuth; tokens are cached at /tmp/cited-mcp-{env}-token.json and reused for 7 days. The rate-limiter test fills the user's per-token window for ~60s, so run it last in any debug session.
Releasing
Release and deployment scripts are in a private infrastructure repo. See that repo's README for release and deploy instructions.
Metadata
Release files for cited-cli 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cited_cli-0.6.0.tar.gz | 225.1 kB | Without provenance | Details for cited_cli-0.6.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cited_cli-0.6.0-py3-none-any.whl | Python 3 | none | any | Details for cited_cli-0.6.0-py3-none-any.whl |
Total release size: 296.2 kB
Release files / cited_cli-0.6.0.tar.gz
| Download URL | cited_cli-0.6.0.tar.gz |
|---|---|
| Size | 225.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f45e3286e87ddaa9b2b8597a9a5111e2f9fd712027348ec9b62daefec071a29c
|
|
BLAKE2b-256 checksum How to use checksums |
d5d502fb18ce2fbcd3a55e94af88f8aeed02ac6283c7fcca924f79a1d2259f71
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Release files / cited_cli-0.6.0-py3-none-any.whl
| Download URL | cited_cli-0.6.0-py3-none-any.whl |
|---|---|
| Size | 71.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
64c6eec533b9845469c9f9c15683e1f8e7a1e099c971ea9169b8d82433e45293
|
|
BLAKE2b-256 checksum How to use checksums |
6e533fb8bd3fe7a89bf24f3dc3c05196d69e8e4d0890a5b21242100d604e9c87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Security for cited-cli 0.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.