Kungfu
FreeNot checkedA humorous MCP server that catalogs martial-arts factions and narrates sparring matches between them.
About
A humorous MCP server that catalogs martial-arts factions and narrates sparring matches between them.
README
🎬 Live presentation: https://davidcai.github.io/kungfu-mcp/presentations/
A humorous Model Context Protocol server, in TypeScript, that catalogs the major factions of the kung fu world (the martial-arts underworld) and narrates sparring matches between them.
It demonstrates the three MCP primitives side by side:
- Tools (model-controlled) —
list_factions,get_faction,spar,spar_arena. - Resources (application-driven context) —
kungfu://kungfu/rosterandkungfu://factions/{id}profiles as markdown. - Apps (interactive UI rendered in chat) —
spar_arenalaunches an inline arena built on aui://resource that calls tools back on the server.
The server runs on WebStandardStreamableHTTPServerTransport over Hono (Apps require HTTP transport).
Starting the MCP server
npm install
npm start # builds (server + UI), then serves → http://localhost:3001/mcp
The server logs kungfu-mcp listening on http://localhost:3001/mcp.
Fast iteration (no build):
npm run dev # tsx server.ts — runs the server directly
Note:
npm run devskips the UI build. Tools and resources work immediately; thespar_arenaUI returns an error untilnpm run buildhas produceddist/mcp-app.htmlat least once.
| Script | What it does |
|---|---|
npm run build |
tsc (server → build/) + tsc -p tsconfig.ui.json (UI typecheck) + vite build (UI → dist/mcp-app.html) |
npm start |
npm run build && node build/server.js → http://localhost:3001/mcp |
npm run dev |
tsx server.ts (run the server without building) |
npm run inspect |
Launch the MCP Inspector |
Inspecting the MCP server
The MCP Inspector is the fastest way to verify tools, resources, and templates. It is not an app host — it cannot render the spar_arena UI — but everything else is testable.
With the server running (npm start), in another terminal:
npm run inspect
In the Inspector UI:
- Transport Type:
HTTP - URL:
http://localhost:3001/mcp - Connect
Then exercise each primitive:
- Tools tab — call
list_factions,get_faction(id: "shaolin"),spar(faction_a: "shaolin", faction_b: "wudang"),spar_arena. - Resources tab — read
kungfu://kungfu/roster; browse thekungfu://factions/{id}template (id autocompletes).
list_factions and spar return both humorous text (for the LLM) and structuredContent (for the UI) in a single result.
Using kungfu-mcp in Cursor
Cursor 2.6+ is a native MCP Apps host — point it at the running server and spar_arena renders inline in the chat as an interactive iframe. Add the server to ~/.cursor/mcp.json (or project .cursor/mcp.json):
{ "mcpServers": { "kungfu": { "type": "http", "url": "http://localhost:3001/mcp" } } }
Then call spar_arena, pick two factions (e.g. Neo vs. Morpheus), and press Begin the Spar.
Progressive enhancement: hosts without MCP Apps support just get
spar_arena's text result, so the server stays usable everywhere. Other app-capable hosts (e.g. Claude web/Desktop via acloudflaredtunnel + paid plan) also render the arena.
What the server exposes
Tools
| Tool | Arguments | What it does |
|---|---|---|
list_factions |
(none) | Roster markdown + structuredContent ({ factions }). |
get_faction |
id: string |
Full profile for one faction as markdown. |
spar |
faction_a, faction_b: string, optional champion_a, champion_b: string |
Biased narration + structuredContent ({ rounds, verdict, winnerId }). Each round randomly picks a signature technique per side; the winner has the higher sum of picked techniques' threats. Champion names (e.g. "Neo") replace faction names in the narration. |
spar_arena |
(none) | Launches the interactive Spar Arena UI (MCP App). |
Resources
| URI | Type | What it returns |
|---|---|---|
kungfu://kungfu/roster |
static | The full roster as markdown. |
kungfu://factions/{id} |
template | Per-faction profile as markdown (list + complete). |
ui://spar-arena/app.html |
app UI | The bundled Spar Arena HTML. |
Project layout
server.ts # HTTP entry: hono + @hono/node-server + WebStandardStreamableHTTPServerTransport on :3001/mcp
vite.config.ts # react() + viteSingleFile(), input mcp-app.html → dist/mcp-app.html
mcp-app.html # UI shell: #root div + src/ui/main.tsx script tag
src/ # one file per MCP primitive:
tools.ts # Tools — list_factions, get_faction, spar
resources.ts # Resources — kungfu://kungfu/roster + kungfu://factions/{id}
app.ts # App — spar_arena tool + ui://spar-arena/app.html resource
ui/ # React UI (useApp hook from @modelcontextprotocol/ext-apps/react)
format.ts # shared markdown formatting (tools, resources, and the UI)
data.ts # KungfuFaction[] dataset (the heart of the humor)
Build outputs: build/server.js (run by npm start) and dist/mcp-app.html (the ui:// resource).
Notes
- A demo. All factions, fun facts, and spar outcomes are fabricated for entertainment.
- Tools and resources render the same markdown via
src/format.ts; the primitives differ only in who decides to fetch the content. - The server is HTTP-only (stdio was dropped because Apps require HTTP).
Installing Kungfu
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/davidcai/kungfu-mcpFAQ
Is Kungfu MCP free?
Yes, Kungfu MCP is free — one-click install via Unyly at no cost.
Does Kungfu need an API key?
No, Kungfu runs without API keys or environment variables.
Is Kungfu hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Kungfu in Claude Desktop, Claude Code or Cursor?
Open Kungfu on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectCompare Kungfu with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
