MCP Server
Tool Reference
Complete reference for all 110 MCP tools available in the Surface MCP server
The Surface MCP server exposes 110 tools organized into 14 families. All tools are automatically scoped to your environment via your API key or OAuth connection.
A new connection loads the default forms bundle (the Forms, Responses, and AI Lead Scoring tools below). Add ?tools= to the server URL to load other families; see Tool Bundles.
Two things to know about the write tools:
- Form edits save a draft. Nothing a visitor sees changes until
publish_formpromotes the draft to live. - Schemas are discoverable at runtime.
list_component_typesanddescribe_component_typedocument every buildable component, andget_tool_schemareturns the full JSON Schema for the heavy authoring tools, so your assistant never has to guess a payload shape.
Forms
Create, edit, style, route, and publish forms.
| Use Case | Tool | Key Parameters |
|---|---|---|
| List all my forms with response counts | list_forms | page, limit, search, sortBy, sortOrder, dateRange |
| View a specific form's full configuration, questions, and styles | get_form | formId, source: "draft" | "live" (default draft) |
| Discover which components can go on a form step | list_component_types | None |
| Learn a component type's exact params (JSON schema + example) | describe_component_type | type |
| See a form's step/component outline with edit addresses | get_form_structure | formId, source: "draft" | "live", include: ["params"] for full component content |
| Get a plain-English narrative of a form to relay to the user verbatim | summarize_form | formId, source: "draft" | "live" (default draft) |
| Get the full JSON Schema for the heavy authoring tools | get_tool_schema | tool |
| Add a component to a step of an existing form | add_component | formId, stepId, type, params, placement |
| Change a component's question, choices, or required flag | update_component | formId, stepId, row, column, params, required |
| Remove a component from a step | remove_component | formId, stepId, row, column |
| Move or reorder a component (same step or across steps) | move_component | formId, from, to |
| Add a step (page) to a form, optionally with components | add_step | formId, name, index, endStepKind, components |
| Rename a step, mark it as thank-you/disqualified, or set a redirect | update_step | formId, stepId, name, endStepKind, redirection |
| Remove a step from a form | remove_step | formId, stepId |
| Reorder a form's steps | move_step | formId, stepId, toIndex |
| Browse Surface form templates (styling sources for create_form) | list_form_templates | kind, search |
| Find a Surface scheduler's id/booking link for a scheduler step | list_schedulers | includeInactive (default: bookable only) |
| Restyle a form with typed tokens (page fill, panes, layout, progress bar) | update_form_styles | formId, tokens |
| Restyle one component type (button colors, input borders, option styles) | update_component_styles | formId, componentType, styles |
| Style the WHOLE form in one call (palette, template, or another form's look) | apply_form_theme | formId, one of palette / templateId / sourceFormId |
| Branch a step on an answer, URL param, or known-lead signal | set_step_routing | formId, stepId, routing (null clears) |
| Apply several edits atomically in ONE call (all-or-nothing) | batch_edit | formId, operations (ordered { op, ...params } array) |
| Discover marketing (story) pane component types | list_marketing_component_types | None |
| Set the marketing pane's headline, bullets, testimonial, logos, FAQ | update_marketing_pane | formId, stepId (optional), components, replace |
| Edit ONE marketing component's text in place, keeping its styling | update_marketing_component | formId, stepId (optional), index, params, expectedType |
| Update a form's SEO metadata, tracking ids, language, or partial tracking | update_form_settings | formId, settings, confirm |
| Check a form is valid: references, dead ends, reachability, routing graph | validate_form | formId (draft/live) or config |
| Dry-run a visitor's answers and see the exact path and ending they reach | simulate_response | formId, answers: { questionId: value }, source: "draft" | "live" |
| Critique a form blueprint before building (gaps, open questions, readiness) | plan_form | request, styleIntent, steps ({ purpose, components?, routingIntent?, routing? }); loop until readyForCreate |
| Create a new form with steps, routing, and a styling source | create_form | name, steps (components as { type, params }), optional styling source (sourceFormId / templateId, designTokens alone or as overrides on either; omit for the stock theme), copyMarketing (default true), confirmed (first call echoes the plan; true creates, as a draft unless publishImmediately: true) |
| Publish a form so visitors see the latest draft | publish_form | formId |
Responses
| Use Case | Tool | Key Parameters |
|---|---|---|
| Get latest responses for a specific form | list_responses | formId, limit |
| Get responses for form X in a date range | list_responses | formId, dateRange: { from, to } |
| Get only completed (or only partial/abandoned) responses | list_responses | formId, finished: true | false |
| Filter responses by answer value (e.g. contains "enterprise") | list_responses | formId, filter: [{ type, filter, operator: "contains" }] |
| Full-text search across response data | list_responses | formId, search: [{ type, value }] |
| Get a single response with all answer data, notes, tags, and person info | get_response | responseId |
Leads
| Use Case | Tool | Key Parameters |
|---|---|---|
| List all qualified leads with attributes (email, name, company) | list_leads | page, limit, search, dateRange |
| Filter leads by source (form, website de-anon, webhook, HTML form) | list_leads | source: "surfaceForm" | "htmlForm" | "websiteDeAnon" | "webhook" |
| Get total count of qualified leads | get_leads_count | None |
| Break down lead count by source | get_leads_count | bySource: true |
| Break down lead count by funnel stage (visited, submitted, completed, meeting booked) | get_leads_count | byEventType: true |
| Import leads into the environment | import_leads | leads |
Analytics
| Use Case | Tool | Key Parameters |
|---|---|---|
| Get completion rate, dropoff analysis, email open rates, and top referrers for a form | get_form_analytics | formId, optionally dateRange |
| Get day-by-day response counts for a form | get_daily_form_stats | formId, optionally dateRange |
| Get daily environment-level metrics (visitors, leads, responses, workflow runs) | get_daily_stats | optionally dateRange (defaults to last 30 days) |
| See landing page performance (visitors, form starts, completions, meetings, conversion rate) | get_lead_source_analytics | page, limit, search, urls, dateRange |
| Get UTM and traffic source breakdown for a form (source, medium, campaign, AI referrers, click IDs) | get_user_journey_analytics | formId, optionally dateRange |
| Get per-URL conversion funnel (form starts → completed/partial → qualified/disqualified → meetings booked/not booked) | get_conversion_funnel | optionally dateRange, page, limit, url |
| Get a high-level overview of the environment (total forms, leads, responses, workflows) | get_environment_overview | None |
AI Lead Scoring
| Use Case | Tool | Key Parameters |
|---|---|---|
| Get the top (or bottom) responses and leads ranked by AI lead score | get_top_ai_scores | limit, order, formId, minScore |
| Get AI score statistics (average, min, max, distribution buckets) | get_ai_score_stats | optionally formId |
| Get responses for a form sorted by AI score | get_responses_with_ai_scores | formId, sortBy: "score", finished |
| Get leads ranked by AI score | get_leads_with_ai_scores | sortBy: "score", minScore, maxScore |
| Find responses containing a specific email, name, or answer text | search_responses | searchTerm, optionally formId |
| Compare forms by response count, completion rate, and average AI score | compare_forms | optionally formIds (omit to compare all) |
Workflows
| Use Case | Tool | Key Parameters |
|---|---|---|
| List recent workflow runs, filtered by response, lead, workflow, or success | list_workflow_runs | page, limit, sortOrder, responseId, leadId, workflowId, success |
| Get full details of a workflow run (per-step tasks, payloads, errors, timing) | get_workflow_run | runId |
AI Visibility
| Use Case | Tool | Key Parameters |
|---|---|---|
| List AEO/GEO answer-engine visibility reports (with PDF/DOCX links) | list_ai_visibility_reports | status, limit |
| Get a single visibility report's status and download links | get_ai_visibility_report | reportId |
| List all site profiles being tracked | list_ai_visibility_profiles | None |
| Get profile context, positioning, competitors, topics, and latest per-model scores | get_ai_visibility_profile | profileId |
| List tracked prompts with per-prompt visibility stats | list_tracked_prompts | profileId, category, topicClusterId |
| Audit longitudinal prompt/model/competitor evidence | get_tracked_prompt_history | profileId, optional prompt/category/model/date filters |
| Get daily visibility/coverage, model scores, and raw competitor mention rates | get_prompt_visibility_scores | profileId, startDate, endDate |
| See which domains AI models cite when answering prompts | list_cited_sources | profileId |
| Check if a scan is running, queued, or idle | get_scan_status | profileId |
| Trigger a new AI visibility scan | trigger_scan | profileId |
| Add a custom tracked prompt to a profile | create_tracked_prompt | profileId, text, categoryId |
Content Analytics
| Use Case | Tool | Key Parameters |
|---|---|---|
| List all tracked URL patterns | list_content_patterns | None |
| Get content performance dashboard with metrics and deltas | get_content_analytics | dateRange, compare |
| See AI traffic source breakdown (ChatGPT, Gemini, Claude, etc.) | get_ai_traffic_sources | dateRange |
| Add a URL pattern to track | create_content_pattern | pattern |
| Bulk import URL patterns (up to 500) | bulk_import_patterns | patterns |
| Auto-discover sub-pages from a prefix via sitemap crawl | discover_content_patterns | pattern (must end with *) |
| Remove a tracked pattern | delete_content_pattern | patternId |
Content Review
| Use Case | Tool | Key Parameters |
|---|---|---|
| List blogs with optional state/search filtering | list_blogs | state, search, page, limit |
| Get full blog details (title, state, author, blocks) | get_blog | blogId |
| List all version summaries for a blog | get_blog_versions | blogId |
| Get the rendered markdown content of a specific version | get_blog_version_content | blogId, versionId |
| List all content reviewers in the environment | list_reviewers | None |
| Create a new blog from pasted markdown | paste_blog | title, markdown |
| Update a blog's title | update_blog_title | blogId, title |
| Assign or clear a strategy cluster for a blog | assign_blog_cluster | blogId, clusterId |
| Quick-approve a blog's latest version | quick_approve_blog | blogId |
| Request changes on a blog (must be IN_REVIEW) | request_blog_changes | blogId, feedback |
| Publish or unpublish an approved blog | toggle_blog_publish | blogId |
| Archive or unarchive a blog (soft-delete) | archive_blog | blogId |
CMS
| Use Case | Tool | Key Parameters |
|---|---|---|
| List all content types with fields and entry counts | cms_list_content_types | None |
| Get a single content type by id or apiName | cms_get_content_type | contentTypeId or apiName |
| List entries with optional filters | cms_list_entries | contentTypeId, status, search |
| Get a single entry with draft and published data | cms_get_entry | entryId |
| Get an entry by content type and slug | cms_get_entry_by_slug | apiName, slug |
| List revision history for an entry | cms_list_entry_revisions | entryId |
| List uploaded assets (images/files) | cms_list_assets | page, limit |
| Get a single asset with signed download URL | cms_get_asset | assetId |
| Get a presigned upload URL (step 1 of upload) | cms_create_asset_upload_url | filename, mimeType, sizeBytes |
| Confirm an asset upload (step 2 of upload) | cms_confirm_asset_upload | storageKey, filename, mimeType, sizeBytes |
| Create a new content type | cms_create_content_type | displayName, apiName, kind |
| Update a content type's metadata | cms_update_content_type | contentTypeId, displayName |
| Delete a content type and all entries | cms_delete_content_type | contentTypeId, confirm |
| Add a field to a content type | cms_add_field | contentTypeId, displayName, type |
| Update a field's properties | cms_update_field | contentTypeId, fieldId |
| Remove a field from a content type | cms_remove_field | contentTypeId, fieldId, confirm |
| Reorder fields in a content type | cms_reorder_fields | contentTypeId, fieldIds |
| Create a new CMS entry | cms_create_entry | contentTypeId, data |
| Update an entry's data or slug | cms_update_entry | entryId, data |
| Publish an entry | cms_publish_entry | entryId |
| Unpublish an entry (back to draft) | cms_unpublish_entry | entryId |
| Archive an entry | cms_archive_entry | entryId |
| Delete an entry and its revision history | cms_delete_entry | entryId, confirm |
| Schedule an entry to auto-publish at a future time | cms_schedule_entry | entryId, scheduledFor |
| Cancel a scheduled publish (back to draft) | cms_unschedule_entry | entryId |
Environment & Admin
| Use Case | Tool | Key Parameters |
|---|---|---|
| Get team info, members, subscription, and billing | get_team_info | None |
| Create a new environment with a trial | create_environment_with_trial | name |
| Invite a new member by email | invite_member | email, role |
| Submit feedback about MCP tools | submit_feedback | type, message |