魂斗罗 MCP Demo

魂斗罗 MCP Demo

Enables creating a Contra-style game session that can be played inline in MCP-compatible clients or via a browser fallback URL.

Category
Visit Server

README

魂斗罗 MCP Demo

This project follows the architecture from Chris Nager's DOOM MCP App write-up, but uses an original placeholder browser game with Contra-style horizontal shooting.

The important part is not "MCP creates a game." The point is:

MCP can return a live app UI, not just text or JSON. In compatible clients, the game appears inside the conversation itself.

No original Contra assets, music, characters, levels, or ROM data are included.

Main Flow

  • create_game_session: creates an inline game session and returns MCP App metadata so compatible hosts can render the game inline. It intentionally does not expose the browser fallback URL.
  • get_game_launch_url: creates a signed /game/play?token=... URL for hosts that cannot render MCP Apps inline.
  • /game/play?token=...: browser fallback route. The token is enough to boot the same game session without durable server-side session storage.
  • ui://contra-style/mcp-app.html: the inline MCP App resource. It listens for the create_game_session tool result, extracts the session, and runs the game directly in the host iframe.

Optional extension tools:

  • update-game-state: the MCP App can publish score, HP, position, enemies, ammo, and stage.
  • get-game-state: reads the latest state.
  • suggest-next-move: returns a Chinese gameplay suggestion from the latest state.

Run

npm install
npm run build
npm run serve

MCP endpoint:

http://localhost:3001/mcp

Use From Codex Or Another MCP Host

Ask the host to call:

create_game_session

If the host supports MCP Apps, it should render the game inline from:

ui://contra-style/mcp-app.html

That is the primary demo: the host calls a tool, and the tool result causes a playable game UI to appear in the chat surface. Do not show or open a fallback link in this path.

If inline rendering is unavailable, call:

get_game_launch_url

Then open the returned /game/play?token=... URL.

Use From Claude Desktop

Claude Desktop renders MCP App UI resources inline in the chat (the client advertises the io.modelcontextprotocol/ui capability with text/html;profile=mcp-app). The matching local config:

~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "contra-demo": {
      "command": "npx",
      "args": ["-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--allow-http"]
    }
  }
}

The mcp-remote bridge runs as a stdio child process inside Claude Desktop and forwards JSON-RPC to the local HTTP endpoint. The --allow-http flag is required because mcp-remote defaults to refusing non-HTTPS URLs. Quit and reopen Claude Desktop after editing the config, then ask Claude to call create_game_session — the playable game appears as a widget in the conversation.

Note: the Custom Connectors UI on claude.ai (web) is Remote MCP — those requests originate from Anthropic's servers and cannot reach localhost. Use Claude Desktop with the file-based config above for a local URL, or expose the server over a public tunnel for the web Connector route.

Run as a background service (macOS LaunchAgent)

If you start the server from an interactive shell or a Claude Code session, it dies when you quit that process. To keep it always-on, register it with launchd:

~/Library/LaunchAgents/com.contra-demo.mcp.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>             <string>com.contra-demo.mcp</string>
    <key>ProgramArguments</key>  <array>
        <string>/PATH/TO/npm</string>
        <string>run</string>
        <string>serve</string>
    </array>
    <key>WorkingDirectory</key>  <string>/PATH/TO/deep-mcp</string>
    <key>EnvironmentVariables</key><dict>
        <key>PATH</key>          <string>/PATH/TO/node/bin:/usr/bin:/bin</string>
    </dict>
    <key>RunAtLoad</key>         <true/>
    <key>KeepAlive</key>         <true/>
    <key>StandardOutPath</key>   <string>/tmp/contra-demo-mcp.out.log</string>
    <key>StandardErrorPath</key> <string>/tmp/contra-demo-mcp.err.log</string>
</dict>
</plist>
launchctl load -w ~/Library/LaunchAgents/com.contra-demo.mcp.plist     # start + auto-start at login
launchctl list | grep contra-demo                                       # check
launchctl unload -w ~/Library/LaunchAgents/com.contra-demo.mcp.plist   # stop

launchd is independent of any GUI app, so quitting Claude Desktop / Terminal / IDE no longer kills the server. KeepAlive=true also restarts it if it crashes.

Browser Fallback

After npm run build && npm run serve, call get_game_launch_url and open the returned URL.

For quick UI development only:

npm run dev

That opens the game without a signed session, so it is useful for visual testing but not the main demo flow.

Controls

  • Move: WASD or arrow keys
  • Shoot: Space or J
  • Restart: R

Video Talking Points

  • This is modeled after the DOOM MCP App architecture, not a from-scratch game-dev tutorial.
  • The headline is: MCP can return an interactive game UI inside the conversation.
  • The primary path is inline-only; the signed browser launch URL is exposed only by get_game_launch_url.
  • The MCP App runs the game directly in the host iframe; it does not iframe another page inside the app.
  • The real MCP lesson: protocol + UI resource + signed launch flow can turn a web capability into an AI-client-native app.

Verification

npm run check
npm run build
curl -sS -X POST http://localhost:3001/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  --data '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured