Guide

MCP server

Give an AI assistant first-class access to the Food Web network. The MCP server exposes the food asset map and the community forum as typed tools — role-gated by your account, audited on every write.

Introduction

Model Context Protocol (MCP) is the open standard AI clients use to call external tools. Connecting the Food Web server means Claude Code, Claude Desktop, Cursor and friends can search the map, file curation suggestions, and participate in the forum on your behalf — with exactly the permissions your account has, nothing more.

The model runs on the client side: the server performs no inference, it just executes tools. Anonymous access is allowed for public reads, so you can try it before minting a key.

Endpoint & transport

MCP endpoint
https://mcp.foodweb.network

Transport is Streamable HTTP in stateless mode: each JSON-RPC message is one POST, responses are plain JSON, and no session state is held between calls — ideal for serverless. GET/DELETE return 405. A raw exchange looks like:

# The endpoint speaks MCP Streamable HTTP (JSON responses).
curl -X POST https://mcp.foodweb.network \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Authorization: Bearer fw_YOUR_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
        "protocolVersion":"2025-06-18",
        "capabilities":{},
        "clientInfo":{"name":"curl","version":"0"}}}'

Authentication

Send Authorization: Bearer <credential> with either:

  • an API key (fw_…) minted on the dashboard — long-lived, revocable, stored hashed; or
  • a Firebase ID token — the same credential the REST API uses (expires hourly, so keys are the better fit for MCP clients).

Roles are live

Keys resolve to your account, and roles are read from Firebase custom claims at call time (cached ~60s). Revoking a key or removing a role takes effect within about a minute — no key rotation needed.

API keys authenticate only the MCP server today; /v1 REST endpoints continue to take Firebase ID tokens.

Role tiers

The server registers tools per credential, so tools/list shows only what your account can actually call:

TierCredentialUnlocks
Anonymousnonewhoami, public map search, public forum reads
Any accountfw_ key or ID token+ forum posting, replies, votes
Contributor (verified email)fw_ key or ID token+ suggest_entity, find_duplicates
Curator / Adminfw_ key or ID token+ full curation: review, patch, merge, archive, enrich, re-ingest

Tool catalog — asset map

18 tools across the three map tiers.

Public reads (anonymous OK)

whoamiAuth status: method, uid, roles, unlocked capabilities
search_entitiesSearch the asset map by text, type, region, or bounding box (paginated)
get_entityOne entity with its place and app links
list_citiesMapped cities for a country + province

Contributor (verified email)

suggest_entityFile a map suggestion (create/edit/report-duplicate); curators can auto-apply
check_duplicatesDuplicate candidates near a coordinate before suggesting

Curator / admin

list_suggestionsReview queue, filterable by status/type
review_suggestionApprove/apply, reject, or resolve as duplicate
admin_search_entitiesCuration search: hidden/duplicate rows, sort, UUID lookup
entity_statsWhole-dataset counts and per-type breakdown
update_entityEdit entity fields (status active|hidden, meta merge)
update_placeEdit address/coordinates/status of a place
merge_entitiesMerge a duplicate entity into a canonical one
merge_placesMerge a duplicate place into a canonical one
archive_entitySoft-archive; admins may hard-delete
enrich_entityFill empty fields from Google Places
reingest_entityQueue re-ingestion from the entity website (single or bulk)
link_entity_appConnect an entity to a Food Web app record (e.g. its kitchen listing)

Forum tools

Reads follow the forum's visibility model (anonymous → public threads; signed-in → members threads and your private invites). Writes post as your account and require authentication.

forum_list_categoriesForum channels, in display order
forum_list_discussionsGlobal or per-category feed, visibility-filtered
forum_get_discussionOne thread with messages and replies
forum_create_discussionStart a thread (public / members / private + invites)
forum_post_messagePost a top-level message
forum_replyReply to a message
forum_voteLike/dislike a discussion, message, or reply

Auditing & limits

  • Every mutating tool call is recorded in an audit log — actor, key, tool, redacted arguments, affected ids, outcome. Reads are not logged.
  • Requests are rate-limited to 120 calls/minute per account (per IP when anonymous); exceeding it returns an error with a retry hint. whoami shows your remaining budget.
  • Suggestions are additionally limited to 20/hour per account, matching the REST API.
  • Search pages are capped at 100 rows per call; use cursor to paginate.
  • Up to 10 active API keys per account.

Connect a client

For Claude Code it is one command:

claude mcp add --transport http foodweb https://mcp.foodweb.network \
  --header "Authorization: Bearer fw_YOUR_KEY"

Cursor and Claude Desktop configs (including the mcp-remote bridge for stdio-only clients) are on the dashboard, pre-filled and copy-pastable.

Troubleshooting

401 UnauthorizedThe key is wrong, revoked, or the header is malformed. Mint a fresh key and re-check "Authorization: Bearer fw_…". Note: a bad credential is rejected — it does not fall back to anonymous.
Tool missing from tools/listTools are registered per role tier. Run whoami: if the roles are stale, wait ~60s (live-claims cache) and reconnect; if a role is absent, your account does not have it.
Rate limit exceededYou hit 120 calls/min — the error includes a retry hint; whoami shows the remaining budget.
405 Method Not AllowedThe server is stateless: send JSON-RPC over POST. SSE/GET streaming is not used.
forbidden: Email verification requiredContributor tools need a verified email on the account (curators/admins are exempt).
Claude Desktop cannot connectDesktop speaks stdio — use the mcp-remote bridge config from the connect page, and make sure Node is installed.