nakama-mcp
The nakama-mcp server provides an MCP interface to a Heroic Labs Nakama game backend, enabling AI models to interact with both the player-facing Client API and the admin Console API across ~180 operations.
Discovery & General Execution
Search API actions (
nakama_search_actions): Find any of the ~180 available Nakama operations by natural-language intent, returning action IDs, HTTP method/path, and parameter schemasExecute any action (
nakama_execute_action): Run any discovered operation by its action ID with support for path params, query params, and request body; supports auto-pagination to follow cursors and merge pages
Player / Client API
Authenticate players (
nakama_authenticate): Establish a player session via device, custom, or email authentication methodsCall server RPCs (
nakama_call_rpc): Invoke registered runtime RPC functions, with optional HTTP key for unauthenticated callsWrite storage objects (
nakama_write_storage_object): Create or update a storage object as the authenticated player, with permission and optimistic-concurrency controlSubmit leaderboard scores (
nakama_write_leaderboard_record): Post a score (with optional subscore and metadata) to a leaderboard as the authenticated player
Admin / Console API
List/search player accounts (
nakama_console_list_accounts): Browse or filter player accounts by user ID or username, with auto-paginationGet a player account (
nakama_console_get_account): Fetch full account details (profile, wallet, devices, linked logins) for a specific user IDList storage objects (
nakama_console_list_storage): Browse storage objects filtered by collection, key, and/or owner, with auto-paginationGet server status (
nakama_console_get_status): Retrieve node status and lightweight service metrics (CPU, memory, latency, presences)Send notifications (
nakama_send_notification): Deliver in-app notifications to a specific player with custom code, subject, and contentBan/unban a player (
nakama_ban_account,nakama_unban_account): Ban or remove a ban from a player account by user ID
Diagnostics
Healthcheck (
nakama_healthcheck): Probe both the client and console API surfaces, verify admin login, and get a per-surface reachability report
Reliability Features
Auto-pagination on list endpoints (merges pages, reports
__pages_fetched/__more_available)Secret redaction: strips server keys, passwords, JWTs, and auth headers from error output before it reaches the model
Automatic console JWT management (auto-login and token refresh)
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@nakama-mcpList the 10 most recent players whose username contains 'test'."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
nakama-mcp
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 |
| read | Find operations by intent → returns action IDs, method/path, params. |
| write | Run any operation by |
| write | Establish a player session (device / custom / email) for client-API calls. |
| write | Call a registered runtime RPC (payload encoded the way the gateway expects). |
| read | List / search player accounts. |
| read | Fetch one player account by user ID. |
| read | List storage objects (filter by collection / key / owner). |
| read | Node status and lightweight service metrics. |
| read | Probe client + console reachability and admin login. |
| write | Write/update a storage object as the authenticated player. |
| write | Submit a score to a leaderboard as the authenticated player. |
| write | Send an in-app notification to a player (console). |
| write | Ban a player account by user ID (console). |
| write | Remove a ban from a player account (console). |
Reliability features
Auto-pagination —
nakama_execute_action,nakama_console_list_accounts, andnakama_console_list_storageacceptauto_paginate: true(+ optionalmax_pages, default 5) to followcursor/next_cursorand merge pages, adding__pages_fetched/__more_availableto the result.Secret redaction — error output is scrubbed of the configured server key / console password, JWTs, and
Basic/Bearerheader values before it reaches the model.Healthcheck —
nakama_healthcheckprobes 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 buildConfiguration
All configuration is via environment variables. Defaults match a stock local Nakama dev setup.
Variable | Default | Notes |
|
| Host for both APIs. |
|
| Client API port. |
|
| Console API port. |
|
| Use |
|
| Server key for client authenticate endpoints. |
|
| Console admin user. |
|
| Console admin password. |
|
| 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.jsCursor / 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.jsover 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 |
|
| Set to |
|
| Bind address. Loopback by default. |
|
| Listen port. |
|
| MCP endpoint path. |
| (unset) | Static bearer token required in |
|
| 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_PASSWORDon 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 — callnakama_authenticatefirst; the session token is held in memory for the rest of the connection.RPCs:
nakama_call_rpcJSON-encodes the payload as Nakama's REST gateway expects. Passhttp_keyto 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 collectionsaves.""Call the
healthcheckRPC."
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 |
| Nakama isn't running or host/port/SSL are wrong. Start it ( |
| A client ( |
| Wrong admin creds. Check |
Client authenticate returns HTTP 401 | Wrong |
| Use |
HTTP mode: every | Missing/incorrect |
HTTP mode: server won't start, "Refusing to bind …" | You bound a non-loopback host without |
Tools don't appear in your MCP host | Point the host at the absolute path to |
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 wipeThe 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 runsnpm 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/tagThe 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.mcpbnpm run mcpb runs two steps you can also run separately:
npm run mcpb:build— type-checks, bundles the server with esbuild intomcpb-build/server/index.mjs, and stagesmanifest.json,data/catalog.json, andpackage.json(the server reads its version from it).npm run mcpb:pack— packsmcpb-build/intodist-mcpb/nakama-mcp.mcpb(validates the manifest). A plaincd 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/Bearerheaders) 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.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mlger/nakama-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server