shooting-game
Click on "Deploy 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., "@shooting-gameJoin my match with code 4521 and play to win!"
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.
shooting-game MCP server
Lets Claude (via Claude Desktop or Claude Code) join a real match of the shooting game as the second player and actually play it — reading the arena through a real, live browser and moving/shooting through the same inputs a human would use.
It does not re-implement any game logic. Each tool call drives a
headless (or visible) Chromium instance pointed at the real Angular app
via Playwright, reading state out of the DOM
and sending real keyboard input — the same trick used to test the
vs computer bot in this repo. That keeps it perfectly in sync with
whatever the game actually does, with nothing to duplicate or drift.
How a match works
A human opens the game and clicks "vs claude (mcp)" on the home screen. This creates a normal friendly match and shows a match code (the same underlying flow as "create match", just with different instructions on screen).
The human gives Claude that code.
Claude calls
join_matchwith the code — this is exactly the "join match by id" flow a second human player would use. Claude is always the second player to join (PLAYER_B).Claude calls
get_state,move,shoot, and optionallyscreenshotto actually play.
Related MCP server: the-mogiyoon-mcp
Setup
npm install # also downloads a Chromium build for Playwright
npm run test:smoke # optional: verifies the whole pipeline against a live gameEnvironment variables
Variable | Default | Purpose |
|
| Base URL of the Angular client to connect to. Point this at |
|
| Set to |
Register with Claude Code
claude mcp add shooting-game -- node /absolute/path/to/mcp-server/index.js(or add it to a project's .mcp.json with the same command/args.)
Register with Claude Desktop
Add an entry to claude_desktop_config.json:
{
"mcpServers": {
"shooting-game": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/index.js"],
"env": {
"GAME_CLIENT_URL": "https://shooting-game-eight.vercel.app",
"MCP_HEADLESS": "false"
}
}
}
}Hosted connector (claude.ai)
There's a second entry point, http-server.js, that serves the same tools
over the MCP Streamable HTTP transport instead of stdio — this is what lets
someone add the game as a custom connector in claude.ai (Settings →
Connectors → Add custom connector), rather than only from Claude Code/Desktop
on the machine that's running the process.
Unlike the stdio entry point, this one is multi-tenant: it hands each
connecting client its own GameSession (so unrelated users don't share a
browser/match), tracked by the standard Mcp-Session-Id session header. An
idle session (no tool calls for SESSION_IDLE_TIMEOUT_MS, default 15
minutes) has its browser closed automatically to free resources.
npm run start:http # listens on $PORT (default 3000), endpoint is POST /mcpDeploying (Render): this needs a persistent Node process with Chromium
installed, not a serverless function — build the included Dockerfile
(based on the official mcr.microsoft.com/playwright image, pinned to the
same Playwright version as package.json) as a Render Web Service. No
extra configuration is required: Render sets $PORT automatically, and the
image already sets MCP_HEADLESS=true.
Then in claude.ai: Settings → Connectors → Add custom connector → paste
https://<your-render-app>.onrender.com/mcp as the URL, no authentication.
Resource limits: because the connector has no auth, anyone with the URL can open a session, each of which holds a real Chromium process. Two knobs guard against that:
Variable | Default | Purpose |
|
| Hard cap on simultaneous browser sessions across all connected clients; |
|
| How long a session can go without a tool call before its browser is closed and the slot freed. |
Tools
Tool | Purpose |
| Join a friendly match by code (or random matchmaking if omitted). Launches the browser session. |
| Round, score, your position/health, opponent's position/health, arena size, any round/match-end announcement. |
| Hold |
| Fire in the direction you last moved. |
| PNG of the current arena, if Claude would rather look than read coordinates. |
| Disconnects and closes the browser. |
There is no separate aim. The game only supports firing in whichever of the 4 cardinal directions you last moved in — rotation and shot direction are the same thing. To land a hit, get on the same row or column as the opponent (within roughly half a player-width) and shoot while facing that way.
Notes
The stdio entry point (
index.js) holds exactly one browser session for its whole process lifetime — callleave_matchbeforejoin_match-ing again if you want a clean session. The HTTP entry point (http-server.js) gives each connected client its own session instead (see above).Because the real Node relay server has no server-side game state, hit detection happens independently in each player's own browser from the same relayed inputs. There's no separate "who's the source of truth" concern here beyond what the game already has for any two human players.
Available Tools
6 toolsget_stateGet game stateA
Read the current match state: round, score, your health and position, your opponent's health and position, arena size, and any round/match-end announcement. Positions are pixel coordinates, arena origin top-left.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries the burden. The verb 'Read' and the absence of any side-effect language transparently indicate a non-destructive operation, though it does not mention potential error cases or prerequisites like an active match.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct, lists the state components in a natural flow, and adds useful coordinate-system context without redundancy. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must convey the return content. It does so comprehensively, including the coordinate origin caveat. Slight ambiguity about the format of 'round/match-end announcement' and whether health/position are numeric, but overall sufficient for a simple read tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, and the schema coverage is 100%. Baseline for 0 parameters is 4, and the description correctly avoids inventing parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it 'Read[s] the current match state' and enumerates the exact data returned (round, score, health, position, arena size, announcements), distinguishing it from action-oriented siblings like move or shoot.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implicitly clear that this is the observation tool among action siblings, but does not explicitly say 'use this when you need to inspect state' or contrast with screenshot for visual info. Lacks an explicit when-not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
join_matchJoin matchA
Join a friendly 1v1 match of the shooting game as the second player, using the match code the human shares with you. Launches a browser and connects to the live game. Omit the code to enter random matchmaking instead.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | The match code the human gave you, e.g. from the "vs Claude" screen. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the key side effect ('Launches a browser and connects to the live game') and the optional random matchmaking path. However, it does not mention what happens on invalid codes, wait times, or how the agent learns whether the join succeeded.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with zero filler. The core action is front-loaded, and the optional-code behavior is stated immediately after without unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool with one optional parameter and no output schema, the description covers the essential context: what the tool does, how it behaves, and the optional mode. It would be slightly stronger if it noted the post-join outcome, but the core usage is adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already describes the 'code' parameter. The description adds meaningful behavioral context by explaining that omitting the code triggers random matchmaking, which goes beyond the schema's static parameter description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('join'), a specific resource (a friendly 1v1 match as the second player), and the mechanism (using a match code). It clearly distinguishes this tool from the sibling game-control tools by naming the match-joining action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells the agent when to use the tool ('using the match code the human shares with you') and provides the alternative behavior when no code is available ('Omit the code to enter random matchmaking instead'). This is precise and leaves no ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
leave_matchLeave matchA
Disconnect from the current match and close the browser session.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations to carry the burden, the description discloses the key behavioral side effect—closing the browser session—beyond the basic 'leave match' idea. It does not mention reversibility or downstream effects, but the main consequence is explicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence states the action and its consequence with no filler. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter action with no output schema, the description is nearly complete: it names the action and the important browser-session consequence. It could add explicit guidance about ending the session permanently, but this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so parameter semantics are trivial. The baseline for zero-parameter tools is 4, and the description has nothing that needs to clarify about inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description specifies a concrete action ('Disconnect from the current match') and a distinct consequence ('close the browser session'), clearly separating it from siblings like join_match and get_state. There is no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The action itself implies the use case: call it when the agent wants to leave the current match. However, it does not explicitly state when not to use it or contrast it with alternatives, so the guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
moveMoveA
Move in one direction for a short duration. The player steps ~10px roughly every 20ms while the key is held and rotates to face that direction, which is also the direction shoot() will fire in.
| Name | Required | Description | Default |
|---|---|---|---|
| holdMs | No | How long to hold the direction, in milliseconds. Default 150. | |
| direction | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does so well by detailing step distance, timing, rotation, and the relationship to shooting direction. It does not mention edge cases like obstacles or boundaries, but core behavior is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, tightly packed with relevant behavioral details. There is no redundant or extraneous wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides enough context for a simple movement action, including timing, distance, and interaction with shooting direction. It lacks only minor environmental details such as collision or boundary behavior, which are not essential for basic usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema documents holdMs with units and bounds, and direction has an enum, so both parameters are reasonably clear. The description adds context for direction by linking it to player orientation and shooting, but it does not deeply elaborate on how holdMs affects movement beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: moving the player in one direction for a short duration. It also specifies the movement cadence and that the player rotates to face the chosen direction, making the action unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what the tool does but does not explicitly state when to use it instead of sibling tools. Usage is implied rather than directly guided, though the movement semantics are clear enough for basic selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screenshotScreenshot the arenaA
Get a PNG screenshot of the current arena, so you can look at the match instead of only reading coordinates.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral disclosure. It states the output is a PNG and captures the current arena, which implies a read-only operation. But it does not disclose how the PNG is returned, whether the action has side effects, or any latency/cost. For a simple no-parameter tool this is adequate but minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence: the core action ('Get a PNG screenshot of the current arena') comes first, followed by a brief rationale. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter visual-read tool, the description covers what it returns (PNG), what it captures (current arena), and why to use it (visual inspection instead of coordinates). The only missing detail is the mechanics of the returned image (e.g., file path, base64, size), which would be useful but is not critical given no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and 100% schema coverage, so there is nothing for the description to add beyond confirming the invocation requires no arguments. Baseline of 4 for parameterless tools applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get a PNG screenshot of the current arena.' It clearly distinguishes from sibling get_state by stating the screenshot lets you 'look at the match instead of only reading coordinates,' so an agent can tell it apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the use case explicitly: use screenshot when you need a visual view of the arena, as opposed to reading coordinates (presumably from get_state). However, it doesn't name alternative tools or provide explicit when-not-to-use guidance, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shootShootA
Fire in whichever direction you last moved (there is no separate aim — facing is set by your last move). Holding longer fires multiple shots.
| Name | Required | Description | Default |
|---|---|---|---|
| holdMs | No | How long to hold the trigger, in milliseconds. Default 200. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description explains key behavior: direction from last move, no separate aim, holding longer fires multiple shots. Could mention ammo/cooldown but not critical.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, direct, no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given simple tool, description covers action and parameter. Missing details like ammo but not necessary for basic use. No output schema so no return description needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema describes holdMs fully; description adds effect of holding longer (multiple shots), adding meaning beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action ('Fire') and specific behavior (direction based on last move). Distinguishes from siblings by describing its unique mechanic.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. Gives mechanics but not selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v1.0.0- First observed
get_state - First observed
join_match - First observed
leave_match - First observed
move - First observed
screenshot - First observed
shoot
TDQS
Scored across 6 tools
Each tool targets a distinct action: joining, reading structured state, moving, shooting, screenshotting, and leaving. get_state and screenshot both provide observation but are clearly separated as text data vs visual image, so no real ambiguity.
join_match, get_state, and leave_match follow a clear verb_noun pattern, and move/shoot are intuitive imperative verbs. screenshot is a minor deviation because it is a noun used as an imperative rather than a verb_object form like take_screenshot.
Six tools is well-scoped for a real-time browser game agent: lifecycle, movement/action, and observation are covered without redundant utilities. Every tool earns its place.
The set covers the full match lifecycle: joining, observing via both state and screenshot, acting via move and shoot, and leaving. The shoot-direction note confirms aiming is handled through movement, so no separate aim tool is needed.
Maintenance
Related MCP Connectors
Build browser games on gamedev.pl from your coding agent.
Real Chrome for agents: start a browser, read pages as numbered markdown, click, type, hand off.
Free Streamable HTTP MCP arena for 1v1 AI agent skill battles and Gladiator Badges.
Play Werewolf against other AI agents. join once, then loop observe/act. Public ELO leaderboard.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Claude to fully control a Windows desktop with native screen capture, low-level input injection, game-grade input, and play-testing capabilities.MIT
- FlicenseNot gradedqualityDmaintenanceEnables controlling a game character, drawing on a canvas, and running chemistry experiments via natural language commands to Claude.-
- AlicenseNot gradedqualityBmaintenanceChrome extension + MCP bridge that gives Claude control over your real browser via CDP, enabling navigation, clicking, typing, scrolling, screenshots, and JS execution with a visible cursor and tab-bring-to-front.1MIT
- FlicenseAqualityCmaintenanceGives Claude control of a real, headed Chromium browser via Playwright, enabling web navigation, clicking, typing, screenshots, and JavaScript evaluation.8-