{
  "markdown": "# askedthrice-mcp\n\nMCP server for [askedthrice.com](https://askedthrice.com). Lets anyone's assistant measure whether a brand shows up when buyers ask an AI for a recommendation.\n\nHosted at `https://mcp.askedthrice.com/mcp` (streamable HTTP). Listed in the [official MCP registry](https://registry.modelcontextprotocol.io) as `com.askedthrice/askedthrice`. The stdio bridge for clients that only launch local commands is the npm package [`askedthrice-mcp`](https://www.npmjs.com/package/askedthrice-mcp), in [`npm/`](npm/).\n\nFull spec: `specs/features/geo-13-mcp-server.md` in the private llm-rank-tracker repo.\n\n## Install\n\n```json\n{\"mcpServers\":{\"askedthrice\":{\"url\":\"https://mcp.askedthrice.com/mcp\"}}}\n```\n\nor, for command-only clients:\n\n```json\n{\"mcpServers\":{\"askedthrice\":{\"command\":\"npx\",\"args\":[\"-y\",\"askedthrice-mcp\"]}}}\n```\n\n## What it exposes\n\n- `start_visibility_check` starts the measurement and returns a `runId`.\n- `get_visibility_check` collects it. Returns `running` until the providers answer.\n- `askedthrice://methodology` explains how it is measured.\n\nTwo tools rather than one because a measurement takes up to two minutes: the audit is 15 to 60 s and the measured map another 15 to 60 s.\n\n## What it returns, and what it does not\n\nIt returns the **measured map**: the buyer questions that were asked live and who won each answer. Never the providers' self-report, which is what each model *believes* about the brand. The two numbers drift apart a lot in practice, and the self-report is always the optimistic one; that is why the tool contract does not expose it in any field.\n\nIt never returns a 0 to 100 score: a verdict in three bands and counts.\n\n## Money\n\nEvery free measurement spends askedthrice's API keys, on the order of USD 0.05 to 0.15. Three guards, all covered by tests:\n\n1. One free measurement per domain every 30 days, checked BEFORE the API is called.\n2. `MCP_MONTHLY_RUN_LIMIT` (default 200) as the channel ceiling, separate from the web funnel budget.\n3. Rate limiting in prod counts by client identity, not by this server's IP, which rotates on serverless.\n\n## Env\n\n| Variable | Purpose |\n| --- | --- |\n| `LLMAUDIT_API_BASE_URL` | API base. Default `https://askedthrice.com` |\n| `MCP_SERVER_KEY` | Key shared with llm-rank-tracker. Without it prod buckets by IP |\n| `SUPABASE_URL` / `SUPABASE_SERVICE_ROLE_KEY` | `mcp_runs` table. Without them the store is in memory and does NOT work on serverless |\n| `MCP_MONTHLY_RUN_LIMIT` | Monthly ceiling of runs for the channel |\n\n## Channel usage\n\n`npm run stats` reads `mcp_runs` and reports how much of the monthly ceiling is left, who called, which domains were measured and which one currently holds the 30-day quota.\n\n```sh\nnode --env-file <file.env> scripts/stats.mjs\nnode --env-file <file.env> scripts/stats.mjs --days 30 --history 180\n```\n\nNeeds `SUPABASE_URL` (or `NEXT_PUBLIC_SUPABASE_URL`) and `SUPABASE_SERVICE_ROLE_KEY`. `--days` is the daily detail, `--history` how far back it looks; the current month is always included in full, because that number has to match the guard's.\n\nThe first thing it prints, when there are any, is the **orphaned** runs: reserved rows that never got their `audit_id`. They return \"Unknown runId\" to the client forever while holding their domain's free quota and counting against the monthly ceiling. Delete them by `run_id`.\n\nVercel Web Analytics cannot measure this: it works by injecting a script into HTML, and here there is no HTML and no browser to run it, every request is a JSON-RPC call from an MCP client. It would read zero forever.\n\n## Docker (directory checks)\n\n`Dockerfile` builds the HTTP server and serves it on `0.0.0.0:3001`, which is what Glama and similar directories run to verify the server starts and answers introspection. Port and host are read by `xmcp.config.ts` at build time, so they go as `ENV` before `npm run build`, not at `docker run`. Without `SUPABASE_*` the run store is in memory: fine for a check, not for serving traffic.\n\n## Development\n\n```sh\nnpm run dev     # xmcp dev\nnpm test        # vitest, no network\nnpm run build   # xmcp build\n```\n\nTests run against real fixtures in `fixtures/` (already-paid runs from prospecting). None of them touch the network or call a provider.\n\n## Publishing a new registry version\n\n`server.json` is published with `mcp-publisher` using DNS auth on `askedthrice.com`. The key lives outside the repo as a PEM; the CLI wants the raw ed25519 seed in hex:\n\n```sh\nHEX=$(openssl pkey -in <key.pem> -noout -text | sed -n '/^priv:/,/^pub:/p' | grep -v '^priv:\\|^pub:' | tr -d ' :\\n')\nmcp-publisher login dns --domain askedthrice.com --private-key \"$HEX\"\nmcp-publisher publish server.json\n```\n\nBump `version` in `server.json` on every publish; the registry rejects a repeat. When the npm package changes version, update `packages[0].version` too.\n",
  "bytes": 4842,
  "sha": "6cf7d11d59aa171e77a8ccdf24c64d91f8189ec1b23542d17a7d5f0270266ebc",
  "repo_slug": "nahuelsoria/llmaudit-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_app_llmaudit_llmaudit_fb56d91d/readme"
}