Go to App

MCP Server

ExportComments ships an MCP (Model Context Protocol) server that gives AI assistants native access to your account — exports, the comment picker, webhooks, scheduled exports, usage info. Works with ChatGPT, Claude Desktop, Claude Code, Claude on the web, Cursor, Windsurf, and any MCP-compatible client.

If you just want to connect and get going, the short version lives at exportcomments.com/mcp. This page is the reference.

Two ways to use it:

Hosted (recommended)Self-installed (stdio)
URL / commandhttps://mcp.exportcomments.com/mcpnpx -y exportcomments-cli
AuthOAuth 2.0 (browser sign-in) or API tokenAPI token or OAuth JWT in env var
InstallationNone — paste the URLNode.js 18+ on your machine
Best forClaude on the web, Cursor, hosted clientsClaude Desktop, automation scripts

Both expose the same 23 tools.

💡
Browser visit to mcp.exportcomments.com

Opening https://mcp.exportcomments.com directly in a browser bounces to exportcomments.com — the host is an MCP JSON-RPC endpoint, not a website. Point your MCP client at https://mcp.exportcomments.com/mcp (note the path) for the actual service.

Hosted — Claude Desktop, Cursor, Claude web

Point your MCP client at https://mcp.exportcomments.com/mcp and let the OAuth flow handle credentials. On the first tool call you'll be redirected to exportcomments.com, sign in (same email/password you use today), click Authorize, and you're done. No tokens to copy.

Claude Desktop / Cursor — mcp_servers config

json
{
"mcpServers": {
"exportcomments": {
"url": "https://mcp.exportcomments.com/mcp"
}
}
}

On the first request the client sees a 401 Unauthorized with a WWW-Authenticate header pointing at our OAuth discovery doc, opens your browser to https://exportcomments.com/oauth/authorize, you approve, and the access token is stored in the client.

ChatGPT

Open Settings → Connectors, add a custom connector, and paste https://mcp.exportcomments.com/mcp. Custom connectors sit behind the advanced or developer settings on some plans. Confirm, sign in with your ExportComments account when the authorization window opens, and the tools appear in your next chat.

Claude on the web

Add a remote MCP server in Settings → Connections → Add custom MCP and paste https://mcp.exportcomments.com/mcp. Claude walks the OAuth flow automatically.

Already have an API token? Skip OAuth

If you'd rather use your existing API token instead of OAuth:

json
{
"mcpServers": {
"exportcomments": {
"url": "https://mcp.exportcomments.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_TOKEN_HERE"
}
}
}
}
💡
OAuth vs API token

OAuth tokens are tied to your user and expire — convenient and revocable. API tokens are tied to your account, don't expire for 1 year, and are best for automation. Either one works with every tool.

Self-installed (stdio) — Claude Desktop

If you'd rather run the MCP server locally (Claude Desktop spawns the binary on your machine and talks to it over stdio), install the CLI:

bash
npm install -g exportcomments-cli

Or use npx for zero-install (auto-updates):

bash
npx -y exportcomments-cli

Then add to claude_desktop_config.json:

json
{
"mcpServers": {
"exportcomments": {
"command": "npx",
"args": ["-y", "exportcomments-cli"],
"env": {
"EXPORTCOMMENTS_API_TOKEN": "your-token-here"
}
}
}
}

Claude Code

bash
claude mcp add exportcomments -- npx -y exportcomments-cli
export EXPORTCOMMENTS_API_TOKEN="your-token-here"

Run directly

bash
EXPORTCOMMENTS_API_TOKEN="your-token" exportcomments-mcp

OAuth flow (hosted)

The hosted MCP server speaks standard OAuth 2.0 with PKCE. Most clients handle this automatically — you'll only see this section if you're building your own MCP client.

  1. Discovery — your client fetches https://exportcomments.com/.well-known/oauth-authorization-server and reads:

    json
    {
    "issuer": "https://exportcomments.com",
    "authorization_endpoint": "https://exportcomments.com/oauth/authorize",
    "token_endpoint": "https://exportcomments.com/oauth/token",
    "registration_endpoint": "https://exportcomments.com/oauth/register",
    "revocation_endpoint": "https://exportcomments.com/oauth/revoke",
    "scopes_supported": ["read", "write"],
    "response_types_supported": ["code"],
    "grant_types_supported": ["authorization_code", "refresh_token"],
    "code_challenge_methods_supported": ["S256"],
    "token_endpoint_auth_methods_supported": ["none"],
    "revocation_endpoint_auth_methods_supported": ["none"]
    }
  2. Authorize — open the user's browser at:

    bash
    https://exportcomments.com/oauth/authorize
    ?response_type=code
    &client_id=mcp
    &redirect_uri=<your_callback>
    &scope=read+write
    &state=<random>
    &code_challenge=<base64url(sha256(code_verifier))>
    &code_challenge_method=S256

    If the user isn't signed in, they're redirected to /login?redirect=<this_URL>. After signing in they see the consent screen, click Authorize, and are sent to redirect_uri?code=...&state=....

  3. Token exchange — POST to /oauth/token:

    bash
    grant_type=authorization_code
    code=<from callback>
    client_id=mcp
    redirect_uri=<same as step 2>
    code_verifier=<original verifier>

    Returns:

    json
    {
    "access_token": "eyJ0eXA…",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "rt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "scope": "read write"
    }
  4. Use — send Authorization: Bearer <access_token> on each MCP request to mcp.exportcomments.com.

  5. Refresh — when the access token nears its hour, POST to /oauth/token again:

    bash
    grant_type=refresh_token
    refresh_token=<the one you stored>
    client_id=<your client_id>

    You get back a fresh access token and a new refresh token. Store the new one and discard the old.

Refresh token rotation

Refresh tokens are single-use. Redeeming one consumes it and mints a replacement, so the token you hold changes on every refresh.

If a token that has already been redeemed is presented again, that is treated as a replay: the entire rotation family is revoked and both the replayed token and its successors stop working. This is deliberate — it means a stolen refresh token cannot be used alongside the legitimate client for long. In practice it only bites if your client stores the response before the request completes, or runs two refreshes concurrently. Serialize refreshes and always persist the newest token.

Refresh tokens are valid for 30 days from issue, and each rotation resets that window. Only a SHA-256 hash of the token is stored on our side, so we cannot recover one for you — if it is lost, re-run the authorization flow.

Revoking a token

POST /oauth/revoke implements RFC 7009:

bash
token=<a refresh token or an access token>
client_id=<your client_id>

Revoking a refresh token kills its whole rotation family. Revoking an access token blacklists it until it would have expired anyway. The endpoint always answers 200, even for a token that never existed — it deliberately does not reveal whether one did.

💡
Token lifetime

Access tokens are JWTs that expire after 1 hour; refresh tokens last 30 days and rotate on use. A client that stores the refresh token stays connected without ever sending the user back through the browser.

Registering a client

Most clients register themselves through RFC 7591 dynamic client registration at POST /oauth/register, declaring their own redirect_uris. That is how ChatGPT, Claude and Cursor get a client_id, and it means there is no allow-list to get added to. Registration is public, rate-limited per IP, and every client it issues is PKCE-only with no client secret.

Redirect URIs must be https://, or http:// on 127.0.0.1 / localhost for native loopback flows per RFC 8252. The pre-registered mcp client additionally accepts any port on http://127.0.0.1 and http://localhost, plus https://claude.ai/api/mcp/auth_callback.

Tools

The MCP server exposes 23 tools covering the full account surface — exports, the random comment picker, webhooks, scheduled exports, account info. See the tool reference for parameters and examples.

CategoryTools
Exportsexport_comments, check_export, list_exports, download_export
Discoverydetect_platform, list_platforms
Accountget_my_profile, get_my_quota, get_my_limits
Pickerpick_random_winners
Webhookslist_webhooks, create_webhook, update_webhook, delete_webhook, toggle_webhook, test_webhook
Scheduleslist_schedules, create_schedule, update_schedule, delete_schedule, run_schedule, pause_schedule, resume_schedule

Example workflows

Export and download

An AI assistant can chain tools for a full workflow:

  1. detect_platform — check what options the URL supports.
  2. export_comments with wait=true — create the export, return when done.
  3. download_export — retrieve the raw JSON.

Pick giveaway winners

  1. export_comments with wait=true — get every comment on the giveaway post.
  2. pick_random_winners with count=5, require_mention="@brand" — pick 5 random commenters who tagged the brand, deduped by username.

Recurring weekly export to a webhook

  1. create_webhook with event="export.finished", url="https://your-app.com/hook" — set up the delivery channel.
  2. create_schedule with url=…, frequency="weekly", options.replies=true — schedule the export.

Every Monday the export runs, finishes, and your webhook gets the result.

Response format

All MCP tool responses return structured JSON:

json
{
"ok": true,
"data": {
"id": 12345,
"guid": "b4219d47-3138-5efd-9762-2ef9f9495084",
"status": "done",
"url": "https://www.instagram.com/p/ABC123/",
"totalComments": 342,
"exportedComments": 342,
"downloadUrl": "https://exportcomments.com/api/v3/job/b4219d47-.../download"
}
}

On error:

json
{
"ok": false,
"error": "Human-readable error message",
"error_code": "MACHINE_READABLE_CODE",
"detail": "Additional context"
}
💡
AI-optimized output

All tool responses are JSON, making it trivial for AI assistants to parse results and chain operations. Use wait=true on export_comments and check_export to get final results in a single round-trip.

Troubleshooting

"Unauthorized: missing or invalid Bearer token"

You're hitting the hosted MCP without auth. Either complete the OAuth flow or include Authorization: Bearer <token> in your MCP client config.

The server answers 401 with a WWW-Authenticate header for a missing, expired, malformed or revoked credential. Clients treat error="invalid_token" in that header as their cue to re-run the OAuth flow, so a connector that has gone stale should recover on its own.

Hosted MCP responds 503 / connection refused

The hosted service is at mcp.exportcomments.com. Check status: curl -s https://mcp.exportcomments.com/health should return {"ok":true,…}. If not, check the status page or contact support.

npx exportcomments-mcp fails on Claude Desktop

Make sure Node.js 18+ is on your PATH. Claude Desktop sometimes can't see system Node — point command at the absolute path instead (e.g. /usr/local/bin/node + args: ["/path/to/node_modules/exportcomments-cli/dist/mcp.js"]).

Every tool call fails after the connector has been open a while

Access tokens last an hour. A client that stored the refresh token renews silently and you should never notice. A client that discarded it — or one added before refresh tokens existed — has nothing to renew with, and every call fails until you reconnect.

Remove the connector and add it again. That runs a fresh authorization and stores a refresh token this time.

"Refresh token already used; the token family has been revoked"

Your client redeemed the same refresh token twice, so rotation treated it as a replay and revoked the chain. Reconnect to get a new one, and make sure the client persists the token from each refresh response before issuing the next request.