MenuMCP server

Developer docs

MCP server

Connect Claude, Cursor, or any MCP client so your AI can check flight status, list proofs, post new proofs, inspect proof interactions, and read public user proof data.

Endpoint: https://flyinpublic.com/mcp. Transport: HTTP / Streamable HTTP. Auth: Fly in Public OAuth sign-in.

Recommended: install the skill

Start with the Fly in Public skill. It tells compatible agents to use hosted OAuth MCP, read the lightweight docs, and avoid API-token setup unless the client cannot support OAuth.

Hosted OAuth client config

Use this against the deployed Worker once OAuth storage is configured. In production, that is https://flyinpublic.com/mcp.

{
  "mcpServers": {
    "flyinpublic": {
      "type": "http",
      "url": "https://flyinpublic.com/mcp"
    }
  }
}

Claude Code CLI

claude mcp add --transport http flyinpublic https://flyinpublic.com/mcp

MCP Inspector

npx @modelcontextprotocol/inspector \
  --transport http \
  --url https://flyinpublic.com/mcp

Your client should open a Fly in Public sign-in flow. Sign in and approve the connection.

Claude Desktop connector

Claude Desktop supports custom remote MCP connectors, and a connector added there can also be used from the Claude mobile app after it is connected.

  1. Open Claude Desktop.
  2. Go to Settings, open Customize, then choose Connectors.
  3. Click the plus button or Add custom connector.
  4. Set Name to Fly in Public.
  5. Set Remote MCP server URL to https://flyinpublic.com/mcp.
  6. Click Add, then click Connect.
  7. Sign in to Fly in Public in the browser window and approve the connection.
  8. Accept the browser prompt to return to Claude.
  9. For smoother use, change tool permissions from Needs approval to Always allow.

Test it with prompts like "When will my bird crash?", "What are my leaderboard ranks?", or "What did @max post this week?"

Tools reference

Account tools operate on the connected user. Public-read tools accept a public username, never a private user id.

Status tools include altitude in meters for display. Leaderboard rank tools return both tabs: longest flight and highest altitude.

Planning tools (create_planned_proof, list_planned_proofs, update_planned_proof, cancel_planned_proof, complete_planned_proof, link_proof_to_planned_proof) let you plan a future proof calendar conversationally. A planned proof records intent only and does not change altitude until you complete it with a real proof. New planned proofs default to a Telegram reminder 1 hour before due time.

ToolDescriptionInputs
bird_statusGet your bird's current flight state: altitude in meters, status (flying, grounded, crashed), crash deadline, recent streak, and both leaderboard ranks.none
list_proofsList your most recent proofs (most recent first). Returns id, url, platform, message, publishedAt.
  • limit (integer default 10): How many proofs to return (1 to 50).
add_proofPublish a new proof for the authenticated user's flight. The URL is auto-enriched: message, publishedAt, and platform are pulled from the link (X, YouTube, TikTok, Reddit, Open Graph) when not provided. Any field you pass in explicitly overrides the auto-detected value.
  • url (string required): Public URL of the proof.
  • message (string): Short description of the proof.
  • publishedAt (string): ISO-8601 publish timestamp. Defaults to now.
leaderboard_rankGet the authenticated user's leaderboard ranks for both tabs: longest flight and highest altitude. The leaderboard only ranks flights that are currently in the air, so a crashed flight has no rank until it takes off again.none
leaderboard_topGet the top N leaderboard entries for a tab. Only flights currently in the air are ranked.
  • metric (string (one of: longest, altitude) default "longest"): Leaderboard tab to return: longest flight or highest altitude.
  • limit (integer default 5): How many entries to return (1 to 25).
get_public_userGet a public user's profile and current flight state by username. Returns only public fields.
  • username (string required): Public username/handle, with or without a leading @.
list_public_user_proofsList a public user's proofs, most recent first. Returns only public proof fields.
  • username (string required): Public username/handle, with or without a leading @.
  • sinceHours (integer): Optional lookback window in hours.
  • limit (integer default 10): How many public proofs to return (1 to 50).
  • cursor (string): Optional pagination cursor from a previous response.
get_public_proofGet one public proof by username and proof id. Returns only public proof fields.
  • username (string required): Public username/handle, with or without a leading @.
  • proofId (string required): Public proof id from a profile, leaderboard, or proof list.
list_recent_likesList the most recent likes on the authenticated user's proofs (since the cutoff).
  • sinceHours (integer default 168): Lookback window in hours (default 168 = 7 days).
  • limit (integer default 20): Max number of results.
list_recent_commentsList the most recent comments on the authenticated user's proofs (since the cutoff).
  • sinceHours (integer default 168): Lookback window in hours (default 168 = 7 days).
  • limit (integer default 20): Max number of results.
create_planned_proofSchedule a future proof task (a planned proof). Use this to help the user plan a proof calendar conversationally. A planned proof records intent only: it does NOT change altitude until it is completed with a real proof. New planned proofs default to a Telegram reminder 1 hour before due time; pass reminderAt as null/empty or reminderMinutesBefore as empty to disable it. One platform per planned proof; create separate planned proofs to cross-post. All timestamps are ISO-8601 UTC.
  • description (string required): What the user intends to ship or post.
  • dueAt (string required): ISO-8601 UTC date-time the proof is due.
  • platform (string): Target platform/proof type (e.g. X, YouTube, LinkedIn). Defaults to Other.
  • context (string): Optional project or campaign this planned proof belongs to.
  • reminderAt (string): Optional ISO-8601 UTC reminder time. Leave empty/null to disable reminders.
  • reminderMinutesBefore (integer default 60): Optional reminder offset in minutes before the due time (used if reminderAt is not set). Defaults to 60 on create; leave empty/null to disable reminders.
  • sourceTaskId (string): Optional id of an originating task in another system.
list_planned_proofsList the authenticated user's planned proofs, ordered by due date. Returns id, description, dueAt, platform, status, reminderAt, and completed proof link.
  • status (string (one of: planned, completed, missed, cancelled)): Optional status filter.
  • upcomingOnly (boolean): Only return planned or missed tasks (not completed or cancelled).
  • limit (integer default 50): Max number of planned proofs to return.
update_planned_proofUpdate fields of a planned proof: description, dueAt, platform, context, reminder, status, sourceTaskId. Status can be set to planned, missed, or cancelled here; to mark completed, use complete_planned_proof so a real proof is created or linked.
  • id (string required): Planned proof id.
  • description (string)
  • dueAt (string)
  • platform (string)
  • context (string)
  • reminderAt (string): Set a specific reminder time, or pass empty/null to disable reminders.
  • reminderMinutesBefore (integer): Set a reminder offset in minutes before the due time.
  • status (string (one of: planned, missed, cancelled))
  • sourceTaskId (string)
cancel_planned_proofCancel a planned proof. It stays on record with status cancelled.
  • id (string required): Planned proof id.
complete_planned_proofComplete a planned proof by publishing a real proof from a URL (auto-enriched like add_proof) or by linking an existing proof id. This publishes/links the real proof and updates flight altitude normally, then marks the planned proof completed and cross-links the two.
  • id (string required): Planned proof id to complete.
  • url (string): Public URL of the proof to publish. Omit if linking an existing proofId.
  • message (string): Optional message for the new proof.
  • publishedAt (string): Optional ISO-8601 publish timestamp for the new proof.
  • proofId (string): Existing proof id to link instead of publishing a new one.
link_proof_to_planned_proofLink a proof the user already published to a planned proof, marking the planned proof completed without creating a new proof.
  • id (string required): Planned proof id.
  • proofId (string required): Existing proof id to link.

Example prompts

  • "What's my flight status?"
  • "When is my bird going to crash, and how much time do I have left?"
  • "Add this URL as a proof: https://example.com/post"
  • "Show me my last 5 proofs and which one performed best."
  • "Who liked my proofs this week?"
  • "What did @max post this week?"
  • "Show me public proofs from daniel from the last 7 days."
  • "Help me schedule next week's proofs around this launch."
  • "Mark my planned changelog post done with this URL."

Advanced bearer-token fallback

If your client cannot use hosted OAuth MCP, create an API token from profile settings and use https://flyinpublic.com/api/mcp.

curl -X POST https://flyinpublic.com/api/mcp \
  -H "Authorization: Bearer $FIP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

Call a tool

curl -X POST https://flyinpublic.com/api/mcp \
  -H "Authorization: Bearer $FIP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc":"2.0",
    "id":3,
    "method":"tools/call",
    "params":{
      "name":"add_proof",
      "arguments":{
        "url":"https://example.com/post",
        "message":"Shipped today!"
      }
    }
  }'

Troubleshooting

  • OAuth does not open: confirm your client supports remote HTTP MCP with OAuth.
  • 401 Unauthorized on advanced MCP: token missing or revoked.
  • 404 Not Found: use exactly https://flyinpublic.com/mcp or https://flyinpublic.com/api/mcp and POST.
  • no_project: visit the dashboard once to create your flight.
  • Proof calls succeed but proofs do not appear: check that publishedAt is not in the future and the URL is not already attached.

See also