A comprehensive Kanban board application demonstrating all features of the @mcp-apps-kit SDK.
| Feature | Description | Example in Code |
|---|---|---|
| Tool Definitions | Type-safe tool definitions with Zod schemas | All tools use z.object() for input/output |
| Tool Annotations | Behavioral hints for AI models | readOnlyHint, destructiveHint, openWorldHint, idempotentHint |
| ToolContext | Client-provided metadata in handlers | context.locale, context.userLocation, context.subject, context.widgetSessionId |
| fileParams | Enable file upload parameters | createTask tool with fileParams: ["attachmentId"] |
| widgetDescription | Human-readable summary for AI | UI resource with widgetDescription |
| ClientToolsFromCore | End-to-end typed UI client | UI imports KanbanClientTools (from ClientToolsFromCore<typeof app.tools>) |
| _text | Human-friendly model-facing output | Tools that return message also set _text: message |
| _closeWidget | Dismiss widget after action | clearCompleted tool returns _closeWidget: true |
| visibility | Control who can invoke tools | "model", "app", "both" |
| widgetAccessible | Allow widget to call tool | All widget-only tools |
| invokingMessage/invokedMessage | Loading state messages | createTask, deleteTask, etc. |
| title | Human-readable tool title | All tools have title property |
| Hook | Description | Usage in App |
|---|---|---|
| useAppsClient | Access typed client for tool calls | Main tool call interface |
| useToolInput | Access initial tool input | Debug panel display |
| useHostContext | Access theme, viewport, locale | Theme and context display |
| useWidgetState | Persist state across reloads | Collapsed columns, debug panel |
| useHostStyleVariables | Apply host CSS variables | Applied in App component |
| useDocumentTheme | Apply theme class to document | Light/dark mode |
| useDisplayMode | Access/change display mode | Debug panel display |
| useSafeAreaInsets | Mobile safe area padding | Container padding |
| useOnToolCancelled | Handle tool cancellation | Cancellation message |
| useOnTeardown | Cleanup on widget teardown | Console logging |
| useFileUpload | Upload files (ChatGPT) | Task attachment |
| useIntrinsicHeight | Report widget height | Auto-height container |
| useView | Access view identifier | Debug panel display |
| useModal | Host-owned modal dialogs | Delete confirmation |
# Install dependencies
npm install
# Start both server and UI dev mode
npm run dev
# Or start individually
npm run dev:server # Server only
npm run dev:ui # UI dev server only
# Build for production
npm run buildThe server starts at http://localhost:3001.
| Tool | Description | Features Used |
|---|---|---|
listTasks |
List all tasks (optional filter) | readOnlyHint, idempotentHint, visibility: "app" |
createTask |
Create task with attachment | fileParams, invokingMessage |
moveTask |
Move task between columns | idempotentHint |
updateTask |
Update task details | Widget-accessible |
deleteTask |
Delete a task | destructiveHint |
clearCompleted |
Clear done tasks | _closeWidget |
exportBoard |
Export board data | openWorldHint |
getBoardSummary |
Get board overview | ui: "kanban-board" |
{
"tool": "createTask",
"arguments": {
"title": "Review document",
"description": "Review the attached document",
"attachmentId": "file-abc123"
}
}{
"tool": "clearCompleted",
"arguments": {
"closeWidget": true
}
}{
"tool": "exportBoard",
"arguments": {
"format": "csv",
"includeMetadata": false
}
}Click the π§ button to open the SDK Feature Status panel, showing:
- Host context (theme, platform, locale, viewport)
- Display mode and available modes
- Safe area insets
- Platform feature support (file upload, modal, intrinsic height)
- Current view identifier
- Tool input
The following preferences are persisted using useWidgetState:
- Collapsed columns (click column header to toggle)
- Debug panel visibility
On supported platforms (ChatGPT), delete confirmation uses native host modals via useModal. Falls back to confirm() on other platforms.
On supported platforms (ChatGPT), the Add Task modal includes a file upload option using useFileUpload.
kanban-mcp-example/
βββ api/
β βββ index.ts # Vercel serverless function
βββ public/
β βββ index.html # Built UI output
βββ src/
β βββ index.ts # Server with all SDK features
β βββ ui/
β βββ App.tsx # React app with all hooks
β βββ main.tsx # Entry point with AppsProvider
β βββ index.html # HTML template
β βββ styles.css # Comprehensive styling
βββ package.json
βββ tsconfig.json
βββ tsup.config.ts
βββ vercel.json
βββ vite.config.ts
{
"mcpServers": {
"kanban": {
"command": "npx",
"args": ["tsx", "/path/to/kanban-mcp-example/src/index.ts"]
}
}
}// In src/index.ts
config: {
protocol: "openai", // Change from "mcp" to "openai"
}# Type checking
npm run typecheck
# Build UI
npm run build:ui
# Build server
npm run build:server
# Build everything
npm run buildThis project is configured for deployment on Vercel:
# Deploy preview
vercel
# Deploy to production
vercel --prod