Skip to main content
Glama

nakama-mcp

CI License: Apache-2.0 Node >= 18

An MCP (Model Context Protocol) server for Heroic Labs Nakama. It lets Claude (or any MCP host) talk to a running Nakama instance across both of its HTTP APIs:

  • Client API (:7350) — player-facing: authentication, accounts, friends, groups, storage, leaderboards, tournaments, RPCs, …

  • Console API (:7351) — admin/operations: search players, inspect & edit storage, leaderboards, active matches, server status & metrics, …

Nakama exposes ~180 operations across the two surfaces, so this server uses a search + execute design instead of one tool per endpoint, plus a handful of promoted convenience tools for the most common jobs.

Tools

Tool

Read/Write

What it does

nakama_search_actions

read

Find operations by intent → returns action IDs, method/path, params.

nakama_execute_action

write

Run any operation by action_id with path_params / query_params / body.

nakama_authenticate

write

Establish a player session (device / custom / email) for client-API calls.

nakama_call_rpc

write

Call a registered runtime RPC (payload encoded the way the gateway expects).

nakama_console_list_accounts

read

List / search player accounts.

nakama_console_get_account

read

Fetch one player account by user ID.

nakama_console_list_storage

read

List storage objects (filter by collection / key / owner).

nakama_console_get_status

read

Node status and lightweight service metrics.

nakama_healthcheck

read

Probe client + console reachability and admin login.

nakama_write_storage_object

write

Write/update a storage object as the authenticated player.

nakama_write_leaderboard_record

write

Submit a score to a leaderboard as the authenticated player.

nakama_send_notification

write

Send an in-app notification to a player (console).

nakama_ban_account

write

Ban a player account by user ID (console).

nakama_unban_account

write

Remove a ban from a player account (console).

Reliability features

  • Auto-pagination — nakama_execute_action, nakama_console_list_accounts, and nakama_console_list_storage accept auto_paginate: true (+ optional max_pages, default 5) to follow cursor/next_cursor and merge pages, adding __pages_fetched / __more_available to the result.

  • Secret redaction — error output is scrubbed of the configured server key / console password, JWTs, and Basic/Bearer header values before it reaches the model.

  • Healthcheck — nakama_healthcheck probes both surfaces (and verifies admin login); use it first when calls fail.

Typical flow: ask nakama_search_actions for what you want → take the action_id → call nakama_execute_action. The promoted tools are shortcuts for frequent reads.

Related MCP server: Claude-LMStudio Bridge

Install & build

npm install
npm run build

Configuration

All configuration is via environment variables. Defaults match a stock local Nakama dev setup.

Variable

Default

Notes

NAKAMA_HOST

127.0.0.1

Host for both APIs.

NAKAMA_PORT

7350

Client API port.

NAKAMA_CONSOLE_PORT

7351

Console API port.

NAKAMA_USE_SSL

false

Use https instead of http.

NAKAMA_SERVER_KEY

defaultkey

Server key for client authenticate endpoints.

NAKAMA_CONSOLE_USERNAME

admin

Console admin user.

NAKAMA_CONSOLE_PASSWORD

password

Console admin password.

NAKAMA_TIMEOUT_MS

15000

Per-request timeout.

See .env.example. These are secrets — prefer your MCP host's env config over committing them.

Add to an MCP host

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "nakama": {
      "command": "node",
      "args": ["/absolute/path/to/nakama-mcp/dist/index.js"],
      "env": {
        "NAKAMA_HOST": "127.0.0.1",
        "NAKAMA_SERVER_KEY": "defaultkey",
        "NAKAMA_CONSOLE_USERNAME": "admin",
        "NAKAMA_CONSOLE_PASSWORD": "password"
      }
    }
  }
}

Claude Code

claude mcp add nakama -- node /absolute/path/to/nakama-mcp/dist/index.js

Cursor / Windsurf (~/.cursor/mcp.json or ~/.codeium/windsurf/mcp_config.json)

Both read the same mcpServers shape as Claude Desktop:

{
  "mcpServers": {
    "nakama": {
      "command": "node",
      "args": ["/absolute/path/to/nakama-mcp/dist/index.js"],
      "env": { "NAKAMA_SERVER_KEY": "defaultkey", "NAKAMA_CONSOLE_PASSWORD": "password" }
    }
  }
}

VS Code (.vscode/mcp.json)

VS Code nests servers under a top-level servers key:

{
  "servers": {
    "nakama": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/nakama-mcp/dist/index.js"],
      "env": { "NAKAMA_SERVER_KEY": "defaultkey", "NAKAMA_CONSOLE_PASSWORD": "password" }
    }
  }
}

Any MCP-capable host works — point it at node /absolute/path/to/nakama-mcp/dist/index.js over stdio (env vars default to a stock local Nakama), or at the Remote HTTP transport below.

Remote HTTP transport

By default the server speaks stdio. Set MCP_TRANSPORT=http to run it as a network-reachable streamable-HTTP server that multiple MCP clients can share. It still targets the single Nakama configured by your NAKAMA_* vars; each connected MCP client gets its own isolated player session, and the console admin login is shared.

Variable

Default

Notes

MCP_TRANSPORT

stdio

Set to http to enable the HTTP server.

MCP_HTTP_HOST

127.0.0.1

Bind address. Loopback by default.

MCP_HTTP_PORT

3000

Listen port.

MCP_HTTP_PATH

/mcp

MCP endpoint path.

MCP_AUTH_TOKEN

(unset)

Static bearer token required in Authorization: Bearer ….

MCP_SESSION_TTL_MS

1800000

Idle session timeout (30 min).

MCP_TRANSPORT=http MCP_AUTH_TOKEN=s3cret npm start
# nakama-mcp ready -> http://127.0.0.1:3000/mcp (transport=http, auth=on)
curl -s http://127.0.0.1:3000/healthz   # -> {"ok":true}

Security: if you bind a non-loopback address (e.g. MCP_HTTP_HOST=0.0.0.0) the server refuses to start unless MCP_AUTH_TOKEN is set, so Nakama admin is never accidentally exposed. The endpoint is plain HTTP — terminate TLS at a reverse proxy for public hosting. GET /healthz is unauthenticated for load balancers; all /mcp traffic requires the token.

How auth works

  • Console API: the server auto-logs-in with NAKAMA_CONSOLE_USERNAME / NAKAMA_CONSOLE_PASSWORD on first use, caches the JWT, and refreshes when it expires. You don't call a login tool.

  • Client API: authenticate endpoints use HTTP Basic with NAKAMA_SERVER_KEY. Every other client endpoint needs a player session — call nakama_authenticate first; the session token is held in memory for the rest of the connection.

  • RPCs: nakama_call_rpc JSON-encodes the payload as Nakama's REST gateway expects. Pass http_key to call an RPC without a player session.

Usage examples (what to ask Claude)

  • "Search Nakama for how to ban an account, then ban user <uuid>."

  • "List the 10 most recent players whose username contains test."

  • "Show me server status and current latency."

  • "Authenticate as device demo-1, then write a storage object in collection saves."

  • "Call the healthcheck RPC."

Troubleshooting

When in doubt, ask Claude to run nakama_healthcheck first — it probes both API surfaces and verifies admin login, and pinpoints which side is failing.

Symptom

Likely cause & fix

Failed to reach Nakama at http://127.0.0.1:7350

Nakama isn't running or host/port/SSL are wrong. Start it (docker compose up -d --wait) and check NAKAMA_HOST / NAKAMA_PORT / NAKAMA_USE_SSL.

No player session yet … call nakama_authenticate first

A client (:7350) endpoint was used without a session. Run nakama_authenticate (device/custom/email) before other player calls.

Console login did not return a token

Wrong admin creds. Check NAKAMA_CONSOLE_USERNAME / NAKAMA_CONSOLE_PASSWORD (defaults admin / password).

Client authenticate returns HTTP 401

Wrong NAKAMA_SERVER_KEY (default defaultkey).

Unknown action_id '…'

Use nakama_search_actions to find the exact id; the error also suggests close matches.

HTTP mode: every /mcp request returns 401

Missing/incorrect Authorization: Bearer <MCP_AUTH_TOKEN> header.

HTTP mode: server won't start, "Refusing to bind …"

You bound a non-loopback host without MCP_AUTH_TOKEN. Set a token, or bind 127.0.0.1.

Tools don't appear in your MCP host

Point the host at the absolute path to dist/index.js, run npm run build first, and restart the host (configs are read at startup).

The server logs to stderr only (stdout is the protocol stream). In Claude Desktop, check the MCP logs; for the integration test set VERBOSE=1.

Testing against a real Nakama

A docker-compose.yml (Nakama 3.37.0 + CockroachDB) and a live integration test are included.

docker compose up -d          # start Nakama + DB (wait until healthy)
npm run build
npm run test:integration      # drives the MCP server over stdio against the live server
npm run test:http-integration # same, but over the streamable-HTTP transport (SDK client)
docker compose down -v        # stop and wipe

The stdio test exercises the full path end to end: tools/list, console auto-login + status, list accounts, player device authentication, GetAccount, and a storage write/read round-trip. The HTTP test drives the same live backend over the streamable-HTTP transport and also verifies the per-session player-session isolation that only the HTTP transport provides (each MCP session gets its own NakamaClient / player session). Both print a PASS/FAIL summary and exit non-zero on any failure, so they are CI-friendly. Set VERBOSE=1 to see server logs. They honor the same NAKAMA_* env vars as the server (defaults already match the bundled compose).

Continuous integration

.github/workflows/ci.yml runs on every push and PR:

  • smoke — npm ci → build → resolve + redact + smoke + http + http-reaper + version (unit + stdio/HTTP protocol surface; no Nakama). Fast.

  • integration — boots Nakama + CockroachDB with docker compose up --wait, then runs npm run test:integration, dumps server logs on failure, and tears down.

Run the same checks locally:

npm test                   # full fast suite, no server needed
npm run test:integration   # needs `docker compose up -d` (stdio)
npm run test:http-integration  # needs `docker compose up -d` (HTTP transport)

Regenerating the API catalog

The bundled data/catalog.json is generated from Nakama's upstream OpenAPI (Swagger 2.0) specs. regen-catalog also resolves request-body $refs into inline field schemas, so nakama_search_actions shows Claude the exact fields (name, type, required, description — including nested objects) each POST/PUT body expects.

Run it on your machine (needs network) to refresh and fully enrich the catalog:

npm run regen-catalog            # uses master
npm run regen-catalog -- v3.37.0 # a specific git ref/tag

The resolver is covered by a unit test (npm run test:resolve).

Install as a desktop extension (MCPB)

For zero-prerequisite installs (no Node, no npm, no build), package the server as an MCPB bundle and install the single file.

npm run mcpb        # builds mcpb-build/ and packs dist-mcpb/nakama-mcp.mcpb

npm run mcpb runs two steps you can also run separately:

  • npm run mcpb:build — type-checks, bundles the server with esbuild into mcpb-build/server/index.mjs, and stages manifest.json, data/catalog.json, and package.json (the server reads its version from it).

  • npm run mcpb:pack — packs mcpb-build/ into dist-mcpb/nakama-mcp.mcpb (validates the manifest). A plain cd mcpb-build && zip -r ../dist-mcpb/nakama-mcp.mcpb . also works.

Then drag dist-mcpb/nakama-mcp.mcpb onto Claude Desktop to install. The installer prompts for the connection settings declared in manifest.json (host, ports, HTTPS, server key, console username/password); the server key and console password are stored in the OS keychain.

MCPB is the right choice when Nakama runs on the user's own machine/localhost. If you target a shared or cloud Nakama, a remote HTTP server is the better distribution path (see below).

Distribution / upgrade path

Stdio (the default) is the fastest shape to prototype and run against your own Nakama. Two paths cover wider distribution:

  • MCPB bundle — package the server with its Node runtime so it installs without prerequisites (best when it still needs to reach a Nakama the user runs locally).

  • Remote streamable-HTTP — already built in (MCP_TRANSPORT=http); host it once behind a URL (best if it targets a shared/cloud Nakama). Add OAuth in front if you need more than the static bearer token.

The tool layer and Nakama client are transport-agnostic — both transports build the same server via buildMcpServer() in src/server.ts.

Security & disclaimer

This server gives an AI model real, write-capable access to your Nakama instance. nakama_execute_action can call any operation in the catalog, and the console (:7351) tools act with admin authority — they can write/delete storage, send notifications, and ban or unban accounts. Treat it accordingly:

  • Point it at a dev/staging Nakama, not production, until you trust the workflow. Operations are real and some are irreversible.

  • Keep credentials in your MCP host's env/secret store, not in committed files. The server key and console password are secrets; error output is scrubbed of them (plus JWTs and Basic/Bearer headers) before it reaches the model, but don't paste them into prompts.

  • Remote HTTP: always set MCP_AUTH_TOKEN, and don't expose the endpoint without TLS in front. A non-loopback bind without a token is refused by design.

  • No telemetry. The server makes network calls only to the Nakama you configure — nothing is sent to any third party.

This is an independent, community integration — not an official Heroic Labs product. Use at your own risk; see SECURITY.md to report a vulnerability privately.

Contributing & security

  • Contributions welcome — see CONTRIBUTING.md for dev setup and the two-tier test workflow.

  • Changes are tracked in CHANGELOG.md.

  • Found a security issue? Please report it privately — see SECURITY.md. Don't open a public issue.

License

Apache-2.0 — see LICENSE. Nakama is a trademark of Heroic Labs; this is an independent integration.

Available Tools

14 tools
nakama_authenticateAuthenticate a player (client API)A

Establish a player session for the client API (:7350). Required before calling other client/player endpoints. Supports device, custom, or email auth. The session token is held in memory for subsequent calls.

Inputs: method (required), id, email, password, +2 more.

nakama_ban_accountBan a player account (console)B
Destructive

Ban a player account by user ID via the console API.

Inputs: id (required).

nakama_call_rpcCall a Nakama server RPCA

Invoke a registered runtime RPC function by id over the client API. Pass payload as a JSON object or string; it is encoded as the gateway expects. Provide http_key to call an RPC without a player session; otherwise authenticate first with nakama_authenticate.

Inputs: id (required), payload, http_key.

nakama_console_get_accountGet a player account (console)A
Read-only

Fetch a single player account (profile, wallet, devices, linked logins) by user ID via the console API.

Inputs: id (required).

nakama_console_get_statusGet server status (console)A
Read-only

Return Nakama node status and lightweight service metrics (CPU, memory, latency, presences) via the console API.

Inputs: no named parameters.

nakama_console_list_accountsList player accounts (console)A
Read-only

List/search player accounts via the console API. Optional filter by user ID or username.

Inputs: filter, tombstones, cursor, auto_paginate, +1 more.

nakama_console_list_storageList storage objects (console)A
Read-only

List storage objects via the console API, optionally filtered by collection, key, and/or owner user ID.

Inputs: collection, key, user_id, cursor, +2 more.

nakama_execute_actionExecute a Nakama API actionA
Destructive

Execute any Nakama operation by its action_id (from nakama_search_actions). Provide path_params, query_params, and/or body as needed. Auth is handled automatically: console actions auto-login with configured admin credentials; client actions use the player session from nakama_authenticate; authenticate endpoints use the server key. For calling server RPCs prefer nakama_call_rpc (it encodes the payload correctly).

Inputs: action_id (required), path_params, query_params, body, +2 more.

nakama_healthcheckCheck Nakama connectivityA
Read-only

Probe both APIs: the client /healthcheck endpoint and a console status call (which also verifies admin login). Returns a per-surface reachability report. Use this first when calls are failing.

Inputs: no named parameters.

nakama_search_actionsSearch Nakama API actionsA
Read-only

Search the Nakama API catalog (179 operations: 87 client, 92 console) by natural-language intent and get matching action IDs, HTTP method/path, summaries, and parameter schemas. Use this to discover the action_id you then pass to nakama_execute_action. Results include resolved request-body field schemas when available. Examples: 'list players', 'write storage object', 'leaderboard records', 'ban account', 'active matches'.

Inputs: query (required), surface, limit.

nakama_send_notificationSend a notification (console)B

Send an in-app notification to a player via the console API. Use a positive app-defined code (<=0 is reserved).

Inputs: user_id (required), subject (required), content, code, +1 more.

nakama_unban_accountUnban a player account (console)A

Remove a ban from a player account by user ID via the console API.

Inputs: id (required).

nakama_write_leaderboard_recordWrite a leaderboard record (client)A

Submit a score to a leaderboard as the authenticated player (call nakama_authenticate first).

Inputs: leaderboard_id (required), score (required), subscore, metadata.

nakama_write_storage_objectWrite a storage object (client)A

Write or update a single storage object as the authenticated player (call nakama_authenticate first). Pass value as an object or JSON string. Use version '*' to require the object not already exist.

Inputs: collection (required), key (required), value (required), version, +2 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 14 tools

    Disambiguation4/5

    Most tools have clear purposes, with console and client operations separated by naming. However, nakama_call_rpc and nakama_execute_action overlap in functionality, potentially causing confusion about which to use for RPC calls.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern in snake_case, with console operations consistently prefixed by 'console_' and client operations by no prefix. This makes the set predictable and easy to navigate.

    Tool Count5/5

    With 14 tools, the count is well-scoped for a game backend server covering authentication, account management, storage, leaderboards, notifications, RPCs, and healthcheck. This is within the ideal 3–15 range.

    Completeness5/5

    The tool set covers common tasks directly and provides a generic search-execute mechanism that can invoke all 179 Nakama API operations, ensuring no dead ends. Minor omissions like storage delete are handled via execute_action.

    Related MCP Connectors

    Related MCP Servers