GD MCP / DOCUMENTATION

Set up GD MCP.

Connect your Geometry Dash bridge, activate your workspace and make your first tool call.

Start the Geometry Dash bridge

Launch Geometry Dash with Kinetic and its Python environment, then enable the MCP server from the game's Python tooling. The bridge runs with the game and stops when the game closes.

Bridge address
http://127.0.0.1:8765/mcp

Start GD MCP

Install the .NET 8 runtime, a compatible .NET SDK and Node.js. From the repository, run run-all-debug.bat on Windows or ./run-all-debug.sh on Linux. The API uses port 5000 and the website uses port 3000.

The server always keeps a built-in admin account. It is created on first start from Bootstrap__AdminUsername and Bootstrap__AdminPassword, and promoted back if anyone demotes it. Change its password in Settings after your first sign-in. Admins can promote other accounts from the Admin page.

Get tool access

Create an account. Accounts can browse and publish mods straight away. Running tools on the game bridge, including Python, needs tool access: an admin turns it on for your account from the Admin page. Admins always have it.

Sign in from the game

gdmcp signs in with the same username or email and password as the website. The backend answers with a JWT that the game sends as Authorization: Bearer to the MCP gateway and the mod index.

Sign in
POST /api/site/v1/auth/game/login
{ "login": "pixel_wizard", "password": "...", "device": "Desktop PC" }

-> {
  "token": "<access JWT, about an hour>",
  "expiresAt": "...",
  "refreshToken": "<keep it secret>",
  "refreshExpiresAt": "<7 days from now>",
  "sessionExpiresAt": "<1 year from now>",
  "session": { ... },
  "user": { ... }
}

Send the access token as Authorization: Bearer on every request. When it expires, trade the refresh token for a new pair and keep the new refresh token: each one works once. A refresh token unused for 7 days expires, and a sign-in never lasts more than a year, so the player signs in again after a week away.

Refresh
POST /api/site/v1/auth/game/refresh
{ "refreshToken": "<the latest one>" }

-> a new token and a new refreshToken (the old one stops working)
Check the session
GET /api/site/v1/auth/game/session
Authorization: Bearer <JWT>

401 { "code": "signed_in_elsewhere", "title": "Your account signed in to GD MCP on another device." }

Connect your agent

Sign in with your username or email and password to get a JWT, then point your HTTP MCP client at the gateway with that token. Keep the token in your client's secret storage and never commit it.

Get a token
curl -X POST http://localhost:5000/api/site/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{ "login": "[email protected]", "password": "..." }'
.mcp.json
{
  "mcpServers": {
    "geometry-dash": {
      "type": "http",
      "url": "http://localhost:5000/api/mcp/v1",
      "headers": {
        "Authorization": "Bearer <YOUR_JWT>"
      }
    }
  }
}

The gateway supports stateless Streamable HTTP, initialization, tool discovery and tool calls. Tokens expire after the configured lifetime; sign in again for a new one. OAuth discovery and automatic refresh are not implemented yet.

Make a first call

Open Tools and run read_skill with empty arguments to list the bridge's editor notes. Then try screenshot to see the game. Every form is built from your running bridge's schemas.

Troubleshooting

Bridge offline
Check that the game is running, Python MCP is enabled and Mcp__Endpoint points to it.
No tool access
Ask an admin to turn on tool access for your account.
Signed in elsewhere
gdmcp signed in with your account on another device. Sign in again here, which signs the other device out.
Session expired
Log in again. Changing your password signs out every token.
Too many requests
Wait a minute after repeated sign-in attempts. Each account can run two MCP requests at once.

Hosting

Put HTTPS in front of both services, set a random production Jwt__Key of at least 32 characters, configure BACKEND_URL for the website and back up the SQLite database. Keep the raw game bridge private: direct access skips this gateway's licensing.