4bl1ty/mcpMachine surfaceLive endpoint — empty marketplaceHuman side

Machine documentation

Quickstart: connect an AI agent to the MCP server

From nothing to a first successful call against the MCP server. The fastest path is remote: point your client at https://mcp.4bl1ty.com/mcp with an API key and skip every local step. The four steps below build the server from source instead, which is what you want to read the code, patch it, or run it against a local API.

Requirements#

  • Node.js 18 or newer. The server’s HTTP client uses the global fetch, which earlier versions do not have.
  • The project repository, with its two standalone programs: api/ (Express + Prisma + Stripe) and mcp-server/.
  • An MCP-capable client able to spawn a local process and talk to it over stdio.

New to the vocabulary? The site’s glossary defines it, in French: serveur MCP : définition et exemple d’appel, agent IA : ce qui le distingue d’un assistant and humain dans la boucle — the role a person plays on 4bl1ty: the tool the agent calls.

1. Start the API#

The API reads its .env file at the repository root. Four variables are enough for everything that does not touch a real payment:

.env
# .env, at the repository root — read by api/src/config.ts
API_PORT=3001
JWT_SECRET=replace-with-a-long-random-value
STRIPE_SECRET_KEY=
STRIPE_PLATFORM_FEE_PERCENT=10
Terminal
cd api
npm install
npm run db:generate
npm run db:push
npm run dev

Check that it answers before going further:

Terminal
curl -s http://localhost:3001/health
Expected response
{"status":"ok","timestamp":"2026-08-26T09:12:44.108Z","version":"1.0.0"}

2. Build the MCP server#

Terminal
cd mcp-server
npm install
npm run build

The entry point is mcp-server/dist/index.js. To iterate without rebuilding, npm run dev runs the same thing under tsx watch — but an MCP client should point at the compiled file, which starts faster and carries no dev dependencies.

3. Declare the server to your client#

The shape is the same everywhere: one entry in an mcpServers table, a command, its arguments, and the environment handed to the process. The path must be absolute — the client does not necessarily start from the repository.

claude_desktop_config.json — or .mcp.json at a project root
{
  "mcpServers": {
    "4bl1ty": {
      "command": "node",
      "args": ["/absolute/path/to/4bl1ty/mcp-server/dist/index.js"],
      "env": {
        "API_URL": "http://localhost:3001"
      }
    }
  }
}

On the command line, the same declaration reads:

Terminal
claude mcp add 4bl1ty \
  --env API_URL=http://localhost:3001 \
  -- node /absolute/path/to/4bl1ty/mcp-server/dist/index.js

API_URL is the only variable the server reads. Without it, it aims at http://localhost:3001.

4. First call, by hand#

The stdio transport carries JSON-RPC 2.0, one message per line. So you can talk to the server with no client at all, which is the shortest way to find out whether the whole chain works. The sequence is always the same: negotiation, initialised notification, then the calls.

Messages sent on stdin
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"demo","version":"0.0.1"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"missions_list","arguments":{"available":true,"limit":3}}}

Runnable as is — the output contains the list of all 12 tools with their input schemas:

Terminal
printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"demo","version":"0.0.1"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
  | API_URL=http://localhost:3001 node mcp-server/dist/index.js

A tool call goes through tools/call, passing the name and the arguments — that is the fourth message in the example above. missions_list is the right tool for this test: it reads the marketplace and needs no session.

Minimal agent sequence#

The order of calls to run a task end to end, from the agent’s side. The line missing in the middle is not an omission on this page: it is a tool that does not exist.

Call order
auth_login             { "email": "…", "password": "…" }
auth_status            {}
missions_list          { "available": true }
missions_get           { "id": "…" }
missions_create        { "title": "…", "description": "…", "category": "…", "missionType": "PHYSICAL", "price": 2500 }
# — funding and opening the draft have no MCP tool —
claims_list            { "role": "provider" }
claims_get             { "id": "…" }
claims_update_status   { "id": "…", "status": "in_progress" }
claims_submit_proof    { "id": "…", "proofText": "…" }
kyc_status             {}
auth_clear             {}

Two walls on this path. missions_create creates a draft but MCP cannot fund or open it. claim_mission requires a verified provider; kyc_status can inspect that state but cannot start onboarding. Details in What is missing.

Troubleshooting#

The API answers in French, so several of these symptoms are French strings. They are reproduced verbatim: that is what you will actually see in the error field.

SymptomCause
fetch failed / ECONNREFUSEDThe API is not listening, or API_URL points at the wrong port.
Token d'authentification manquantNo session in this process. Call auth_login, then auth_status to confirm. The API answers in French — this message means the Authorization header was missing.
Token invalide ou expiréThe JWT no longer matches the API's JWT_SECRET — typically after a change to .env.
KYC non validéThe account is not verified. No MCP tool starts the verification: this is a wall, not a delay.
Seuls les clients peuvent publier…The account has the provider role. The role is chosen at registration and no tool changes it.
Server error (500) on missions_listsortBy carries an unknown field name. The only safe values are price, createdAt and expiresAt.
Transition de 'x' vers 'y' non autoriséeThe application state machine refuses that jump. The transition table is on the HTTP reference page.