gdansk
React Frontends for Python MCP Servers
Gdansk: React Frontends for Python MCP Servers
[!WARNING]
This project is currently in beta. The APIs are subject to change leading up to v1.0. The v1.0 release will
coincide with the v2.0 release of the python mcp sdk
The name "Gdansk" (pronounced "guh-DANSK") is a nod to the Polish port city's historical role as a bridge between
cultures and trade routes—much like this framework bridges Python backends and React frontends.
Gdansk bridges Python backend logic with React/TypeScript UIs, letting you create rich, interactive tools for Model
Context Protocol (MCP) servers without leaving the Python ecosystem.
Gdansk combines FastMCP for server-side Python logic with React for client-side
interfaces, and uses Rolldown (a Rust-based bundler) to handle all the JavaScript/TypeScript
bundling automatically. Whether you're building data visualization tools, form-based interfaces, or interactive
dashboards for Claude Desktop and other MCP clients, Gdansk provides a straightforward path from Python functions to
polished UIs.
Installation
uv add gdansk
Skill for Coding Agents
If you use coding agents such as Claude Code or Cursor, we recommend adding this skill to your repository:
npx skills add mplemay/gdansk
Examples
- FastAPI: FastAPI-based MCP server integration with mounted app routes.
- get-time: Feature-rich MCP app covering tool calls, messaging, logging, and links.
- ssr: Minimal SSR example using
Amber(ssr=True)with a single tool UI. - shadcn: Todo app example using
shadcn/uicomponents with Gdansk.
Quick Start
Here's a complete example showing how to build a simple greeting tool with a React UI:
Project Structure:
my-mcp-server/
├── server.py
└── views/
├── package.json
└── widgets/
└── hello/
└── widget.tsx
The views folder name is only an example: pass any directory to Amber(..., views=...) (for examplePath(__file__).parent / "frontend").
server.py:
from pathlib import Path
from mcp.server.fastmcp import FastMCP
from mcp.types import TextContent
from gdansk import Amber
import uvicorn
mcp = FastMCP("Hello World Server")
amber = Amber(mcp=mcp, views=Path(__file__).parent / "views")
@amber.tool(name="greet", widget=Path("hello"))
def greet(name: str) -> list[TextContent]:
"""Greet someone by name."""
return [TextContent(type="text", text=f"Hello, {name}!")]
if __name__ == "__main__":
app = amber(dev=True) # Enable hot-reload for development
uvicorn.run(app, port=3000)
views/widgets/hello/widget.tsx:
import { useApp } from "@modelcontextprotocol/ext-apps/react";
import { useState } from "react";
export default function App() {
const [name, setName] = useState("");
const [greeting, setGreeting] = useState("");
const { app, error } = useApp({
appInfo: { name: "Greeter", version: "1.0.0" },
capabilities: {},
});
if (error) return <div>Error: {error.message}</div>;
if (!app) return <div>Connecting...</div>;
return (
<main>
<h2>Say Hello</h2>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter your name..."
/>
<button
onClick={async () => {
const result = await app.callServerTool({
name: "greet",
arguments: { name }
});
const text = result.content?.find(c => c.type === "text");
if (text && "text" in text) setGreeting(text.text);
}}
>
Greet Me
</button>
{greeting && <p>{greeting}</p>}
</main>
);
}
Gdansk mounts your default export into #root automatically and wraps it with React.StrictMode.
Run the server with python server.py, configure it in your MCP client (like Claude Desktop), and you'll have an
interactive greeting tool ready to use.
HTML resources are cached in memory by default. Use Amber(..., cache_html=False) if you need uncached reads (for
example, intentionally dynamic SSR output).
Why Use Gdansk?
Python Backend, React Frontend — Use familiar technologies you already know. Write your logic in Python with type
hints, build your UI in React/TypeScript. No need to learn a new framework-specific language.Built for MCP — First-class support for FastMCP servers. Automatic resource registration, MCP app protocol
handling, and seamless integration with Claude Desktop and other MCP clients.Rust-Powered Bundling — Lightning-fast Rolldown bundler processes your TypeScript/JSX automatically. Hot-reload
in development mode means you see changes instantly without manual rebuilds.Type-Safe — Full type safety across the stack. Python type hints on the backend, TypeScript on the frontend, with
automatic type checking via ruff and TypeScript compiler.Developer-Friendly — Simple decorator API (
@amber.tool()), automatic resource registration, hot-reload dev
mode, and comprehensive error messages. Get started in minutes, not hours.Production Ready — Comprehensive test suite covering Python 3.11-3.14 across Linux, macOS, and Windows. Used in
production MCP servers with proven reliability.
Credits
Gdansk builds on the shoulders of giants:
- Model Context Protocol — Official MCP documentation
- @modelcontextprotocol/ext-apps — React hooks for
MCP apps - Rolldown — Fast Rust-based JavaScript bundler
- PyO3 — Rust bindings for Python
- mcp/python-sdk — Python SDK for MCP server development
- Deno Core — JavaScript runtime that powers Gdansk's Rust runtime
Special thanks to the Model Context Protocol team at Anthropic for creating the MCP standard and the@modelcontextprotocol/ext-apps package.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found