rampify
Rampify: the SEO MCP server that acts on your data Your website is your product.
What it can do
- List Projects: List all projects you have access to. Shows which project is currently active for this API key.
- Get Page Intelligence: Everything about ONE page in a single call: search performance (GSC), on-site traffic (pageviews/sessions/channels), AI-assistant visibility (ChatGPT/Claude/Perplexity fetches),
- Get Issues: Get all SEO issues for a site. Returns critical issues, warnings, and opportunities grouped by category.
What data it sees
Do you need an account
No: the server works without sign-in
Rampify: the SEO MCP server that acts on your data
Your website is your product. Ship it like one. Rampify brings your dev workflow to your website's search and AI-answer visibility, inside the coding agent you already use.
Most SEO MCP servers are read-only data faucets. Rampify does the whole job in one connection: it pulls the data, finds the gaps, writes the fix as a spec, and your agent ships it.
Batteries included: data and action in one server
You don't need to bolt on separate data servers. Rampify retrieves it for you:
- Keyword data (search volume, suggestions, clustering) via DataForSEO
- Google Search Console performance (impressions, queries, indexing)
- A live crawl of your own site (meta, schema, content, Core Web Vitals)
Then it acts: generate titles, meta, and JSON-LD schema grounded in that data, and open the PR.
Built for developers: track the work like you track code
What's unique is the feature spec system. Rampify turns findings into specs with affected URLs and tasks, then links the commits that resolve them, so marketing work has the same paper trail as your engineering:
create_feature_spec/create_spec_task: plan the changelink_commit: attribute the commit that shipped itget_commit_message: generate the message, spec trailer and all
Spec it, ship it, link the commit. The same workflow you already trust, pointed at the part of your product the world actually sees.
Find your blind spots
Discovery runs research as your buyer and shows where you're invisible when people ask AI assistants about your category, then turns the gaps into specs.
Zero install. Connect over OAuth from Claude Code, Cursor, VS Code, or claude.ai.
- Learn more: https://www.rampify.dev/mcp
- Connect: https://www.rampify.dev/docs/mcp/connecting
Server tool list (57)
Raw names from tools/list. Only developers need these.
| list_projects | List all projects you have access to. Shows which project is currently active for this API key. |
| get_page_intelligence | Everything about ONE page in a single call: search performance (GSC), on-site traffic (pageviews/sessions/channels), AI-assistant visibility (ChatGPT/Claude/Perplexity fetches), conversions, SEO health, keyword clusters, feature specs, campaigns, and change history. Requires a url_path or url_id. This is Rampify's flagship unified API — every metric Rampify knows about a single page, joined into one JSON blob, so you can reason about a specific URL end-to-end without multiple tool calls. For SITE-WIDE top pages/queries and search opportunities (not one page), use get_search_performance. Returns the complete PageIntelligence shape. Use the 'include' param to request a subset of sections for smaller responses. |
| get_issues | Get all SEO issues for a site. Returns critical issues, warnings, and opportunities grouped by category. |
| crawl_site | Crawl the entire site to discover pages and check SEO. Finds URLs from sitemap or navigation links. domain and project_id are optional overrides; otherwise uses the configured project. |
| scan_page | Scan a page for SEO data, keyword audit, and content analysis. Two modes: - **Deployed:** Just pass url_path. Fetches the live page, runs the full audit, saves results to Rampify. - **Pre-deploy:** Pass url_path + content (raw text or HTML). Runs the same keyword audit on the provided content without deploying. Useful for drafts composed in conversation, file content read from a connected codebase, or HTML fetched from a staging URL via WebFetch. The url_path must match a keyword cluster's target_url for keywords to be resolved. |
| generate_meta | Generate optimized meta tags (title + description) for a page. Deterministic template generation (no LLM): it delegates to generate_title and generate_description, so every returned draft is keyword- and length-validated — the target keyword and SERP length are guaranteed. `recommended` is the top validated draft per field (or null when none passes constraints), and `title_candidates` / `description_candidates` list the rest. These are validated DRAFTS to refine, not final copy — polish the wording yourself using the returned `business_context`. Accepts page content (text drafted in conversation, file content from a connected codebase, or HTML via WebFetch); without it, falls back to a live fetch + stored meta + target keywords (medium confidence). If no keyword cluster is mapped to the URL, it falls back to the page's top Search Console query as the target so it can still generate — the response's `keyword_source` is then `gsc_query`; mention this and offer to map a keyword cluster for ongoing optimization. Best paired with codebase access so the chosen draft can land directly in the page source. |
| github_open_meta_pr | Open a GitHub pull request that updates a page's title and/or meta description. Rampify never commits to the default branch directly — it drafts a reviewable PR a human merges. WRITE tool: it commits to a new branch and opens a PR (no reads). Requires the project's repository to be connected (Settings → Connect GitHub) and the URL to map to an MDX file; otherwise it declines with a structured `reason` (e.g. no_integration, no_mapping, unsupported_file) telling you what to do, rather than erroring. Pair it with generate_meta: draft and refine the copy first, then open the PR for the version you approve. Returns the opened PR's number and URL. |
| generate_title | Generate title tag candidates that provably satisfy explicit constraints. Deterministic template-based generation (no LLM) + rule validator. Every returned candidate is guaranteed to include every must_include keyword (case-insensitive), retain every must_retain keyword already in the current title (prevents ranking regression), and fit within the length bounds. If no candidate meets all constraints, the tool refuses to return any — it surfaces rejected candidates with reasons instead. Never returns a title it cannot prove is safe. Accepts page content as primary input (raw text or HTML); falls back to stored meta + live URL fetch when content not provided. Defaults: must_include = primary target keyword for the URL; must_retain = target keywords already present in the current title. |
| generate_description | Generate meta description candidates that provably satisfy explicit constraints. Deterministic template + rule validator. Every candidate is guaranteed to include must_include keywords and retain must_retain keywords already in the current description (prevents ranking regression). Refuses to return what it can't prove is safe. Defaults to 110-160 chars (SERP snippet fit). Accepts content as primary input (raw text or HTML); falls back to stored meta when content not provided. |
| generate_schema | Generate JSON-LD schema markup for a page. Accepts page content as primary input (text or HTML) for accurate schema-type inference and metadata extraction; falls back to URL path + stored meta when content not provided. Returns the schema block as a recommendation — best paired with codebase access so the markup can be inserted directly into the page source. |
| get_search_performance | Site-wide Google Search performance: your top-ranking PAGES and QUERIES by clicks/impressions, plus CTR/ranking OPPORTUNITIES and content recommendations — aggregated across the whole site (no single-page input). For everything about ONE page across all data sources, use get_page_intelligence. |
| create_keyword_cluster | Create a strategic keyword cluster with its keywords in a single call. Each cluster groups related keywords sharing search intent and serves as a content brief. Always include the keywords array — keywords that don't exist yet are auto-created as target keywords. Returns keywords_assigned and keywords_created counts. |
| get_keyword_clusters | Retrieve keyword clusters with keywords, volume data, GSC performance, and audit status. Supports filtering by target_url (exact match), name (partial match), or cluster_id. Without filters, returns all clusters. Use target_url to find the cluster for a specific page (e.g., target_url: "/" for the homepage cluster). |
| create_content_spec | Create a page-type feature spec linked to a keyword cluster. The spec carries content strategy; keyword data is resolved dynamically from the cluster. Use this after creating keyword clusters to generate actionable content briefs. |
| lookup_keywords | Look up search volume, competition, CPC, and monthly trends for keywords using DataForSEO. Results cached 30 days. Incurs ~$0.075 in DataForSEO API charges per call regardless of keyword count. |
| suggest_keywords | Get related keyword suggestions for a seed keyword using DataForSEO. Incurs DataForSEO API charges per call. |
| optimize_content | Run a deterministic keyword audit and return specific fix instructions (add keyword to title, increase density, add internal links, etc.). Accepts page content directly for pre-deploy or chat-drafted audits — when content is provided, skips the live fetch and audits the provided content against the keywords mapped to the given URL. Without content, fetches the deployed page and runs the audit on live HTML. Resolve url_id via get_page_intelligence (returned at url.id). |
| create_feature_spec | Create and save a feature specification to Rampify. Always include tasks to break the work into concrete steps. Pass status='idea' for captured-but-not-committed work that should stay out of the default "what's next" queue. |
| update_keyword | Update a target keyword's tier, cluster assignment, or target URL. Accepts a single keyword_id or a batch via keyword_ids. At least one of tier, cluster_id, or target_url must be supplied. Setting tier='primary' auto-demotes the previous primary in the same cluster. Pass cluster_id: null to move a keyword to unclustered. Resolve keyword IDs via get_keyword_clusters. |
| remove_keyword | Soft-delete a target keyword. Accepts a single keyword_id or a batch via keyword_ids. Resolve keyword IDs via get_keyword_clusters. |
| get_feature_spec | Fetch one feature spec by UUID with full nested detail (tasks, criteria, related commits). To find a spec by name or other criteria, use list_feature_specs with the search filter. Pass include[] to trim the payload to only the sections you need. Valid section names: 'tasks', 'criteria', 'commits', 'description', 'ai_context_summary'. When include is omitted, every section is returned (back-compat). When provided, omitted sections are nulled out (description, ai_context_summary, related_commits) or returned as empty arrays (tasks, criteria). For triage workflows, use include: ['tasks'] to skip the long description and criteria — typically saves 60-80% of payload size. |
| list_feature_specs | List feature specs for a project with rich filtering. Use search to find specs when you only remember part of the title or description; use status/priority/feature_type/tags/assigned_to/source/module to slice. summary_only=true returns a slim shape (id/title/status/priority/next_action/tags) — much cheaper for scanning many specs. Pagination: response is { specs, page: { limit, offset, has_more, total_count } }. Walk all specs in chunks: let offset = 0; while (true) { const r = await list_feature_specs({ summary_only: true, limit: 50, offset }); // ...consume r.specs if (!r.page.has_more) break; offset += r.specs.length; } |
| update_feature_spec | Update spec body fields: title, description, status, priority, feature_type, tags, tech_stack, affected_files, ai_context_summary, assigned_to, depends_on_specs, next_action. Tasks and criteria are managed via create_spec_task / update_spec_task / delete_spec_task and create_spec_criterion / update_spec_criterion / delete_spec_criterion. Source-pipeline fields (module, severity, source_action_type, source_scan_id) are owned by scan generators and cannot be changed here. |
| create_spec_task | Add one or more tasks to a feature spec. Pass task for a single insert or tasks for a batch. |
| update_spec_task | Update a task on a feature spec. Single mode: pass task_id with at least one of status, title, description, task_type, files_to_modify, code_snippet. Batch mode: pass tasks (array of {task_id, status}) to update multiple task statuses at once. spec_id is optional — resolved from task_id when omitted. |
| delete_spec_task | Remove a task from a feature spec. Pass task_id for single deletion or task_ids for batch. spec_id is optional — resolved from task_id when omitted. |
| create_spec_criterion | Add an acceptance criterion to a feature spec. |
| update_spec_criterion | Update an acceptance criterion on a feature spec. spec_id is optional — resolved from criterion_id when omitted. |
| delete_spec_criterion | Remove an acceptance criterion from a feature spec. spec_id is optional — resolved from criterion_id when omitted. |
| list_campaigns | List marketing campaigns for the project. Each campaign has tracked links with unique rid codes for attribution. |
| create_campaign | Create a marketing campaign. The campaign name is auto-generated from channel, source, and date (e.g., "Social / LinkedIn / Apr 2026"). Use create_tracked_link next to generate tracked URLs for the campaign. |
| create_tracked_link | Generate a tracked link for a campaign. The server creates a unique rid code and returns the complete URL. Use this URL in content — never construct tracking URLs manually. Idempotent: same campaign + destination returns the same link. destination_path must match an existing URL in the project (one that has been crawled or added). Use crawl_site or list URLs first if you're unsure what's available — the call will fail with a list of valid paths if you guess wrong. |
| save_campaign_content | Save content created for a campaign. Stores the copy alongside the campaign for performance tracking, A/B testing, and as reference for future content creation. For LinkedIn (and other platforms with multiple accounts), pass posting_account to tag the draft as 'personal' or 'company' so voice/audience can be filtered later. Without this hint, drafts land 'unspecified' and the user has to tag them in the UI. |
| get_top_campaign_content | Get top-performing CAMPAIGN marketing content — the copy (tone, structure, messaging) that drove the most clicks in past campaigns, to reference when creating new campaign content. This is marketing campaign copy, NOT website pages: for top website PAGES by traffic use get_search_performance, or get_page_intelligence for a single page. |
| get_campaign_performance | Get traffic performance data for a campaign. Returns clicks, top pages, devices, and countries for the specified period. |
| link_commit | Link a git commit SHA to a feature spec, optionally to a specific task. Creates traceability: code → commit → task → spec. Parses Task: <uuid> and Spec: <url> trailers from commit_message when task_id / spec_id aren't passed explicitly. When task_id is omitted and the spec has open tasks, the response includes a top-level warning: "spec_only_attribution" with a warning_message explaining the gap and an open_tasks array listing candidates. Spec-only linking is legitimate for architecture work and multi-task refactors but should be the exception — always pass task_id when one task drove the commit. |
| get_commit_message | Generate a conventional-commits-style message from spec/task context. Derived from structured spec data — no external AI call needed. Includes Spec: and Task: trailers per the project workflow convention. When task_id isn't passed but the spec has exactly one in-progress task, that task is auto-suggested (its title becomes the subject, its UUID becomes the Task: trailer, and suggested_task_id is surfaced in the response so the next link_commit call can use it). When multiple in-progress tasks exist, the response includes in_progress_tasks so the caller can pick. |
| create_product | Create an additional product on a project. Every project already has a default product (auto-created with the company name). Only call this when the founder explicitly wants to track a distinct second/third/etc. product separately — most companies are single-product. Returns the new product row. Slug is derived from name (lowercase, non-alphanumeric → hyphens) when omitted. Slug must be unique per project. |
| update_product | Update one or more products' identity (name, slug) and scalar positioning fields (category_phrase, one_liner, primary_cta, tagline, tech_stack_category). Single mode: pass product_id. Batch mode: pass product_ids — the same field updates apply to every product in the list. Updating a scalar positioning field flips its field_meta entry to source='user_edited' (highest trust), clearing any prior agent_inference / legacy_inference provenance. Cannot toggle is_default via this tool. Setting a different product as the default isn't supported through the MCP yet. |
| delete_product | Delete a product. Refuses to delete the default product (is_default=true) — promote another product to default first. research_sessions.product_id is ON DELETE SET NULL via the FK constraint, so any Discovery sessions previously scoped to this product become project-default-scoped after delete. Use list_products first to confirm the product_id and is_default flag. |
| list_products | List the products configured for a project. Every project starts with a single default product named after the company; founders can add more from the Products section in the profile UI (or via create_product) only if they want to track multiple distinct products separately. Returns each product's id, name, slug, is_default flag, and the populated positioning fields. Use product_id from this response when calling start_discovery or other tools to scope them to a specific product. |
| get_business_profile | Get the business profile for the current project with completeness score, phase status, and guidance on what to fill next. Use this as the starting point for both full onboarding conversations and ad-hoc profile updates. Returns current field values, which phases are unlocked, and the next recommended section to complete. The profile has 4 progressive phases: - Phase 1 (Foundation): Industry, business model, company stage, elevator pitch, geography - Phase 2 (Strategy): Goals, target audience personas, competitive landscape - Phase 3 (Voice & Content): Brand voice (from writing samples), content strategy, business narrative - Phase 4 (Revenue): Revenue assumptions for traffic projections |
| update_business_profile | Update one or more business profile fields. Supports both section-based updates (during onboarding) and individual field updates (ad-hoc). Pass a section name to update all fields in that section at once, or pass individual field key-value pairs. The profile is auto-created if it doesn't exist yet. Sections: business_identity, geography, goals, audience, competitive, brand_voice, content_strategy, narrative, revenue_assumptions Phase prerequisites are soft — the tool will warn but still apply updates for ad-hoc edits. Returns the updated completeness score and any newly unlocked phases. ## JSONB field shapes (get these right on the first try) Several fields are structured JSONB. Field names below match the live schema exactly — extra keys are silently dropped by validation, missing required keys reject the whole write. Inner arrays must be arrays, not comma-separated strings. `audience_personas`: array of objects. Required: `label`. Use `label`, NOT `name`. ``` [ { "label": "Frontend engineer at Series-A", "role": "IC engineer", "pain_points": ["doesn't own SEO", "doesn't trust marketing team's tooling"], "search_behavior": "searches in terminal, evaluates on docs quality", "decision_factors": ["runs in-terminal", "integrates with git workflow"], "is_buyer": false } ] ``` `competitors`: array of objects. Required: `domain`. Use `domain` (NOT `url`); `strengths` and `weaknesses` are arrays of strings (NOT single strings). ``` [ { "domain": "tryprofound.com", "name": "Profound", "why_they_compete": "Both target AI-search visibility for B2B SaaS", "strengths": ["enterprise focus", "established brand"], "weaknesses": ["per-prompt pricing", "no developer workflow"], "dismissed": false, "source": "agent" } ] ``` Only list brands literally named on the target site or surfaced by `research_competitors`. Do NOT invent. `voice_analysis`: object. `tone` is an array of strings (NOT a single string). Inner array fields are `dos` and `donts` — plural with no apostrophe. ``` { "tone": ["direct", "developer-first", "no-fluff"], "formality": "conversational", "dos": ["be specific", "cite sources"], "donts": ["marketing fluff", "vague claims"], "summary": "Reads like a senior engineer talking to peers." } ``` `formality` is one of: `casual`, `conversational`, `professional`, `academic`. `voice_samples`: array of objects. Required: `content`. Use `content` (NOT `excerpt`). ``` [ { "content": "Full excerpted text of the writing sample…", "source_url": "https://example.com/blog/post", "source_label": "Blog post — March 2026" } ] ``` `primary_goals`: Strategic Goals object — a single `active` goal plus an `archived` array. `active` is null or a goal object. `kind` is one of: acquire_first_customers, acquire_more_customers, defend_position, expand_categories, expand_geographies, increase_retention. `horizon` is one of: this_quarter, this_year, long_term. To set the active goal, send just `active` (archived defaults to []). ``` { "active": { "kind": "acquire_more_customers", "detail": "Grow paid pilots ahead of the Q3 launch", "horizon": "this_quarter", "success_metric": "3 qualified demos per month" }, "archived": [] } ``` `primary_content_types`: array of strings. ``` ["blog_post", "landing_page", "guide"] ``` If a call fails with shape errors, the response lists the specific shape_errors — fix and retry. |
| research_competitors | Discover competitors for the current project by crawling the site and analyzing keyword overlap. Returns structured competitor candidates with strengths and weaknesses. Performs multiple external HTTP fetches; runtime up to ~30 seconds. Process: 1. Fetches the project's existing pages and keyword data 2. Identifies domains ranking for the same keywords 3. Crawls competitor homepages to extract positioning, strengths, and weaknesses 4. Returns candidates |
| send_feedback | Submit feedback (positive, negative, suggestion, or confusion) to the Rampify team. Captures tool context, user goal, and conversation summary alongside the feedback type. |
| suggest_next_action | Answer "what should I work on next?" with ranked, scored opportunities. Returns items sorted by score (expected clicks per minute of work), filtered by time budget, autonomy preference, opportunity type, and confidence threshold. Each option includes rationale and the MCP tool + params needed to start work. By default the response is scoped to the project's current launch phase (Pre-Launch, Initial GSC Submission, Indexing & Visibility, Public Launch, or Growth & Optimization) — opportunities that don't apply to the current phase are filtered out. Pass launch_phase to override, or launch_phase="all" to see everything regardless of stage. Default behavior: only human-involved work is recommended (decisions + reviews). Agent-autonomous items are excluded from the default because the agent should execute those, not recommend them. Pass autonomy="agent" to see autonomous work, or autonomy="any" to see everything. Scoring rubric: Reach × Impact × Confidence / Effort. See docs/specs/23-opportunity-ranking.md. |
| start_discovery | Start a Discovery research session. Returns the first next_action for the session. Discovery is a multi-step research flow: each call returns a next_action that names the matching submit/record tool to call after producing the result. The lifecycle is: 1. start_discovery → returns the first next_action. 2. For each next_action, produce the requested output, then call the matching tool from this set: - enrich_profile → discovery_submit_profile_enrichment - clarify → discovery_submit_clarify_answers - generate_prompts → discovery_submit_prompts - spawn_subagents → discovery_submit_subagent_results - file_feature_spec → create_feature_spec, then discovery_record_filed_spec - derive_keywords → derive_keyword_clusters, then discovery_record_keywords_derived 3. Each submit/record tool returns the next next_action. Continue until next_action.kind === 'done'. 4. get_discovery_action is a read-only re-fetch — useful after a crash or to inspect a session, but normally not needed because submit/record returns the next action directly. Templates (pass the slug; display names in parens are what users say): - category_visibility — "Category Visibility Check." Does my brand come up when someone asks about my category? - comparison_readiness — "Comparison Readiness." Am I in the consideration set when buyers are narrowing? - scenario_surfacing — "Scenario Surfacing." Do I surface when real problems come up? - developer_workflow — "Developer Workflow." When an engineer asks Claude Code (or similar) how to implement, do I get recommended? - narrative_audit (advanced) — "Narrative Audit." What does the LLM know about me from memory? - market_opportunity — "Market Opportunity." Different kind of session: not "where does my brand surface" but "what's the shape of my market and where's the angle/wedge to exploit?" Outputs a strategic positioning spec, not a content recommendation. Works with or without an established brand. The template arg is optional. When omitted, the tool either auto-runs a single eligible template or returns a structured error listing the options. |
| get_discovery_action | Get the current next_action for a Discovery research session. Read-only — does not persist phase or status changes. Used to re-fetch the current action after a crash or to inspect a session without advancing it. Each submit/record tool returns the same shape, so calling this between actions is usually unnecessary. |
| discovery_submit_profile_enrichment | Submit profile-enrichment results from the agent during a Discovery session. Used when get_discovery_action returns a next_action of kind "enrich_profile". Saves the supplied fields to the project's business profile, marked as agent-inferred so the user can review them later, and returns the next next_action. |
| discovery_submit_clarify_answers | Submit user answers to a clarify next_action during a Discovery session. Used when get_discovery_action returns a next_action of kind "clarify". Saves the answers to the project's business profile, marked as user-confirmed since the user answered directly, and returns the next next_action. |
| discovery_submit_prompts | Submit the prompts generated by the agent during a Discovery session. Used when get_discovery_action returns a next_action of kind "generate_prompts". Server enforces the template shape (counts per kind). On success the prompts are persisted as research_queries and the next next_action is returned. |
| discovery_submit_subagent_results | Submit subagent answer + extraction results during a Discovery session. Used when get_discovery_action returns a next_action of kind "spawn_subagents". For each result the server persists a research_response, citation rows, and indexation snapshots for self-domain citations. Idempotent — queries with existing responses are skipped. |
| discovery_record_filed_spec | Record that the agent has filed a feature_spec during a Discovery session. Used when get_discovery_action returns a next_action of kind "file_feature_spec" and the agent has called create_feature_spec to file the spec. Updates the session's plan_snapshot and returns the next next_action. |
| discovery_record_keywords_derived | Record that the agent has run derive_keyword_clusters during a Discovery session. Used when get_discovery_action returns a next_action of kind "derive_keywords" and the agent has called derive_keyword_clusters. Updates the session's plan_snapshot and returns the next next_action. |
| derive_keyword_clusters | Turn Discovery findings + business profile into a pre-clustered Keywords tool entry. Can also be called standalone with `source_type: "homepage"` to seed Keywords without a Discovery session. ## What you pass in **`keywords_by_bucket`** — 5-12 keywords per bucket across up to all 5 Discovery buckets. Aim for ~30-50 keywords total. Pre-group by intent. Category-level keywords only; no brand names. Bucket meanings: - `discovery` — category-level pre-purchase (what prospects search before knowing brands) - `comparison` — "X vs Y", "best X", "alternatives to X" - `validation` — "does X work", "is X worth it", "X reviews" - `objection` — pricing/risk pushback, "cheaper X", "build in-house" - `troubleshooting` — problem-framed after-purchase ## What the tool does 1. Validates project access 2. Checks the DataForSEO cost cap for the month (refuses if over) 3. Makes ONE batched DataForSEO search-volume call for every keyword passed 4. Creates 5 keyword_clusters (one per bucket) with provenance tagged to the session (or "homepage") 5. Persists keywords under each cluster with their live volume data ## Output Returns cluster IDs + per-bucket counts + total DataForSEO cost used. If the monthly budget is exceeded, returns `{ over_cap: true, spent_usd, cap_usd }` with current spend. |
| list_research_sessions | List Discovery research sessions for a project, most recent first. Returns each session's id, plan_id, status, started_at/completed_at, and aggregate metrics (mention_rate, citation_rate, refusal_rate, blocker_count, query_count, response_count). |
| get_research_session | Get detail for a Discovery research session. By default returns a summary: session metadata, per-bucket query counts and response counts, and per-domain citation aggregates. Pass detail: "full" to inline every response with its citations and indexation snapshots — note the response can grow to multiple MB for long-running sessions. |