Getting started
Zero-install first look: the hosted playground is a public toolkit server with a guided tour — call a tool, watch a widget render, chain a pipeline. Nothing to clone.
Then two paths, in the order we recommend them:
- Run the examples — see a complete host working in four commands. Works in a fresh clone, no npm auth.
- Start your own project — consume the published packages outside this repo.
Run the examples first
From the repo root:
corepack enable # the repo pins pnpm via `packageManager`
pnpm install # `prepare` scripts build the package dists
pnpm --filter @miragon/mcp-toolkit-examples run dev:standalonedev:standalone is the standard loop — the workflow mcp-use itself propagates: examples/standalone-host is a plain mcp-use project with installToolkit on top, run through mcp-use dev. The CLI builds the views with HMR and prints the built-in inspector URL (…/mcp/inspector) — call show_tasks_board there. That is the full loop: an MCP tool returning a rendered widget, hot-reloading as you edit the widget sources.
The full three-module host (articles, tasks, orders — the createFrameworkApp Node-adapter path with the visual builder) is:
cp examples/env.example examples/.env # first time only
pnpm --filter @miragon/mcp-toolkit-examples startstart builds the widget bundle and serves on :3010 — see examples/README.md for what each module proves. Smoke-test it from the shell:
curl -sX POST http://localhost:3010/mcp -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools[].name'For fixture-driven UI work without any server or .env, the optional widget playground remains (fixture data, simulated host):
pnpm --filter @miragon/mcp-toolkit-examples dev:widget-playgroundRunning processes individually
dev:host alone expects the widget bundle to exist — run pnpm --filter @miragon/mcp-toolkit-examples build:bundle once first (the one-shot start does this for you). And since the mcp-use 2.x move the Node-adapter host reads the bundle once at boot: after a rebuild, restart it.
Start your own project
The fast way: use the template
Miragon/mcp-toolkit-starter is a self-contained starter — a plain mcp-use project with the toolkit on top: one module with its own tools, one widget, and views/ built and served by the mcp-use CLI — with pinned versions and CI prepared. Click "Use this template", or:
gh repo create my-mcp-server --template Miragon/mcp-toolkit-starter --private --cloneThen follow its README. The starter is an auto-synced mirror of templates/minimal-server in this repo — copying that directory works just as well.
By hand
The packages live on the public npm registry under the @miragon scope, so no .npmrc or token is needed. Install the server package with its peers. mcp-use is pinned exactly (a second copy in the graph breaks the widgets' host context); the other peers are ranges, so your own versions dedupe:
pnpm add @miragon/mcp-toolkit-core mcp-use@2.7.3 zod@^4.4.0For widgets, add the UI package and its peers:
pnpm add @miragon/mcp-toolkit-ui react@^19.2.0 react-dom@^19.2.0
pnpm add -D tailwindcss@^4.3.0Look and language. The UI package renders in the Miragon design system by default, light or dark as the host is: import @miragon/mcp-toolkit-ui/globals.css once in your view's CSS, and give it your brand by overriding role variables only (see white-labeling). Geist and Geist Mono are named first in the font stacks; loading them is opt-in in the package (@miragon/mcp-toolkit-ui/fonts.css), and the starter template imports it. The toolkit's own text follows the host's locale in English or German; your widgets' text is yours, and the tasks example and the starter's views/shared/messages.ts show a typed en/de catalog for it.
The standard path — a plain mcp-use project, toolkit on top
You own a normal mcp-use project (own MCPServer, views/ convention, mcp-use dev / build / start); installToolkit adds the composition features:
// index.ts
import { MCPServer } from "mcp-use"
import { installToolkit } from "@miragon/mcp-toolkit-core/tools"
import { createPlugin as createTasksPlugin } from "./modules/tasks/plugin.js"
const server = new MCPServer({ name: "my-mcp", version: "0.1.0" })
installToolkit(server, { modules: [createTasksPlugin()] })
server.tool({ name: "echo", ... }, handler) // your plain mcp-use tools — after the install
export default serverRegister your own tools after installToolkit: its duplicate-name guard only sees registrations from the install on.
Add views/render-view/view.tsx (plus one views/<tool>/view.tsx per model-visible widget tool), each rendering McpToolkitApp with your widget map — the CLI discovers, builds, and serves them by convention. The runnable reference is examples/standalone-host.
The Node adapter — createFrameworkApp
When the server must run in your own process (embedded in existing infrastructure, custom entrypoints) or ship its views inline in the MCP resources (e.g. behind gateways that only forward the JSON-RPC endpoint), use the batteries-included wrapper instead:
import path from "node:path"
import { fileURLToPath } from "node:url"
import { createFrameworkApp } from "@miragon/mcp-toolkit-core/tools"
import { createPlugin as createTasksPlugin } from "./modules/tasks/plugin.js"
const here = path.dirname(fileURLToPath(import.meta.url))
const app = await createFrameworkApp({
name: "my-mcp",
version: "0.1.0",
plugins: [createTasksPlugin()], // your AppPlugins
app: {
bundle: {
jsPath: path.join(here, "dist", "mcp-app.js"),
cssPath: path.join(here, "dist", "mcp-app.css"),
},
},
})
await app.listen(Number(process.env.PORT ?? 3010))Both paths boot the same framework surface — the tool trio (get-framework-manifest, render-view, refresh-view) plus mcp-use's natively registered view resources (ui://views/<tool>.html); they differ only in who builds and serves the views. Aggregating several such servers into one surface is an external MCP gateway's job (e.g. agentgateway) — see architecture.
Things the snippets lean on:
- The plugin — a module that registers its own tools and a widget. See the app-plugins concept; the runnable reference is
examples/modules/tasks. - The widget bundle (adapter path only) —
app.bundlemust point at a built ES module (and stylesheet) that maps widget ids to React components. The template ships this Vite setup; in-repo the reference isexamples/app-bundle.
Import paths are deliberate: server-side factories come from @miragon/mcp-toolkit-core/tools (never the root barrel, which stays browser-safe), widget-side hooks from @miragon/mcp-toolkit-ui/app and @miragon/mcp-toolkit-ui/hooks. See each package README for the subpath map.
Where to next
- Playground tour — the toolkit's feature surface as a click-through: widgets, composed views, pipelines, builder.
- Architecture — what the server actually does on each request.
- Using tool-codegen — typed tool calls from steps and widgets, worked through the articles module.
- Env var reference — all config knobs.