.dev
MCP server

MCP server

The hosted Feeef MCP server at mcp.feeef.org — let AI agents manage stores, products, orders, delivery, landing pages and finance over the Model Context Protocol.

The Feeef MCP server exposes the whole commerce platform as Model Context Protocol tools, so AI agents — Cursor, Claude Code, Claude Desktop, VS Code Copilot, or your own agent — can manage stores, products, orders (including Ecotrack delivery), landing pages, inventory, finance and more on a merchant's behalf. It is a thin, stateless-by-design bridge: every tool call becomes a REST API request authenticated with the connected user's bearer token.

Endpointhttps://mcp.feeef.org/mcp (also served at /)
TransportMCP Streamable HTTP (POST/GET/DELETE, SSE-capable)
Tools138 tools in 22 namespaces — see the tools reference
Resourcesserver://info, server://scope
AuthMCP OAuth discovery (PKCE) or a direct Authorization: Bearer header
HealthGET https://mcp.feeef.org/health (shows the active upstream API)

How it fits together

Two ways to authenticate

Clients that implement the MCP authorization spec need zero configuration beyond the URL. An unauthenticated initialize receives 401 with a WWW-Authenticate header pointing at /.well-known/oauth-protected-resource/mcp; the host then discovers the authorization server metadata and runs a standard authorization-code + PKCE flow (PKCE is mandatory):

  1. The host opens GET /authorize in the browser, which redirects to the Feeef sign-in on accounts.feeef.org.
  2. After consent, Feeef calls the server's registered callback (/oauth/feeef/callback), which redirects back to the host's redirect_uri with an authorization code.
  3. The host exchanges the code (plus PKCE verifier) at POST /token and receives the Feeef bearer token as access_token.

Loopback and IDE custom-scheme redirect URIs (cursor://, vscode://, …) are accepted out of the box per RFC 8252. Other public HTTPS redirect URIs must first be registered through the open dynamic client registration endpoint POST /register (RFC 7591). The bridge flow itself is the same authorization-code flow used across the platform.

2. Direct bearer token

Clients that support custom headers can skip OAuth entirely and send a Feeef API token on initialize:

Authorization: Bearer oat_...
Accept: application/json, text/event-stream
Content-Type: application/json

The token is bound to the MCP session and reused for every tool call in it. Any valid API token works: a first-party sign-in token or an OAuth app token with limited scopes.

Scopes and permissions

The MCP server does not run its own permission system — enforcement happens upstream at the Feeef API, exactly as if the agent called the REST API directly:

  • Token scopes. Tool calls carry the session's bearer token, so what the agent can do is what that token's scopes allow. A bearer token minted for products.read fails on products_update with a permission error. Note that the hosted OAuth bridge requests the full * scope on the consent screen — connect with a scoped token via the bearer header when you want a narrower blast radius.
  • Store roles. Store-member RBAC still applies: a viewer member cannot mutate orders no matter which token they hold.
  • Integration gates. finance_* and inventory_* tools require the corresponding paid integration to be active on the store. When it is not, the tool returns a structured integration_required payload naming integrations_subscribe as the fix, instead of a hard error.

The server://scope MCP resource returns the live tool surface as one JSON map of namespaces to qualified tool names. It is generated at runtime from the registration catalog, so it can never drift from what is actually registered:

{
  "namespaces": {
    "auth": ["auth_me", "auth_update"],
    "stores": ["stores_list", "stores_get", "..."],
    "orders": ["orders_list", "orders_send_to_ecotrack", "..."]
  }
}

server://info is a small JSON resource describing the server (name, transport, auth mode).

Sessions

Each initialize creates a server-side session identified by the mcp-session-id header, with the bearer token bound to it. Sessions idle for more than 12 hours are evicted; an expired session answers 404, and spec-compliant clients re-initialize transparently.

Self-hosting

The server is a plain dart:io binary (no web framework) shipped as a from-scratch Docker image. The build AOT-compiles bin/server.dart and copies docs/ into the image — the docs_* and tool_doc_* tools read those markdown files at runtime.

docker build -t feeef-mcp .

docker run -p 8080:8080 \
  -e FEEEF_CLIENT_ID=... \
  -e FEEEF_CLIENT_SECRET=... \
  -e FEEEF_BASE_URL=https://api.feeef.org/v1 \
  feeef-mcp

The client id/secret identify the developer OAuth app the bridge signs users in with — register one in the dashboard and allowlist your callback URL (exact match) against it. The server exits at startup if no client id/secret is available.

Env varPurposeDefault
FEEEF_CLIENT_IDDeveloper-app OAuth client iddev fallback in source
FEEEF_CLIENT_SECRETDeveloper-app OAuth client secretdev fallback in source
FEEEF_BASE_URLUpstream API base, including /v1https://api.feeef.org/v1
FEEEF_OAUTH_REDIRECT_URIFull OAuth callback URL overrideproduction callback
FEEEF_MCP_PUBLIC_ORIGINOrigin used to derive the callback URL
FEEEF_MCP_DEV1 uses the local loopback callbackoff
FEEEF_MCP_OAUTH_CLIENTS_FILEJSON file persisting /register registrationsin-memory
FEEEF_MCP_OAUTH_LOG1 enables verbose OAuth diagnosticsoff
PORT / HOSTBind address8080 / dual-stack any-IPv6

The callback URL resolves in priority order: FEEEF_OAUTH_REDIRECT_URI, then FEEEF_MCP_PUBLIC_ORIGIN + /oauth/feeef/callback, then the loopback URL when FEEEF_MCP_DEV=1, else the production default https://mcp.feeef.org/oauth/feeef/callback. Verify a running instance with GET /health — it reports the active upstream as feeefBaseUrl, plus session count and OAuth endpoints.

On this page