FlowPOS MCP V1 — Developer Setup Guide
Connect the FlowPOS MCP server to Cursor, Claude Code CLI, and the Claude Code VS Code extension using an API key (V1). Covers both local development and remote (staging/production) environments.
Before You Start
1. Get your API key
Use POST /mcp/keys with a Firebase Bearer token to provision a key. The endpoint returns the raw key once — store it immediately in a password manager or secret vault.
curl -s -X POST https://api.flowpos.app/mcp/keys \
-H "Authorization: Bearer <firebase-id-token>" \
-H "Content-Type: application/json" \
-d '{
"businessId": "<business-uuid>",
"role": "tenant_developer",
"scopes": ["pos:read", "reports:read"],
"label": "My Dev Key"
}'
Response:
{
"rawKey": "fp_mcp_a1b2c3d4e5f6...",
"key": {
"id": "key-uuid",
"businessId": "<business-uuid>",
"role": "tenant_developer",
"scopes": ["pos:read", "reports:read"],
"label": "My Dev Key",
"isActive": true,
"createdAt": "2026-01-01T00:00:00.000Z",
"expiresAt": null,
"lastUsedAt": null
}
}
The
rawKeyis never stored on the server — only its SHA-256 hash is. It cannot be recovered after this response.
Available roles and scopes:
| Role | scopes available |
|---|---|
tenant_developer | pos:read, pos:write, reports:read, psa:read, pos:intents |
merchant | same as tenant_developer |
Platform operator keys (
businessId: null) are not available through this endpoint. They require direct database access.
List, revoke, and delete keys:
# List all keys for a business
curl -s "https://api.flowpos.app/mcp/keys?businessId=<uuid>" \
-H "Authorization: Bearer <firebase-id-token>"
# Revoke a key (sets is_active = false)
curl -s -X PATCH "https://api.flowpos.app/mcp/keys/<key-id>/revoke" \
-H "Authorization: Bearer <firebase-id-token>"
# Delete a key permanently
curl -s -X DELETE "https://api.flowpos.app/mcp/keys/<key-id>" \
-H "Authorization: Bearer <firebase-id-token>"
2. Start the local backend (if working locally)
# From the workspace root
docker-compose up -d # PostgreSQL, Redis
pnpm --filter backend run start:dev
The MCP endpoint will be available at http://localhost:4000/mcp.
3. Verify the server is up
curl -s -o /dev/null -w "%{http_code}" \
-X POST http://localhost:4000/mcp \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1"}}}'
Expect 200. A 401 means the key is wrong. A connection refused means the backend isn't running.
Environments
| Environment | MCP URL |
|---|---|
| Local | http://localhost:4000/mcp |
| Staging | https://api-staging.flowpos.app/mcp |
| Production | https://api.flowpos.app/mcp |
Replace the URL in any config block below to switch between environments.
Cursor
Cursor supports MCP through a per-project config file. There is no global MCP config in Cursor — each project gets its own.
Step 1 — Create the config file
In the root of your project (e.g. flowpos-workspace/), create .cursor/mcp.json:
mkdir -p .cursor
touch .cursor/mcp.json
Step 2 — Add the FlowPOS server
Local:
{
"mcpServers": {
"flowpos-local": {
"url": "http://localhost:4000/mcp",
"headers": {
"Authorization": "Bearer fp_mcp_a1b2c3d4e5f6..."
}
}
}
}
Staging:
{
"mcpServers": {
"flowpos-staging": {
"url": "https://api-staging.flowpos.app/mcp",
"headers": {
"Authorization": "Bearer fp_mcp_a1b2c3d4e5f6..."
}
}
}
}
Both environments at once (switch by which server name you reference in chat):
{
"mcpServers": {
"flowpos-local": {
"url": "http://localhost:4000/mcp",
"headers": {
"Authorization": "Bearer fp_mcp_<local-key>"
}
},
"flowpos-staging": {
"url": "https://api-staging.flowpos.app/mcp",
"headers": {
"Authorization": "Bearer fp_mcp_<staging-key>"
}
}
}
}
Step 3 — Reload Cursor
Open the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) and run:
Cursor: Reload Window
Or quit and reopen Cursor.
Step 4 — Verify in Cursor
- Open the Cursor chat panel (
Cmd+L/Ctrl+L) - Click the Tools icon (plug/tool icon near the input)
- You should see flowpos-local (or flowpos-staging) listed with its tools expanded
- Type a prompt:
"Using FlowPOS, list the first 10 products"
Keeping the key out of git
Add .cursor/mcp.json to .gitignore if the file contains real keys:
echo ".cursor/mcp.json" >> .gitignore
For team sharing, commit a .cursor/mcp.json.example with a placeholder key and document that each developer fills in their own key locally.
Claude Code — CLI
The CLI stores MCP server configs globally per user and per project. Project-level configs take precedence over global ones.
Global config (all projects)
Use this if you want FlowPOS available in every Claude Code session regardless of which directory you're in.
Add (local):
claude mcp add flowpos-local \
--transport http \
--url http://localhost:4000/mcp \
--header "Authorization: Bearer fp_mcp_a1b2c3d4e5f6..."
Add (staging):
claude mcp add flowpos-staging \
--transport http \
--url https://api-staging.flowpos.app/mcp \
--header "Authorization: Bearer fp_mcp_a1b2c3d4e5f6..."
List all configured servers:
claude mcp list
Remove a server:
claude mcp remove flowpos-local
Project-level config (recommended for teams)
Project-level config lives in .mcp.json at the project root. Commit a version with placeholder keys and have each developer fill in their own.
Add to the current project:
claude mcp add flowpos-local \
--transport http \
--url http://localhost:4000/mcp \
--header "Authorization: Bearer fp_mcp_a1b2c3d4e5f6..." \
--scope project
This writes to <project-root>/.mcp.json. The file looks like:
{
"mcpServers": {
"flowpos-local": {
"type": "http",
"url": "http://localhost:4000/mcp",
"headers": {
"Authorization": "Bearer fp_mcp_a1b2c3d4e5f6..."
}
}
}
}
Add
.mcp.jsonto.gitignoreto avoid committing real keys. Commit.mcp.json.exampleinstead.
Using the CLI
Interactive session:
cd flowpos-workspace
claude
In the Claude Code REPL, MCP tools are available automatically. Reference them naturally:
> What are my top products this week?
> List all open orders
> Show me the sales report for March 2026
Single-shot command:
claude "List the 5 products with lowest stock using FlowPOS"
Check which tools are loaded:
claude mcp list # shows configured servers
claude mcp get flowpos-local # shows server details
Switching between local and staging in the CLI
The simplest approach: have both servers configured globally and tell Claude which one to use.
claude "Using flowpos-staging, show me today's sales report"
claude "Using flowpos-local, create a test order"
Or use separate shell aliases:
# In ~/.zshrc or ~/.bashrc
alias claude-local='claude --mcp-server flowpos-local'
alias claude-staging='claude --mcp-server flowpos-staging'
Claude Code — VS Code Extension
The VS Code extension shares the same MCP config as the CLI. Any server you add via claude mcp add is immediately available in the extension, and vice versa.
Step 1 — Install the extension
Search for Claude Code in the VS Code Extensions panel (Cmd+Shift+X), or install from the terminal:
code --install-extension anthropic.claude-code
Step 2 — Add the MCP server
The easiest way is via the CLI (changes apply to the extension too):
claude mcp add flowpos-local \
--transport http \
--url http://localhost:4000/mcp \
--header "Authorization: Bearer fp_mcp_a1b2c3d4e5f6..."
Alternatively, edit the MCP config file directly. Open it with:
claude mcp list # shows the config file path at the top
# e.g. ~/.claude/mcp.json (global)
# or <project>/.mcp.json (project-level)
Step 3 — Verify in VS Code
- Open the Claude Code side panel (Activity Bar)
- Start a new conversation
- Click the Tools button or type
/to see available tools - FlowPOS tools (
get_products,get_sales_report, etc.) should appear
Or verify via the Command Palette:
Claude Code: List MCP Servers
Step 4 — Use FlowPOS tools in VS Code
The extension works identically to the CLI — just type naturally:
"Show me a sales report for this week" "Which products are below the reorder point?" "List the last 10 orders for location X"
You can also reference files in the editor and ask Claude to cross-reference them with live FlowPOS data:
"I'm looking at this order schema file — show me a real order from FlowPOS that matches"
Local vs remote in the extension
If you have both flowpos-local and flowpos-staging configured, tell Claude which one to use at the start of the conversation:
"Use the flowpos-staging server for all queries in this session"
Config Reference
Cursor — .cursor/mcp.json
{
"mcpServers": {
"<server-name>": {
"url": "<mcp-url>",
"headers": {
"Authorization": "Bearer <api-key>"
}
}
}
}
Claude Code CLI / VS Code — .mcp.json (project) or ~/.claude/mcp.json (global)
{
"mcpServers": {
"<server-name>": {
"type": "http",
"url": "<mcp-url>",
"headers": {
"Authorization": "Bearer <api-key>"
}
}
}
}
Recommended Workflow for Local Development
┌─────────────────────────────────────────────────────────────────┐
│ Terminal 1 │ Terminal 2 │ IDE │
│ docker-compose up -d │ pnpm start:dev │ Cursor / │
│ (PostgreSQL + Redis) │ (NestJS backend) │ VS Code + │
│ │ → :4000 │ Claude Code │
└──────────────────────────┴─────────────────────┴─────────────────┘
↑
MCP endpoint ready at
http://localhost:4000/mcp
Authorization: Bearer fp_mcp_...
- Start services with
docker-compose up -d - Start backend with
pnpm --filter backend run start:dev - Open project in Cursor or VS Code with Claude Code
- Ask questions — tools call your local DB in real time
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Tools not visible in Cursor | Config file not found or JSON invalid | Confirm .cursor/mcp.json exists at project root; validate JSON at jsonlint.com |
| Tools not visible in VS Code extension | Extension not reloaded after config change | Run Claude Code: Reload MCP Servers from Command Palette |
401 Unauthorized | Wrong or missing API key | Double-check the key; ensure no extra whitespace after Bearer |
ECONNREFUSED / connection refused | Backend not running | Run pnpm --filter backend run start:dev and check :4000 |
400 Bad Request on tool call | Missing session header — client not handling sessions | Use a proper MCP client (Cursor/Claude Code), not raw curl for ongoing calls |
| Only some tools appear | Key scopes are restricted | Ask operator to verify scopes array in mcp_api_key table |
| Cursor shows server as "disconnected" | HTTP server unreachable | Check CORS, firewall, or VPN for remote URLs |
certificate verify failed (staging) | Self-signed cert on staging | Use https:// with a valid cert or add the CA to your trust store |