Koskamo

Moatlight MCP

An official MCP server provided by Moatlight that allows AI agents to measure AI search visibility by starting reports, reading results, and viewing ranked plans of changes to improve how ChatGPT and Google AI Overview describe a business.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Moatlight MCP logo, by MoatlightVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-06Operated by Moatlight
You need:Your own reports, the dashboard and onboarding require an account because they hold a customer's datathe free plan covers every endpoint except agent readiness, which needs the Early Access pass
MCP endpoint (Streamable HTTP)
https://www.moatlight.com/mcp
Vendor documentation

What its tools do

13 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

13 of 13 have a description · 13 of 13 declare behavior hints · 13 of 13 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to moatlight.com ·
  • Passed Endpoint is on the registry namespace domain ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Start a report for a website and read summary visibility numbers
  • Read finished reports to identify competitors named by AI
  • View ranked plans of changes to improve AI search visibility
  • Run agent readiness scans for websites with the Early Access pass

Source and maintenance

Vendor evidenceRegistry 1.1.0
Maintenance checked

Protocol and capabilities

Server
moatlight 1.1.0
MCP protocol negotiated in check
2025-11-25
Tools
13 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Moatlight measures whether ChatGPT and Google AI Overview name a business. Public tools need no login. Report tools need the user to sign in with OAuth; the free plan allows one website and one report every 30 days, so start a report only when the user asks. Agent readiness tools need the Early Access pass, which a person must buy in a browser.

Tools

13 advertised

get_product — What Moatlight does and when to use it
Advertised by the server during the last successful anonymous check.
Advertised read-only

Facts about the product: what it does, who it is for, what it does not do, and how an agent can use it. No login. No login needed.

get_product input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "fields": {
      "type": "string",
      "maxLength": 200,
      "description": "Comma-separated top-level fields to return, for example fields=id,stage. Omit to get everything. Spend fewer tokens by asking for less."
    }
  }
}
get_product annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_pricing — Plans and prices
Advertised by the server during the last successful anonymous check.
Advertised read-only

The free plan and the one-time Early Access pass: price, what each includes, refund window. Payment needs a person in a browser. No login. No login needed.

get_pricing input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "fields": {
      "type": "string",
      "maxLength": 200,
      "description": "Comma-separated top-level fields to return, for example fields=id,stage. Omit to get everything. Spend fewer tokens by asking for less."
    }
  }
}
get_pricing annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_faq — Frequently asked questions
Advertised by the server during the last successful anonymous check.
Advertised read-only

Every FAQ question and answer from the home page, paged. No login. No login needed.

list_faq input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "limit": {
      "type": "integer",
      "maximum": 50,
      "minimum": 1,
      "description": "Items per page, 1 to 50. Default 20."
    },
    "cursor": {
      "type": "string",
      "maxLength": 500,
      "description": "Opaque cursor: send next_cursor from the previous page unchanged. Omit for the first page."
    }
  }
}
list_faq annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_sample_report — A finished sample report on made-up data
Advertised by the server during the last successful anonymous check.
Advertised read-only

Shows the shape of a real report (visibility numbers, rivals, ranked plan) for a fictional coffee roaster. Made-up data, no login. No login needed.

get_sample_report input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "fields": {
      "type": "string",
      "maxLength": 200,
      "description": "Comma-separated top-level fields to return, for example fields=id,stage. Omit to get everything. Spend fewer tokens by asking for less."
    }
  }
}
get_sample_report annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_account — The signed-in user, plan and limits
Advertised by the server during the last successful anonymous check.
Advertised read-only

Returns the user's plan (free or early_access), when the pass ends, what the plan allows, and how to upgrade. Needs login with scope account:read.

get_account input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "fields": {
      "type": "string",
      "maxLength": 200,
      "description": "Comma-separated top-level fields to return, for example fields=id,stage. Omit to get everything. Spend fewer tokens by asking for less."
    }
  }
}
get_account annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
list_reports — List the user's reports
Advertised by the server during the last successful anonymous check.
Advertised read-only

The user's reports, newest first, paged with a cursor. Each has its stage (analyzing, needs_confirmation, running, finished, failed). Needs login with scope reports:read.

list_reports input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "limit": {
      "type": "integer",
      "maximum": 50,
      "minimum": 1,
      "description": "Items per page, 1 to 50. Default 20."
    },
    "cursor": {
      "type": "string",
      "maxLength": 500,
      "description": "Opaque cursor: send next_cursor from the previous page unchanged. Omit for the first page."
    }
  }
}
list_reports annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
create_report — Start a report for a website
Advertised by the server during the last successful anonymous check.
Advertised destructive

Creates a report draft for a website and starts reading it. Free plan: one website, one report every 30 days. Returns 202 Accepted with the report, a job object and a Location header: poll that URL (GET /api/v1/reports/{reportId}) every few seconds until stage is needs_confirmation, then call the start endpoint. Send an Idempotency-Key header so a retry cannot start a second report. Needs login with scope reports:write.

create_report input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "website"
  ],
  "properties": {
    "country": {
      "type": "string",
      "description": "Optional two-letter country. Send with language, or omit both to detect from the site."
    },
    "website": {
      "type": "string",
      "description": "The website to measure, like yourcompany.com. Public sites only."
    },
    "language": {
      "type": "string",
      "description": "Optional language for that country."
    }
  }
}
create_report annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": true
}
batch_get_reports — Read up to 25 reports in one request
Advertised by the server during the last successful anonymous check.
Advertised read-only

Batch read: send a list of report ids and get each report (or its error) in one answer, instead of one call per report. Each result has its own status, so one unknown id does not fail the rest. Read-only. Needs login with scope reports:read.

batch_get_reports input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "report_ids"
  ],
  "properties": {
    "report_ids": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Report ids to read, 1 to 25."
    }
  }
}
batch_get_reports annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_report — Read one report: stage, setup to confirm, or results
Advertised by the server during the last successful anonymous check.
Advertised read-only

While stage is needs_confirmation it returns the business profile and the proposed buyer questions. While running it returns progress. When finished it returns visibility numbers, the brands AI named, and a count of lost questions. Needs login with scope reports:read.

get_report input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "reportId"
  ],
  "properties": {
    "fields": {
      "type": "string",
      "maxLength": 200,
      "description": "Comma-separated top-level fields to return, for example fields=id,stage. Omit to get everything. Spend fewer tokens by asking for less."
    },
    "reportId": {
      "type": "string",
      "description": "Report id from POST /api/v1/reports or GET /api/v1/reports."
    }
  }
}
get_report annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
start_report — Confirm the setup and run the report
Advertised by the server during the last successful anonymous check.

Accepts the proposed business profile and buyer questions (optionally a chosen subset of 3 to 6 question ids) and starts asking the AI engines the account includes (listed in limits.engines on GET /api/v1/me). Takes about two minutes: answers 202 Accepted with a Location header to poll until stage is finished. Safe to repeat; send an Idempotency-Key header to make a retry return the first answer. Needs login with scope reports:write.

start_report input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "reportId"
  ],
  "properties": {
    "reportId": {
      "type": "string",
      "description": "Report id from POST /api/v1/reports or GET /api/v1/reports."
    },
    "question_ids": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Ids of the 3 to 6 questions to ask. Omit to keep the proposed selection."
    }
  }
}
start_report annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": false
}
get_report_actions — The ranked plan of changes and the questions you lost
Advertised by the server during the last successful anonymous check.
Advertised read-only

For a finished report: up to three ranked moves (reason, exact edit, page, effort) and, for each buyer question AI answered with a rival, who won and why. Needs login with scope reports:read.

get_report_actions input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "reportId"
  ],
  "properties": {
    "fields": {
      "type": "string",
      "maxLength": 200,
      "description": "Comma-separated top-level fields to return, for example fields=id,stage. Omit to get everything. Spend fewer tokens by asking for less."
    },
    "reportId": {
      "type": "string",
      "description": "Report id from POST /api/v1/reports or GET /api/v1/reports."
    }
  }
}
get_report_actions annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
get_agent_readiness — Stored agent readiness scan (Early Access pass)
Advertised by the server during the last successful anonymous check.
Advertised read-only

Score, grade, layer breakdown and ranked fixes from the newest scan of the report's website. Needs the Early Access pass; otherwise 402 with a link a person can open to buy it. Needs login with scope agent-readiness:read.

get_agent_readiness input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "reportId"
  ],
  "properties": {
    "fields": {
      "type": "string",
      "maxLength": 200,
      "description": "Comma-separated top-level fields to return, for example fields=id,stage. Omit to get everything. Spend fewer tokens by asking for less."
    },
    "reportId": {
      "type": "string",
      "description": "Report id from POST /api/v1/reports or GET /api/v1/reports."
    }
  }
}
get_agent_readiness annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
scan_agent_readiness — Run an agent readiness scan (Early Access pass)
Advertised by the server during the last successful anonymous check.

Runs, or reuses a result under 24 hours old, for the report's website. Set force to true to scan again after fixing something. Rate limited. Needs login with scope agent-readiness:scan.

scan_agent_readiness input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "reportId"
  ],
  "properties": {
    "force": {
      "type": "boolean",
      "description": "Scan again even if a recent result exists."
    },
    "reportId": {
      "type": "string",
      "description": "Report id from POST /api/v1/reports or GET /api/v1/reports."
    }
  }
}
scan_agent_readiness annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (1 of 1 answered).

  1. 2026-11-07: 1 of 1 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
825 ms
95th percentile latency
825 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 825 ms · metadata changed · 13 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http moatlight-mcp https://www.moatlight.com/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add moatlight-mcp --url https://www.moatlight.com/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable moatlight-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "moatlight-mcp": {
      "url": "https://www.moatlight.com/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "moatlight-mcp": {
      "type": "streamableHttp",
      "url": "https://www.moatlight.com/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start moatlight-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "moatlight-mcp": {
      "type": "http",
      "url": "https://www.moatlight.com/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http moatlight-mcp https://www.moatlight.com/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://www.moatlight.com/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "moatlight-mcp": {
      "serverUrl": "https://www.moatlight.com/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Moatlight MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Moatlight MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing