MCP API Reference
Connect AI assistants like Claude, ChatGPT, Cursor, and more to AEO Optima via the Model Context Protocol (MCP).
Overview
AEO Optima exposes a Model Context Protocol (MCP) server that allows AI assistants to access your brand visibility data, capture snapshots, run analytics, and more — all without leaving your AI tool.
Server URL: https://mcp.aeo.techshu.ai/mcp
Transport: Streamable HTTP (JSON-RPC over HTTP POST)
Authentication: Bearer token or OAuth 2.1
Getting Started
There are two ways to connect your AI client to AEO Optima. The step-by-step setup for each assistant is on one page, Connect AI assistants; this page is the reference.
Option A: Manual Token
- Log in to the AEO Optima dashboard
- Go to Settings > MCP / API
- Click Generate Token
- Give it a name (e.g., "Claude Code") and select a role cap
- Copy the token immediately — it's shown only once
- Paste the token into your AI client's configuration (see Client Configuration below)
Option B: OAuth 2.1 (Click-to-connect)
Some AI clients (Claude.ai and ChatGPT) sign in with OAuth, so there is no token to copy. When you connect from your AI client:
- A browser window opens with the AEO Optima login page
- You log in (or are already logged in)
- A consent screen shows what the AI client is requesting
- You pick your organization and access level, and approve
- You're redirected back — connection is automatic
OAuth discovery endpoints:
- Authorization Server Metadata:
https://aeo.techshu.ai/.well-known/oauth-authorization-server - Protected Resource Metadata:
https://mcp.aeo.techshu.ai/.well-known/oauth-protected-resource
OAuth supports PKCE (required), Dynamic Client Registration, refresh tokens, and token revocation.
Client Configuration
The setup for each assistant is on Connect AI assistants. If the assistant uses a token, start with Generate a token; Which way each assistant connects summarises every assistant.
- Claude.ai (web, desktop and mobile) — OAuth; a fixed token instead of signing in is in beta
- Claude Code — token
- ChatGPT — OAuth, in developer mode
- Grok — a custom connector in the Grok app, or the xAI API remote MCP tool with a token
- OpenAI Codex — token
- Cursor — token
- VS Code with GitHub Copilot — token
- Windsurf — token
- Gemini CLI — token
- Amazon Q Developer — see Amazon Q Developer's MCP guide
- OpenAI Agents SDK — token
- Anthropic API — token
Authentication
AEO Optima supports two authentication methods. Both produce a Bearer token that is sent with every MCP request.
Method 1: Manual Tokens
Generated from the Settings page. Format: aeo_ + 48 random hex characters (52 characters total).
- SHA-256 hashed before storage — plaintext is never stored
- Optional expiration dates for time-limited access
- Can be revoked at any time from the Settings page
- Scoped to a specific user + organization
Method 2: OAuth 2.1
OAuth tokens are generated automatically through the browser-based consent flow. Format: oat_ + 48 random hex characters.
OAuth supports:
- Authorization Code + PKCE (S256 only) — no client secrets needed
- Dynamic Client Registration (RFC 7591) — AI clients auto-register
- Refresh Tokens — access tokens auto-renew without re-authorization
- Token Revocation (RFC 7009) — revoke access or refresh tokens
- Scopes:
mcp:tools,mcp:resources,mcp:prompts
Role Hierarchy
Both token types have a role cap that limits what they can do, regardless of the user's actual role:
| Role | Read Data | Write Data | View Costs | Admin Tools |
|---|---|---|---|---|
| viewer | Projects, snapshots, analytics, prompts, models | No | No | No |
| member | Everything a viewer can + usage/cost data | Capture snapshots, create/update prompts | Yes | No |
| admin | Everything | Everything a member can | Yes | No |
| owner | Everything | Everything | Yes | No |
The effective permission is always the minimum of the token's role cap and the user's actual organization role.
Tools
The MCP server exposes the customer-facing tools below, grouped by category, plus platform-owner-only tools that never appear for customer tokens. Tools that require a feature flag (Advanced Analytics, GEO Audit, GA4, GSC, Webhooks, Connectors, Citations, Crawlers, Content, Predictive, Enterprise, Query Universe, Fusion Insights) only work for organizations whose plan includes the corresponding feature.
Every tool advertises a short human-readable title (for example "Delete an alert rule") alongside readOnlyHint and destructiveHint. Clients that honour these hints can run read-only tools without asking and ask you to confirm anything that changes or deletes data.
Pagination & structured output
Every tool carries the MCP spec annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) so clients can reason about a tool's safety before calling it. Large list tools are cursor-paginated and never silently truncate: get_snapshots, list_insights, and list_actions use a keyset cursor ordered on (created_at desc, id desc), while get_citations uses a documented offset cursor over its deterministically sorted source lists. Whenever more data exists, the response includes a nextCursor — pass it back as cursor to fetch the next page (an invalid cursor returns a clean 400 error):
get_dashboard_metrics, get_citations, get_aeo_program, and get_criteria_map also return structuredContent alongside the text block, with an outputSchema declared on the tool definition.
Projects
| Tool | Description | Min Role |
|---|---|---|
list_projects | List all projects in your organization | viewer |
get_project | Get detailed project info (brand, competitors, LLM configs). The project carries its budget and auto-refill amount fields (budget_allocation, budget_used_current_period, auto_refill_amount, auto_refill_max_per_day, auto_refill_used_today) with their figures only for a token whose organization role is owner or admin; for a member or viewer token each is null (the key is kept, never 0) | viewer |
create_project | Create a project with platform defaults — recommended AI models pre-configured, 5 default alert rules, optional competitor seeding and category/industries business context (industries: up to 5, primary first; a single industry becomes the primary). Counts toward the projects quota. The returned project carries its budget and auto-refill amount fields (budget_allocation, budget_used_current_period, auto_refill_amount, auto_refill_max_per_day, auto_refill_used_today) as null: dollar figures are shown to organization owners and admins in the app | member |
update_project | Update a project's core fields (name, brand, website, description) and its category/industries business context (merge-only settings write). industries replaces the whole list (up to 5, primary first). industry alone sets the PRIMARY and keeps the other industries; an empty industry removes only the primary. When both are sent, industries wins. comparison_basis sets what every coloured number is judged against (best_competitor, benchmark, target, past_best or immediate_past); an empty string clears it, which means the defaults: the best competitor for non-brand questions and the project's own past best for brand questions. Org owner/admin only. The returned project carries its budget and auto-refill amount fields as null, as PATCH /api/projects does; get_project gives an owner or admin the figures | admin |
get_brand_facts | List the project's Brand Facts — verified key-value facts (founding year, HQ, pricing, certifications) ordered by category then key | viewer |
get_claim_library | The claim library: every Brand Fact with its approval state, validity dates, evidence URL, and how many capture runs contradicted it. Only approved claims inside their dates are used in anything the platform generates — look here first when an FAQ or schema block omits a fact | viewer |
set_brand_facts | Create or update Brand Facts in bulk (upsert on fact_key, up to 100 per call), including approval state, validity dates and evidence URL. Approving is a human decision, and changing the value of an approved claim returns it to pending. Omitted fields are left alone; an explicit null clears one. Honest per-fact results. Org owner/admin only | admin |
add_competitor | Add a competitor to track (case-insensitive duplicate rejection, URL validation; a name the project already tracks through its client group is refused with status 409, naming that competitor). For an owner or admin, also returns the names it may also appear under in your answers of the last 30 days, as data; nothing is saved | member |
remove_competitor | Remove a tracked competitor from a project. A competitor that comes from the project's client group is refused with status 409: hide it for the project instead. Org owner/admin only | admin |
Snapshots
| Tool | Description | Min Role |
|---|---|---|
get_snapshots | Retrieve snapshots with filters (date, model, sentiment, brand mention). Each row carries sentimentMethod beside sentiment (who produced the verdict) and sentimentOutcome (what the judge found when it ran: accepted, nothing_to_judge, judge_unavailable, judge_not_run or no_outcome), and mentionBasis beside brand_mentioned: the rule that decided the stored verdict — detector (the name matcher), alias_own (one of your curated names), alias_exclusion (a curated name you marked as not yours), unknown (your curated names could not be read at capture), or owner_revert (a platform-wide correction had newly read the answer as naming you and its undo put it back to not naming you). It is null on answers captured before 23 September 2026, 4:30 pm IST (not recorded) unless a correction has since re-decided them; see Brand Mention. From 17 September 2026 the sentiment filter matches judge-scored answers only and therefore returns fewer rows than before | viewer |
get_snapshot_detail | Get full AI response text and analysis for a snapshot | viewer |
capture_snapshot | Capture new AI responses for a prompt across models (captures per hour are capped by plan — see Rate Limits). Each returned result carries sentimentMethod — judge, word_list or no_record — beside sentiment, so the caller that asked for the capture can see who scored it | member |
Analytics
| Tool | Description | Min Role |
|---|---|---|
get_dashboard_metrics | KPI summary: visibility %, sentiment, rank, period-over-period changes (default 30-day window, matching the dashboard; days overridable). avgRankPosition is kept for compatibility — position within one answer is unstable across runs; topThreeRate is the replacement | viewer |
get_analytics | Visibility trends, LLM comparison, prompt performance. Per surface, per prompt and overall, avgRank is kept for compatibility (position within one answer is unstable across runs); topThreeRate with its rankedRuns denominator is the replacement beside it. poolEngineSplit compares engines inside each of the four question types (rate, numerator, denominator, question floor, best-to-worst spread per type); llmComparison blends the four types into one rate per engine and is kept for compatibility — rank engines on the split, never on the blend | viewer |
get_usage_metrics | Token usage and cost breakdown by provider, model, day. Cost figures (totalCost, avgCostPerRequest, each item's cost) for an owner or admin token, or a platform admin; every cost value null for a member token — tokens and request counts for all (Decision K) | member |
get_sentiment_breakdown | Sentiment analysis by prompt and model | viewer |
Advanced Analytics
get_entity_analysis, get_shopping_visibility and get_multi_language_analysis require the ai_insights_advanced feature flag; list_emerging_competitors and get_share_of_model work on any plan with MCP access.
| Tool | Description | Min Role |
|---|---|---|
get_entity_analysis | Brand attribute extraction from snapshots, clarity scoring (0-100), verified against brand facts. Accepts optional segment parameter. | viewer |
get_shopping_visibility | Shopping keyword detection, position tracking, price accuracy, competitor analysis. Accepts optional segment parameter. Its tone figures moved on 17 September 2026 — sentimentBreakdown counts judge-scored answers only, the payload carries tonePopulation, and notJudgedReasons says why each un-judged row is un-judged | viewer |
get_multi_language_analysis | Per-language visibility, character-range detection (CJK/Arabic/Cyrillic), localized recommendations. Accepts optional segment parameter. Its tone figures moved on 17 September 2026 — judgedCount and sentimentCounts cover judge-scored answers only, and the new judgedAvgSentiment is null where the deprecated avgSentiment reads 0 | viewer |
list_emerging_competitors | Brands extracted from snapshots that are not yet in your configured competitor list, ranked by mention count over the last N days | viewer |
get_share_of_model | Share of Model: per prompt × engine inclusion frequency — the share of sampled runs your brand appears in. Each cell carries sample size n and a confidence band (under 10 = low confidence, 10-29 = below target, 30+ = ok). SERP-AI surfaces appear as their own engines | viewer |
Sentiment counting (changed 4 September 2026): wherever a tool returns a
sentimentBreakdown, itspositive,neutralandnegativecounts are answers that named your brand AND carry a judged verdict — so a share computed over them is a share of answers that actually expressed something. Two residuals now travel beside them and are never folded in:notJudged(your brand was named, but no verdict was recorded) andnotNamed(your brand was not in the answer, so no judgement was possible). Before this date an answer with no verdict was counted asneutral, which reported a missing judgement as a neutral opinion. The three key names and their types are unchanged, so existing integrations keep working; aneutralfigure taken from before 4 September 2026 is not comparable with one taken after.
Tone is counted from judge-scored answers only (changed 17 September 2026): when the sentiment judge cannot be reached, a word list still records a verdict so the capture is not lost. A word list is a stand-in for a reading, not a reading, and until this date every tool counted the two as one thing — while the product's own Sentiment page had stopped counting them on 16 September, a day earlier. From 17 September the verdict counts on
get_analytics(overallStats.sentimentBreakdownand each entry ofpromptPerformance) and onget_sentiment_breakdown(overall,byPrompt,byModel) cover judge-scored answers only, and each payload states the population it is over in an additivetonePopulationfield, whose one value today isjudge_scored. Measured over the 30 days to 16 September 2026, this moved 1,875 counted answers to 1,777 across nine projects — but read the per-project figures in the analytics guide before the average: eight of the nine move by 8% or less while one loses close to a third. Three things to know:totalonget_sentiment_breakdownis now the sum of the three verdict counts (the judge-scored answers), withnamedcarrying the figure it used to hold andnotJudgedcarrying the difference, so a share computed from this payload divides by the population its numerators came from;get_snapshotsreturnssentimentMethod(judge|word_list|no_record) on every row and itssentimentfilter now matches judge-scored rows only, so it returns fewer rows than before for the same value; andget_dashboard_metricsis deliberately unchanged — itssentimentScore,sentimentPolarityandpositiveRatestill cover every brand-mentioning answer, exactly as their field descriptions say.get_entity_analysisdid not move either: its per-entity tone has always read judge-written rows only.Which tools moved.
get_analytics,get_sentiment_breakdown,get_shopping_visibilityandget_multi_language_analysisall count fewer answers than they did before 17 September 2026, and each now statestonePopulationin its response.get_snapshotsandcapture_snapshotdo not count anything, but every row they return carriessentimentMethod, andget_snapshots'sentimentfilter narrowed.get_shopping_visibilityalso gainsnotJudgedReasons: its per-rowsentiment: 'not_judged'token now covers four different facts — the answer named nobody, a word list wrote the verdict, nothing records how it was scored, or a judge scored it and stored no usable verdict — and those four counts sum to exactly the number ofnot_judgedrows. An existing field's VALUE moved there, not just its shape: a row the split no longer counts now readssentiment: "not_judged"where it previously reported the stored verdict — because a word list wrote that verdict, because nothing records how it was scored, or because the answer named nobody. Measured live on 17 September 2026, 154 of the 161 rows that move are the middle case, so most of the drop is missing provenance rather than a word list. ReadnotJudgedReasonsfor the split. The shape is additive; the values are not.get_multi_language_analysisgainsjudgedAvgSentiment, which isnullwhere the deprecatedavgSentimentreads0, and whose non-zero value also moved, because the mean's population narrowed with the counts; on a −1…1 scale 0 means "perfectly balanced", so a language whose every answer a word list scored used to report a balanced tone it never measured.What moves an answer out of the count. Two things, and only the first is what the measured figures above are made of: a verdict a word list wrote, and a row that does not record how it was scored at all. Over the 30 days those figures cover, all 98 dropped answers were word-list verdicts and none were missing-provenance rows — so the explanation above is complete for that window. It is not complete platform-wide: rows carrying no provenance key exist in older data and they stop counting too, for the same reason (silence is not a record that a judge did the reading).
Segment filtering: All analytics tools —
get_dashboard_metrics,get_analytics,get_sentiment_breakdown,get_entity_analysis,get_shopping_visibility,get_multi_language_analysis,get_visibility_forecast,detect_anomalies,analyze_citation_gaps, andgenerate_report— accept an optionalsegmentparameter (all,branded,non-branded, orcompetitor) to filter by prompt type. All REST API analytics endpoints also accept?segment=as a query parameter.
Prompts
| Tool | Description | Min Role |
|---|---|---|
list_prompts | List monitoring prompts for a project (includes topic) | viewer |
create_prompt | Create a new monitoring prompt. Optional building_block_ids links it to contexts of this project (active context ids, from list_building_blocks); a set with any other id is refused and nothing is written. Arguments outside this list are refused | member |
update_prompt | Update prompt text, type, topic, priority, active status, or question type (prompt_segment: branded / non-branded / competitor — a refiling is recorded as a reclassification of the tracked set). Optional building_block_ids replaces its context links, checked as on create_prompt; [] clears them. Arguments outside this list are refused | member |
delete_prompt | Soft-delete a monitoring prompt — hidden from analytics but capture history is preserved (30-day snapshot restore window). Org owner/admin only | admin |
discover_prompts | AI-assisted prompt discovery: generates up to 50 candidate prompts seeded from your brand, website, competitors, and existing prompts. Returns suggestions for review — nothing is auto-inserted. Spends LLM credits | admin |
fanout_prompt | Generate a query fan-out tree for a seed query — the sub-queries an answer engine expands a question into (reformulations, comparisons, follow-ups). Spends LLM credits | admin |
get_prompt_gaps | Competitive prompt-gap analysis: prompts and topics where competitors surface but your brand does not, ranked by gap score. Pass refresh=true to recompute from snapshot data (member role, no LLM spend) | viewer |
classify_intent | Classify search intent for prompts with the rule-based classifier and persist changed intents. No LLM spend | member |
estimate_volume | Estimate and persist relative search-volume scores (1-100) for active prompts from text heuristics + database signals. No LLM spend | member |
Page Analysis
| Tool | Description | Min Role |
|---|---|---|
analyze_page | Analyze a URL for AEO score (0-100) across 6 categories with improvement suggestions | admin |
Models
| Tool | Description | Min Role |
|---|---|---|
list_models | List available AI models from the dynamic registry, optionally filtered by provider | viewer |
Alerts
| Tool | Description | Min Role |
|---|---|---|
get_alerts | Surface active alerts — firings of your configured alert rules, statistical anomalies from the anomaly detector, and capture-health checks (your own thresholds, not hardcoded ones) | viewer |
list_alert_rules | List the configured alert rules for a project (rule type, threshold, active state, notify settings) | viewer |
create_alert_rule | Create or update an alert rule (one rule per type — re-creating a type updates it). Creatable measures: nb_transactional_mention_rate, nb_informational_citation_rate, brand_transactional_negative_share, brand_informational_own_source_share. The older names (visibility_drop, sentiment_negative, brand_not_mentioned, competitor_surge, rank_drop) are accepted only to switch an EXISTING rule off — nothing evaluates them any more. cooldown_hours spaces out the announcement, not the evaluation: 0–168 (one week). Org owner/admin only | admin |
delete_alert_rule | Delete an alert rule from a project. Org owner/admin only | admin |
get_answer_changes | Proactive answer-change and competitor-displacement events — brand dropped, competitor entered, sentiment shift, claim changed, citation displaced — with derived severity and a project-wide summary. Filter by prompt_id / change_type | viewer |
get_model_drift | Model-drift events the sentinel detected — a provider/model whose answer distribution shifted against its own baseline (pre/post mean, delta %, engine, first seen, severity). Newest first | viewer |
AI Analysis
| Tool | Description | Min Role |
|---|---|---|
run_analysis | Run AI-powered analysis: sentiment_drivers, content_gaps, opportunity_scoring, comprehensive | admin |
get_analysis_results | Retrieve completed AI analysis results for a project | viewer |
Criteria Map
| Tool | Description | Min Role |
|---|---|---|
get_criteria_map | Get the project's selection criteria: per tracked engine, the criteria that engine says define the best offering in your category/industry — gates, segment criteria and signals, each with a layer and an evidence quote — plus the gate-clearance table against your approved facts, and answer_use: what answers to your non-brand Hybrid questions reason with, measured over real answers | viewer |
run_criteria_derivation | Run the criteria-derivation battery: asks each tracked engine (one per provider, max 8) what defines the best offering in your category/industry, structures the answers, and upserts one criteria map per engine. Requires the project's Category + Industry settings; consumes one AI-analysis quota unit per run; refused, with nothing charged, when the platform has paused AI spending or the account cannot cover it | admin |
AEO Program
| Tool | Description | Min Role |
|---|---|---|
get_aeo_program | Get the project's AEO Program status: six projection-ladder rungs and five parallel work tracks, every status derived from existing stored signals (intelligence scores, GEO audit, criteria maps, citation-gap placement, coverage report, citation mix) — never computed on demand | viewer |
Scorecard
| Tool | Description | Min Role |
|---|---|---|
get_scorecard | Read the project's Scorecard: the same read as the Scorecard page, so the numbers match it. Optional basis (cohort, the default, or full) and scenario (conservative, base or stretch; the default is the one chosen at the lock). With no locked baseline it says so and names the months a lock may use. The sales figures behind Business impact are returned for owners and admins only; any other token gets it marked restricted | viewer |
Actions
| Tool | Description | Min Role |
|---|---|---|
list_actions | List insight actions (auto-generated from AI analysis or manual) | viewer |
update_action | Update an action's status (pending, in_progress, completed, dismissed) or notes | member |
Plan & Quotas
| Tool | Description | Min Role |
|---|---|---|
get_plan_info | Get organization plan, feature flags, quota limits, and current usage counts | viewer |
GEO Audit
| Tool | Description | Min Role |
|---|---|---|
run_geo_audit | Run a Generative Engine Optimization audit on a URL — scores 8 categories: schema, entity clarity, content depth, answer structure, trust signals, technical SEO, freshness, AI crawler access (incl. JS-dependency) | admin |
run_site_geo_audit | Site-level GEO audit: discovers the site's pages (sitemap → homepage links), audits up to the plan's page cap, aggregates category scores and adds site-wide checks. One quota unit per run | admin |
list_geo_audits | List past GEO audit results for a project | viewer |
GA4
| Tool | Description | Min Role |
|---|---|---|
get_ai_traffic | Get AI referral traffic data from Google Analytics 4 (sessions, users, pageviews from ChatGPT, Perplexity, Claude, Gemini) | viewer |
get_ga4_status | Check GA4 connection status for a project | viewer |
get_prompt_attribution | Prompt-level closed-loop attribution: joins AI-referral traffic (the GA4 "AI-Assistant" channel) to the prompt(s) whose AI answer cited each page — per (prompt, engine, cited URL) rows with fractionally-attributed AI-assisted sessions / conversions / revenue. Every number is a floor. Accepts the analytics lens params (segment, intent, journey, topic, tag, group_id, orbit). Requires Fusion Insights + GA4; aiRevenue redacted for member/viewer tokens | viewer |
GSC
| Tool | Description | Min Role |
|---|---|---|
get_search_performance | Get Google Search Console data (clicks, impressions, CTR, position) for top queries | viewer |
get_gsc_status | Check Google Search Console connection status for a project | viewer |
get_search_context | Map real Search Console queries to the prompts they relate to — EXACT (the query's landing page is a page this prompt's AI answers cite) and HEURISTIC (topic-matched, with relevance 0–1 and matched terms); the two are never summed. Per-prompt query lists, best position, totals. Accepts the analytics lens params. Requires GSC | viewer |
Webhooks
| Tool | Description | Min Role |
|---|---|---|
list_webhooks | List webhook endpoints registered for the organization | admin |
get_webhook_deliveries | Get recent delivery logs for a webhook endpoint | admin |
Citation Intelligence
| Tool | Description | Min Role |
|---|---|---|
get_citations | Get citation sources for a project with aggregated counts, category breakdowns, and per-engine mention-vs-citation split | viewer |
analyze_citation_gaps | Identify sources that cite competitors but not your brand — actionable outreach targets | member |
get_domain_authority | Get domain authority scores for citation sources (frequency, recency, cross-model presence) | viewer |
get_contribution_grid | Get the contribution grid: your citation mix mapped onto the framework's six external source families, with a presence/diversity verdict per family (absent / thin / present / concentrated) | viewer |
Crawler Intelligence
| Tool | Description | Min Role |
|---|---|---|
get_crawler_dashboard | The robots.txt access check — which AI crawlers your robots.txt allows or blocks, when it was last checked (recentLogs[].checkedAt), and what changed since the previous nightly check (patterns: new_bot, blocked, unblocked). Not crawl traffic: for what crawlers actually fetched, use get_ai_crawl_analytics. From 23 October 2026 the check time is checkedAt (it was lastCrawledAt, which was always the check time, never a crawl) and an unblocking is unblocked (it was frequency_change) | viewer |
analyze_robots | Analyze robots.txt and ai.txt for AI bot configuration with recommendations | admin |
get_ai_crawl_analytics | AI-bot crawl analytics from uploaded server access logs — per-bot hits with each bot's purpose (live_retrieval | search_crawl | training | robots_token | unknown; search_crawl is an AI search engine's own index crawler, its own class from 21 October 2026), purposeTotals kept as separate figures that are never summed, byOperator (hits per AI company, split by class), plus purposeTotals.otherKnown (purpose other_known: fetches by known crawlers that are not AI crawlers, such as OAI-AdsBot and Google-CloudVertexBot, left out of every per-bot row and AI figure), byPath (from 22 October 2026: the pages AI crawlers fetched most, up to 200, each with hits, distinct crawlers, the top crawler, the last fetch and the HTTP status counts; read over the same fetches as the AI figures, so with every page listed the pages' hits add up to totalEvents, and byPathTruncated is true when the site had more crawled pages than are listed), crawl→citation funnel with the lag's basis (lagBasisPages, citedBeforeLogsPages), daily trend. The stored kind (train/search) is the robots-guidance reading and is kept for compatibility. Pro Individual plan and above | viewer |
configure_crawl_log_source | Create or update the upload log source for a project (reuses the newest source of the given type). Run before uploading AI-bot access logs. Pro Individual plan and above | admin |
Content Intelligence
| Tool | Description | Min Role |
|---|---|---|
generate_faqs | Generate FAQ content from project prompts and brand facts (suitable for FAQ schema) | admin |
generate_schema_markup | Generate JSON-LD structured data for a URL using brand facts and page content | admin |
get_corrections | Get hallucination correction submissions (drafts, submitted, resolved) | viewer |
list_saved_faqs | The saved FAQs a project publishes to AI crawlers through Edge Delivery, in published order: each one's id, question and answer, whether you edited it (served as written, kept by every "Generate FAQs") and whether you removed it (not served, restorable), plus notServedReason (edge_off | faq_schema_off | null) when none is served right now. Every plan | viewer |
update_saved_faq | Change one saved FAQ's question and/or answer; it is then served exactly as written and kept by every later "Generate FAQs". Restore a removed FAQ first. Question at most 300 characters, answer at most 2,000 | member |
remove_saved_faq | Stop publishing one saved FAQ. It is kept, never served and never brought back by "Generate FAQs"; restore_saved_faq puts it back | member |
restore_saved_faq | Put a removed FAQ back into what Edge Delivery publishes; it stays yours, kept by every later "Generate FAQs" | member |
submit_correction | Hallucination-correction workflow: generate builds provider-specific correction-request templates from the issue context; create saves a draft correction submission | member |
generate_content_brief | GEO-method Content Brief for a target page: measures the four proven citation levers (expert quotations, statistics, cited sources, dated references) and returns the below-target levers to change, ordered by evidence weight, with an honest expected-lift estimate. Deterministic — no per-generation LLM cost. Persists a draft brief. Professional+ | admin |
get_content_briefs | List persisted Content Briefs (levers, gap summary, coverage, expected lift, status draft/applied/verified, linked action id), newest first | viewer |
Connectors
| Tool | Description | Min Role |
|---|---|---|
list_connectors | List registered connectors (Serper, DataForSEO, Slack, Looker, Zapier, Shopify) | admin |
create_connector | Create a connector for an organization. Counts toward the plan's connector limit; credentials are added in the dashboard afterwards | admin |
test_connector | Tests the connection by calling the connector's service. Slack and Zapier receive a real test event; Serper, Brave Search, YouTube, Google Knowledge Graph and Stack Exchange run one search that counts against the service's API quota | admin |
sync_connector | Run a full sync for a connector; returns the sync status and records synced | admin |
delete_connector | Delete a connector and its stored credentials | admin |
manage_connector | Deprecated, not listed in tools/list (still callable) — use create_connector, test_connector, sync_connector or delete_connector. Create, test, sync, or delete a connector | admin |
Predictive & Edge
| Tool | Description | Min Role |
|---|---|---|
get_visibility_forecast | Visibility forecast via Holt-Winters ensemble (level + trend + weekly seasonality) with bootstrap-calibrated 95% prediction intervals. Returns winning model, cross-validated RMSE/MAE/MAPE, coverage probability, Ljung-Box residual test, and confidence quality rating. Accepts optional segment parameter. | viewer |
detect_anomalies | Completeness-aware robust z-score anomaly detection (median/MAD) on visibility, sentiment, and mention-rate metrics. Skips partial-capture days (a day needs at least max(10, 80% of the full-day reference) snapshots, the reference read from the fuller capture days of the last 120 days; the result's coverage says per metric how many complete days there were and whether it was tested), excludes today, applies Benjamini-Hochberg FDR control across every tested point (all metrics pooled), marks persistent when the previous point also deviated notably. Accepts optional segment parameter. | admin |
get_benchmarks | Compare project visibility against a measured industry benchmark (percentile rank); with none measured yet, no numbers and a plain note | viewer |
Enterprise
| Tool | Description | Min Role |
|---|---|---|
get_audit_logs | SOC 2 compliance audit logs for an organization (user actions, data access, config changes) | admin |
get_revenue_attribution | Multi-touch revenue attribution: first_touch, last_touch, linear, time_decay, position_based | member |
Query Universe
| Tool | Description | Min Role |
|---|---|---|
list_building_blocks | List building blocks for a project grouped by category (Core services, Modifiers). Optional include_proposed also returns contexts proposed from the website that nobody has accepted yet; they are left out by default | viewer |
create_building_blocks | Create building blocks in a project from a blocks array (Query Universe feature and building-block limit apply) | member |
update_building_block | Update one building block (block_id, project_id and updates are required) | member |
delete_building_block | Delete one building block from a project (block_id and project_id are required). Org owner/admin only | admin |
manage_building_blocks | Deprecated, not listed in tools/list (still callable) — use create_building_blocks, update_building_block or delete_building_block. Create, update, or delete building blocks; the delete action requires admin | member |
compose_prompts | Generate prompt suggestions from building blocks (cap: 200). When questions per type are set, the types short of their number come first | viewer |
get_coverage_report | Get or regenerate Query Universe coverage report (dimension distributions, gaps, recommendations) | viewer |
seed_building_blocks | Seed building blocks from industry templates | admin |
get_orbit_model | Get the project's definition-orbit model: the four orbits (who-we-are, what-we-do, how-you-qualify, whom-we-serve), the block categories each maps to, per-orbit completeness, the identity record (canonical name, owner or "independent", what the brand makes), and the two registers a person keeps (inherited trust and the brand's own attributes, entered by hand) | viewer |
seed_orbit_blocks | Seed building blocks into one definition orbit's canonical block categories — same validation and plan gates as the building-blocks API | member |
backfill_prompts | Enrich existing prompts with enhanced classification (intent, journey stage, freshness, risk, SDS tier) | admin |
analyze_company_site | Discovery Autopilot: bounded crawl of the company's own site (up to 6 pages) plus one judge-pipeline extraction into a structured, evidence-quoted company profile for review. Consumes one AI-analysis quota unit; 5 analyses/hour per user; refused, with nothing charged, when the platform has paused AI spending or the account cannot cover it | admin |
Agent-driven onboarding walkthrough: call analyze_company_site for a project, present the returned profile to the user for confirmation (items without an evidence quote are confidence low — treat them as suggestions to verify, never facts, and never write a certification the user has not explicitly confirmed), then apply the confirmed items with the write tools: create_building_blocks (blocks), set_brand_facts (certifications as gate evidence), add_competitor, and update_project (category + industry business context). Finish with compose_prompts to generate query candidates from the confirmed universe.
Reports
| Tool | Description | Min Role |
|---|---|---|
generate_report | Generate an AEO report for a project. Supports multiple formats (PDF, slide PDF, Excel, CSV) and report types (executive, standard, comprehensive, competitive, custom, per_prompt, aeo_program — the board-ready define→project→credibility program story). Returns report ID, download URL, AI brand score, and letter grade. The score and grade are null when the window has no captures (insufficient_data) or when one of the score's inputs could not be loaded (score_not_loaded: true); sections_not_loaded lists each part that could not be loaded — section keys, plus coverage, cyclePeriod and competitivePosition. | admin |
get_report_history | Get report generation history for a project. Returns past reports with metadata, scores, and download URLs. A failed generation's error_reason reads "This report did not generate.", and its metadata.error is no longer returned (removed 2026-09-24; GET /api/reports/history does the same). | viewer |
get_report_download | Get a signed download URL for a specific report. URL expires after 1 hour. | viewer |
create_report_share | Create a shareable link for a report. Supports optional password protection, expiry, and comment permissions. | admin |
list_report_shares | List all shared report links for a project, including view counts and status. | member |
revoke_report_share | Revoke (deactivate) a shared report link. The link will no longer be accessible. | admin |
list_scheduled_reports | List recurring scheduled reports for the organization (cadence, recipients, timezone/send hour; channel secrets redacted). Org owner/admin only | admin |
create_scheduled_report | Create a recurring scheduled report delivered by email at a chosen local time (types: quick, executive, standard, comprehensive, competitive, per_prompt, aeo_program). Delivery channels stay dashboard-only. Org owner/admin only | admin |
update_scheduled_report | Update a scheduled report — pause/resume, recipients, cadence, timezone, send hour, or voice. Org owner/admin only | admin |
delete_scheduled_report | Delete a recurring scheduled report so it stops being sent. Org owner/admin only | admin |
Schedules
| Tool | Description | Min Role |
|---|---|---|
list_schedules | List recurring snapshot-capture schedules for a project (name, frequency, next run, active state) | viewer |
create_schedule | Create a recurring snapshot-capture schedule (daily/weekly/biweekly/monthly) across all active prompts and models. Nothing runs until the schedule's first due time; pass run_now: true to also enqueue one immediate first capture (spends credits now; default false) | admin |
delete_schedule | Delete a recurring snapshot-capture schedule for a project | admin |
Goals
| Tool | Description | Min Role |
|---|---|---|
list_goals | List visibility goals with milestones and pace status. Filter by status or segment. | viewer |
create_goal | Create a goal with auto-computed milestones. Supports 7 metrics across 4 segments. Returns feasibility assessment. | member |
update_goal | Update a goal's target, date, status, or notes. | member |
Insights
| Tool | Description | Min Role |
|---|---|---|
list_insights | List intelligence insights generated by computation engines. Filter by type (11 types), severity, or status. | viewer |
update_insight | Acknowledge, dismiss, or convert an insight to an action. | member |
Intelligence
| Tool | Description | Min Role |
|---|---|---|
get_intelligence_scores | Get all 6 intelligence scores: BNCI, CMCS, MEI, SDI, CIPS, ETAS. | member |
get_intelligence_summary | Get unified intelligence summary with KPIs, timeline, recommendations, and action counts. | viewer |
get_fusion_insights | Fuse AI visibility ↔ real traffic ↔ rank on your own page URLs. Returns a per-page fusion table + plain-language insights (cited-page→traffic, AI-vs-SEO divergence, AI-Overview share, first-party Google AI visibility from Search Console, social mention volume, …) with graceful degradation per connected source. Requires the fusion_insights feature (Professional+). Accepts optional segment. | viewer |
verify_action | Trigger scoped measurement for completed actions. Compares visibility before/after to measure real impact. Page-specific fusion actions also report the page's AI-referral sessions, Google position, and citation deltas. | admin |
Quick Audit
| Tool | Description | Min Role |
|---|---|---|
quick_audit | Run a 3-model brand check. The three engines are resolved from the live model registry, so the lineup follows your platform's current models rather than a fixed list. Reports whether each engine NAMES the brand in its answer, which is not whether it knows it — an engine that says it has never heard of a brand still names it — with an excerpt of each answering engine's opening lines so you can read what it said. percentage is the named rate over the engines that ANSWERED — null, never 0, when none did. Naming only — it does not score tone. An answer the engine cut off before it finished is marked cutOff: true on its model entry and counted as neither named nor not named (visibility.cutOff says how many). brand_name must be 2–80 characters: a longer name is refused as invalid arguments, where the web check instead cuts a name to 80 characters after cleaning it; a name carrying instruction-like phrasing is refused on both, and so is a name that, once cleaned, has fewer than 2 characters or no letter or digit. Each call, a cached answer included, counts toward its own hourly cap, the same size as your plan's captures-per-hour cap and separate from capture_snapshot's (see Rate Limits). | member |
A quick audit does not score tone (changed 17 September 2026): this tool reports whether each engine names the brand. It never ran the sentiment judge — but until this date it returned a tone regardless:
sentimentcarried the hardcoded string"neutral"on every answer that named the brand, identical for every brand and every answer, and the public web version of the same check scored a private seventeen-word list. An existing field's VALUE moved here, not its shape:sentimentis unchanged as a field and is now alwaysnull, with an additivesentimentBasisofnot_scoredon each model entry and a plain-languagesentimentBasisNoteon the payload. A caller that readsentimentas a verdict was reading a constant, not a measurement; for real tone useget_sentiment_breakdownorget_analytics, which are judge-scored over your tracked questions.
A quick audit reports over the engines that ANSWERED (changed 17 September 2026):
visibilitynow carriesansweredanderroredbeside the existingmentionedandtotal, and the percentage is computed overansweredrather than over the engines the audit tried.percentageis an existing field whose VALUE moved: it isnull— never 0 — when no engine answered, withreason: "engines_unreachable"and a plain sentence innote. Before this, three refused calls were published as{ mentioned: 0, total: 3, percentage: 0 }and cached for 24 hours, so a caller was told no engine mentions the brand when in fact none had been reached. A caller that branches onpercentagemust handlenulland must not coerce it to 0: the two mean different things.totalstill means the engines we tried, and there is deliberately noaskedfield repeating it. A run in which nothing answered is not cached, so the next call retries rather than being handed the same refusal.Caching: results are cached for 24 hours per brand. Before 17 September 2026 this tool's cache write violated a NOT NULL constraint and failed silently, so no result was ever reusable and every call ran three models afresh. The cached payload is now also checked against the surface that produced it, so this tool is never served a row written by the public web check, whose prompt and payload differ.
A quick audit reports NAMING, not knowing (changed 24 September 2026): an engine counts in
mentionedwhen its answer contains the brand name, and an answer that says "I don't have reliable information about Zorvane" contains it — so a made-up brand can be named by every engine. The count is unchanged; what changed is that the payload now says what it is.percentagekeeps its value: it is the named rate (mentioned÷answered,nullwhen nothing answered). The payload carries an additive top-levelnamingNote, the same sentence every screen prints. Each model'sexcerptis now the engine's opening lines — about 300 characters from the start of its answer, cut at a word boundary, with markdown emphasis and link syntax removed — for every engine that answered, named or not, andnullonly for an engine that did not answer. It used to be the first 200 characters untrimmed here and a window around the name on the web check, so an opening "I don't have reliable information about…" could be cut away. A call refused before any engine runs — the platform paused, the platform balance below its floor, a check that could not be completed, or an engine lineup that could cost more than a quick audit is allowed to — fails with one message,Quick audit is temporarily unavailable. Please try again later., whichever it was; it used to carry the refusing gate's internal detail. From the same datebrand_nameis cleaned the way the web check cleans it (control, format, bidi and zero-width characters removed, whitespace collapsed), the cleaned name is the one asked about, cached and returned, and it must be 2–80 characters before cleaning: the web check cuts a longer name to 80 characters after cleaning, this tool refuses it with an invalid-arguments error. A name that, once cleaned, has fewer than 2 characters or no letter or digit is refused on both. Each call, a cached answer included, also counts toward its own hourly cap, the same size as the plan's captures-per-hour cap and separate fromcapture_snapshot's. Results cached before this date, or under an earlier wording ofnamingNote, are recomputed on the next call rather than served.
A cut-off answer is neither named nor not named (changed 25 September 2026): each model entry carries an additive
cutOff: truewhen the engine ran out of output budget before it finished — the gateway'sfinish_reason: "length", or the provider's nativeMAX_TOKENS, read from the response and never inferred from the text. Such an entry hasmentioned: falseand sits outside both sides of the count.visibilitycarries an additivecutOffcount:percentageismentionedoveranswered − cutOff, and it isnull— withreason: "answers_cut_off"and a plain sentence innote— when every engine that answered was cut off, a different condition fromengines_unreachable. The output budget per engine now follows the model: an engine the model registry describes as reasoning, or has not yet described, is asked with 1,500 output tokens where it was a flat 200 here and 500 on the web check (gemini-3.6-flash spent 479 of 500 on reasoning and returned 65 characters of junk), and the lineup is priced at each engine's own budget before any call. A result in which any engine was cut off is not cached, so the next call runs the engines again.
Capture Runs
| Tool | Description | Min Role |
|---|---|---|
list_runs | List capture runs — the receipt for each capture pass: expected vs actual snapshot counts, status, duration, shape hashes, trigger, and label. Filter by status, run_type (scheduled, manual, backfill or historical_synthesis), prompt group or since. Dollar cost fields carry their figures for org owner/admin tokens only; other tokens get the same fields as null | viewer |
get_run | Get one run's full detail: the run row, its snapshots, per-engine completion, the prompt × engine completion matrix, same-shape run history, and the previous same-shape run for diffing. Dollar cost fields carry their figures for org owner/admin tokens only; other tokens get the same fields as null | viewer |
diff_runs | Diff two capture runs: full apples-to-apples when shape hashes match, intersection-only plus a shape-drift block otherwise. Per-cell deltas: brand mentions, sentiment, rank, snapshot count. expected_comparable is false when either run has no expected count — see the note below | viewer |
expected_snapshot_countcan benullonlist_runs,get_runanddiff_runs, since 2026-09-06. A run refused before it was sized — a paused organisation, or a credit gate, both of which stop the run before its fan-out is computed — has no expected count, and the field says so rather than reporting0. Zero is a different statement: it means the run was sized and had nothing to capture.A client that renders
actual / expectedshould print something like "not sized" for the null case rather than a fraction.diff_runscarriesexpected_comparable: boolean— false when either run has no expected count, because there is no delta to take against an absence. The per-celldiffscount what was actually captured and are unaffected.
A run cut short says why, per cause (added 25 September 2026): a run that captured fewer answers than it planned carries an additive
metadata.shortfallonlist_runsandget_run— one entry per cause, each{ count, reason }, withcountnullwhen the run was refused before it was sized. The causes aremodel_not_served(an engine whose model the registry no longer serves, skipped before any call, never charged, not counted against the allowance or the daily cap),provider_declined(the AI provider could not take the answers; nothing was charged),platform_capacityandplatform_pause(a platform-side pause),plan_cap(the daily cap, the included allowance or the pay-as-you-go cap) andprovider_error. Two more from 23 October 2026, both on a scheduled run that never started, withcountnull:start_failed(the platform could not start it; it is retried every hour and the cycle is kept) andempty_group(the schedule's question group has no active questions).reasonis the same plain sentence the Cycles pages print; nothing internal is in it.skipped_snapshot_countis themodel_not_servedcount on a run that ran; a run refused before it ran keeps the whole planned count there. Runs recorded before that date carry noshortfall. Nothing was renamed or removed.
Admin — Platform Owner
These tools are physically absent from the tool list for anyone who is not a platform owner — they never appear in tools/list for a normal customer token.
| Tool | Description | Min Role |
|---|---|---|
get_health_report | System health check across all platform components | platform_admin |
get_platform_stats | Platform-wide statistics — org/user/project/snapshot counts, 30-day usage + cost rollups, per-provider costs, daily trends, top users/orgs by cost | platform_admin |
platform_balance_check | Current OpenRouter balance, burn rate, and runway forecast | platform_admin |
platform_pause_org | Pause or unpause an organization's snapshot captures (args: org_id, action, duration_hours, reason) | platform_admin |
platform_top_orgs | Top organizations ranked by cost, token usage, and snapshot count | platform_admin |
platform_near_limit_orgs | Organizations approaching their plan limits (>80% usage on any dimension) | platform_admin |
platform_cost_intelligence | Per-org margin (revenue vs cost); optionally drill into one org for a project/user cost breakdown | platform_admin |
All platform-owner tools are only available to users whose email is listed in the PLATFORM_ADMIN_EMAILS environment variable.
Resources
Resources are read-only data endpoints your AI assistant can browse for context. Three are static; the other eight are templated by ID.
| URI | Description |
|---|---|
aeo://projects | List of all projects in your organization |
aeo://models | All available AI models grouped by provider |
aeo://rate-limits | Your organization's effective rate limits |
aeo://projects/{id}/summary | Project summary with key metrics |
aeo://projects/{id}/snapshots/recent | Last 10 snapshots for a project |
aeo://projects/{id}/competitors | Competitor list for a project |
aeo://projects/{id}/geo-audits | Recent GEO audit results for a project |
aeo://projects/{id}/ai-traffic | AI referral traffic summary for a project |
aeo://projects/{id}/actions | Pending insight actions for a project |
aeo://organizations/{id}/plan | Current plan, limits, and feature flags |
aeo://models/{provider} | Models from a specific provider |
Prompts
Prompt templates generate structured reports from your data.
| Prompt | Description | Arguments |
|---|---|---|
weekly_report | Weekly AI visibility report with trends, highlights, recommendations; engines are compared inside each question type (the blended LLM comparison is included for compatibility, marked not to rank on) | project_id |
competitor_analysis | Competitor comparison: share of voice, overlap, rankings | project_id, days? |
content_recommendations | Content improvement suggestions from snapshot analyses | project_id, limit? |
visibility_summary | Quick current-state summary with today's metrics and alerts | project_id |
geo_optimization | GEO optimization plan based on the latest audit results | project_id |
ai_traffic_analysis | Analyze AI referral traffic trends with growth strategies | project_id, days? |
Rate Limits
Rate limits are enforced per token and tiered by your organization's plan:
| Plan | Requests / minute | Requests / hour | Captures / hour |
|---|---|---|---|
| Free / Starter (baseline) | 60 | 1,000 | 10 |
| Pro-Individual | 60 | 500 | 5 |
| Pro-SME (and legacy Professional) | 120 | 2,000 | 20 |
| Enterprise-Brand (and legacy Enterprise) | 240 | 10,000 | 50 |
| Enterprise-Agency | 360 | 20,000 | 100 |
| Custom | 600 | 50,000 | 500 |
The per-minute and per-hour caps cover all tools (resource reads and prompt fetches count too); the captures cap applies to capture_snapshot, and quick_audit has its own hourly cap of the same size (from 24 September 2026 — before that quick_audit counted only toward the per-minute and per-hour caps). Unknown or missing plans fall back to the free-tier baseline — never a more permissive tier. The aeo://rate-limits resource advertises every tier's caps plus your org's effective limits, read from the same table the limiter enforces.
When rate limited, the tool returns an error with a retryAfterSeconds value.
Error Handling
Tool errors are returned as content with isError: true:
| Status Code | Meaning |
|---|---|
| 401 | Missing, invalid, expired, or revoked token |
| 403 | Insufficient role or cross-org access denied |
| 404 | Resource not found |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
When a tool fails because the data it reads could not be loaded, the error reads "We couldn't load this data just now. Try again in a few minutes." — never the database's own message. The same holds for a per-row error inside a successful result (set_brand_facts).
Audit Logging
Every tool call is logged for security and usage tracking:
- Who: Token, user, organization
- What: Tool name, input parameters (sanitized)
- When: Timestamp and duration
- Result: Success or error
Audit logs are viewable by organization admins.
Example Conversations
Check Mention Rate & Visibility Score
You: How is my brand doing on AI search engines today?
AI (calls
list_projectsthenget_dashboard_metrics): Over the last 30 days your brand "TechShu" has a 30% mention rate and a Visibility Score of 49/100 across AI search engines, with a sentiment score of 72%. Average rank position is 3.2, up from 3.5 in the prior 30 days.
Capture a Snapshot
You: Run a snapshot for my "best CRM software" prompt
AI (calls
list_promptsto find the prompt, thencapture_snapshot): Captured responses from 8 AI models. Your brand was mentioned in 3 out of 8 responses. Sentiment was positive in 2 and neutral in 1.
Weekly Report
You: Generate my weekly visibility report
AI (invokes
weekly_reportprompt): Here's your weekly report for TechShu AEO Tracking...
OAuth 2.1 Developer Reference
If you're building an MCP client or integration that needs OAuth (rather than static tokens), here are the technical details.
Discovery
Your client should first fetch the Protected Resource Metadata to find the authorization server:
Then fetch the Authorization Server Metadata:
Dynamic Client Registration
Register your client automatically (RFC 7591):
Redirect URIs must use HTTPS. In production, localhost and 127.0.0.1 redirect URIs are refused, as are private or internal hosts, URIs that carry a user name or password, and URIs with a fragment.
Authorization Flow
- Generate a PKCE code verifier (43-128 character random string) and its S256 challenge
- Redirect the user to the authorization endpoint:
- User logs in, sees the consent screen, picks their organization and role cap, and approves
- User is redirected to your
redirect_uriwith?code=AUTH_CODE
Token Exchange
Exchange the authorization code for tokens:
Response:
Refresh Tokens
When the access token expires, use the refresh token to get a new one:
Token Revocation
Revoke an access token or refresh token (RFC 7009):
Always returns HTTP 200, regardless of whether the token was valid.
OAuth Scopes
| Scope | What It Grants |
|---|---|
mcp:tools | Access to all MCP tools |
mcp:resources | Access to all MCP resources |
mcp:prompts | Access to all MCP prompt templates |
All three scopes are granted by default if no scope is specified.
Compatibility
| Platform | Auth Methods | Status |
|---|---|---|
| Claude.ai (web, desktop, mobile) | OAuth | Verified by AEO Optima Aug 18, 2026 (sign-in only) |
| Claude.ai with a fixed token (beta) | Token in a request header | Documented by the vendor, not verified by AEO Optima |
| Claude Code (CLI) | Bearer token | Documented by the vendor, not verified by AEO Optima |
| ChatGPT (developer mode) | OAuth | Documented by the vendor, not verified by AEO Optima |
| Grok (xAI API remote MCP tool) | Bearer token | Not documented by the vendor, not verified by AEO Optima |
| OpenAI Codex (CLI + IDE + desktop) | Bearer token | Documented by the vendor, not verified by AEO Optima |
| Cursor | Bearer token | Documented by the vendor, not verified by AEO Optima |
| Windsurf | Bearer token | Documented by the vendor, not verified by AEO Optima |
| VS Code + Copilot | Bearer token | Documented by the vendor, not verified by AEO Optima |
| Gemini CLI | Bearer token | Documented by the vendor, not verified by AEO Optima |
| Amazon Q Developer | See Amazon Q Developer's MCP guide | Not documented by the vendor, not verified by AEO Optima |
| OpenAI Agents SDK | Bearer token | Documented by the vendor, not verified by AEO Optima |
| Anthropic API | Bearer token | Documented by the vendor, not verified by AEO Optima |