Docs · MCP server

Integrate in one config block

Bring FeedbackGraph reports, evidence and revenue-ranked opportunities into your AI agent — Claude Code, Cursor, VS Code, Windsurf or Slack. Tenant-scoped and read-first.

What is the FeedbackGraph MCP server?

The FeedbackGraph MCP server is a tenant-facing Model Context Protocol server. It exposes your reports, their full evidence, and your revenue-ranked Evidence Graph to AI agents as tools — read-first, with one flag-gated write action. It reuses the same authorized read paths your dashboard uses, so a token only ever sees one tenant’s data, enforced at the database with row-level security. It is never a super-admin or cross-tenant surface.

1 · Get a token

Create an API key in Settings → API keys. Pick the scopes you need — the key is shown once.

reports:read reports + searchintel:read opportunitiesreports:write routing (flag-gated)

2 · Connect a local agent (stdio)

Add this to .mcp.json (Claude Code) or .cursor/mcp.json (Cursor). The mcp-remote bridge connects your editor’s stdio to the hosted endpoint — VS Code and Windsurf use the same block.

{
  "mcpServers": {
    "feedbackgraph": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://feedbackgraph.com/api/mcp",
        "--header", "Authorization: Bearer sk_live_…"
      ]
    }
  }
}

3 · Connect over HTTP (remote / Slack)

Remote agents POST JSON-RPC to the streamable-HTTP endpoint with a Bearer token. It’s stateless — one MCP session per request.

curl -s https://feedbackgraph.com/api/mcp \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

4 · Tool reference

fg_list_reportsreports:read

input: { status?, severity?, type?, projectId?, search?, page?, pageSize? }

Paginated list — id, title, AI verdict, severity, occurrence count, routed state.

fg_get_reportreports:read

input: { reportId }

One report with full, redacted evidence (console / network / JS errors / replay), AI title, summary, confidence, occurrences and routed tracker URL.

fg_searchreports:read

input: { query, limit? }

Ranked reports + signals by semantic similarity (pgvector cosine).

fg_list_opportunitiesintel:read

input: { status? }

Revenue-ranked opportunities — score, ARR influenced, # accounts, signal count, stage.

fg_get_opportunityintel:read

input: { opportunityId }

Opportunity dossier — status, score, ARR, affected accounts (with ARR), backing signals, suggested next step.

fg_route_reportreports:write

input: { reportId, integrationId, target? }

Routes the report to its tracker and returns the URL. Flag-gated and idempotent — re-routing returns the existing link.

Resources

report://{id} and opportunity://{id} — stable handles an agent can attach as context (they mirror fg_get_report / fg_get_opportunity).

Example — the fg_get_report contract:

// fg_get_report → result (PII already redacted)
{
  "id": "rep_8f2",
  "title": "Checkout 500 on card payment",
  "type": "bug", "severity": "high", "aiConfidence": 0.94,
  "summary": "POST /api/pay returns 500 after the card token…",
  "evidence": {
    "console": [{ "level": "error", "msg": "payment failed; [redacted-email]" }],
    "network": [{ "method": "POST", "url": "/api/pay", "status": 500 }],
    "jsErrors": [{ "msg": "charge declined [redacted-card]" }],
    "replayUrl": "https://app.acme.com/r/8f2"
  },
  "occurrences": 5,
  "routed": { "tracker": "linear", "url": "https://linear.app/…" }
}

5 · Scopes & security

  • Tenant isolation at the database (row-level security); no owner/superuser path.
  • Scopes gate every tool; an unknown scope or cross-tenant id is denied (fail-closed).
  • Evidence is PII-redacted on output; media links remain expiring and signed.
  • Per-token rate limits; every tool call is audit-logged (who, tenant, tool, args hash).
  • Read-first — fg_route_report is off by default behind an env + per-tenant flag.
  • Tokens are revocable; revoke a key in Settings → API keys and it stops resolving.

6 · For AI agents — how do they self-integrate?

Hand your agent this brief (plus llms.txt and the machine-readable /.well-known/mcp.json manifest) and it can self-integrate:

FeedbackGraph MCP server — integration brief for an AI agent
- Endpoint (streamable HTTP): https://feedbackgraph.com/api/mcp
- Auth header: Authorization: Bearer <sk_live_ tenant token>
- Transport: MCP streamable HTTP — POST JSON-RPC;
  Accept: application/json, text/event-stream
- Tools:
    fg_list_reports, fg_get_report, fg_search          (scope reports:read)
    fg_list_opportunities, fg_get_opportunity          (scope intel:read)
    fg_route_report                                    (scope reports:write)
- Resources: report://{id}, opportunity://{id}
- All results are tenant-scoped and PII-redacted. Fail-closed on bad scope/id.
- Machine-readable summary: https://feedbackgraph.com/llms.txt
- Discovery manifest (JSON): https://feedbackgraph.com/.well-known/mcp.json

FAQ

Does the agent ever see another tenant’s data?+

No. A token resolves to exactly one tenant and every tool runs inside a Postgres row-level-security transaction. A report or opportunity id from another tenant returns the same “not found” as a missing id — there is no existence leak and no cross-tenant path.

stdio or HTTP — which should I use?+

Local editors (Claude Code, Cursor, VS Code, Windsurf) connect over stdio via the mcp-remote bridge shown above. Remote and Slack agents POST directly to the streamable-HTTP endpoint with a Bearer token. Both expose the identical tools.

How do I enable routing (fg_route_report)?+

It needs the reports:write scope on your token and per-tenant enablement (it ships off by default so the integration launches read-only). Contact us to turn it on for your workspace.

Can an AI agent self-integrate?+

Yes — point it at the integration brief above and llms.txt. It has the endpoint, the auth header, the transport, and the full tool + scope list in a copy-paste form.