@flynetdev/mcp
v0.2.0
Published
Local MCP server for the Flynet API. Run via npx in Claude Code, Cursor, or Claude Desktop to call Flynet directly mid-reasoning.
Maintainers
Readme
Flynet MCP server
A local MCP server for the Flynet API. Run it with npx inside Claude Code, Cursor, Claude Desktop, or any MCP-aware agent, and the agent can call Flynet directly mid-reasoning instead of generating fetch() code that runs in a separate turn.
It wraps @flynetdev/core — the same client partners use — and exposes 9 read-only action tools, 3 prompts, and 2 resources.
It runs locally: your MCP client launches it as a subprocess over stdio. You run your own instance with your own credentials — nothing is hosted, there's no URL, and no secrets leave your machine.
Two credentials, two route families
The Flynet API has two auth schemes, so the server holds two credentials and routes each tool to the right one:
| Credential | Env var | Backs |
|---|---|---|
| X-API-Key (server-only) | FLYNET_API_KEY | Discovery tools — restaurants, locations |
| OAuth Bearer JWT | FLYNET_ACCESS_TOKEN | Member tools — profile, wallets, check-ins, memberships |
You set these in your MCP client's config (below). A Discovery tool called without an API key — or a member tool without a token — returns a structured, actionable error (the problem, the matching Truth Pack anchor, the next step), never a stack trace.
Credentials come from the partner onboarding email. See sandbox access.
Install
No clone, no build — npx fetches and runs the published package.
Claude Code
claude mcp add flynet \
--env FLYNET_API_KEY=bb_... \
--env FLYNET_ACCESS_TOKEN=ey... \
-- npx -y @flynetdev/mcpCursor — ~/.cursor/mcp.json (or project .cursor/mcp.json):
{
"mcpServers": {
"flynet": {
"command": "npx",
"args": ["-y", "@flynetdev/mcp"],
"env": {
"FLYNET_API_KEY": "bb_...",
"FLYNET_ACCESS_TOKEN": "ey..."
}
}
}
}Claude Desktop — claude_desktop_config.json: same mcpServers block as Cursor.
Member tools need FLYNET_ACCESS_TOKEN; Discovery tools need FLYNET_API_KEY. Provide whichever surfaces you'll use (or both).
Verify with MCP Inspector
npm install
npm run inspectEnv vars
| Var | Required | Default | Used for |
|---|---|---|---|
| FLYNET_API_KEY | For Discovery tools | — | /restaurants*, /locations* — X-API-Key |
| FLYNET_ACCESS_TOKEN | For member tools | — | /users/me/*, /check_ins*, /memberships — Bearer |
| FLYNET_ENV | No | staging | Named environment: staging or production. Selects the API host + OAuth tenant. |
| FLYNET_SERVER_URL | No | — | Explicit API base URL. Takes precedence over FLYNET_ENV (proxy/mock). |
Resolution order for the API host: FLYNET_SERVER_URL > FLYNET_ENV > staging. An invalid FLYNET_ENV fails fast at startup. The server logs the resolved target to stderr on boot.
Surface
Tools (9, all read-only in v1)
| Tool | Wraps | Auth |
|---|---|---|
| list_restaurants | GET /restaurants | API key |
| get_restaurant | GET /restaurants/{id} | API key |
| list_locations | GET /locations | API key |
| get_location | GET /locations/{id} + …/open_hours | API key |
| get_my_profile | GET /users/me + /users/me/status | JWT · read:profile |
| get_my_wallets | GET /users/me/wallets | JWT · read:wallets |
| list_my_check_ins | GET /users/me/check_ins | JWT · read:checkins |
| list_check_ins | GET /check_ins?location= (anonymized venue feed; location required) | JWT · read:checkins |
| list_my_memberships | GET /memberships | JWT |
List tools are paginated (zero-indexed page, page_size ≤ 100) and return trimmed UI fields; pass include_raw: true for the full object. Payment Intent tools are deferred to v2 (they need destructive-tier, user-in-the-loop guardrails).
Resources
| URI | Mime | Content |
|---|---|---|
| flynet://truth-pack | text/markdown | The 8 anchor facts to ground code on |
| flynet://openapi | application/yaml | The Flynet OpenAPI spec |
Prompts
| Prompt | Purpose |
|---|---|
| audit_flynet_integration | Audit partner code against the Truth Pack |
| debug_oauth_flow | Diagnose a 401/403/422 auth failure |
| build_discovery_app | Scaffold a Next.js app composing @flynetdev/react components |
Error handling
Every error from an @flynetdev/core call is normalized to a FlynetError; the server maps it (plus missing-credential cases) to a structured message naming the problem, the Truth Pack anchor, and the next step. No raw stack traces reach the agent.
Optional: self-hosted HTTP
The server also speaks the Streamable HTTP transport, for teams that prefer one shared, zero-install endpoint over a per-developer npx install:
npm run build
node dist/server.js --http # Streamable HTTP on http://127.0.0.1:8787/mcpPoint a client at it with claude mcp add --transport http flynet <url> or { "url": "<url>" }. In this mode the instance uses its own FLYNET_* env credentials for every caller, so run it per-team, not as a public multi-tenant service. Verify it with node scripts/smoke-http.mjs against a running server. For most partners the local npx install above is simpler.
Development
npm run dev # tsc --watch
npm run build # compile + copy the bundled OpenAPI asset
npm test # vitest — protocol smoke + trim unit tests
npm run clean # rm -rf distLogging is stderr-only — stdout is the protocol channel under stdio.
