AgentStack
MCP verified MIT Self-run

Mcp Apps Kit

mcp-andurilcode-mcp-apps-kit · by AndurilCode

A TypeScript framework for building interactive MCP applications that work seamlessly with both MCP Apps and ChatGPT (OpenAI Apps SDK) from a single codebase.

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add mcp-andurilcode-mcp-apps-kit

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Mcp Apps Kit? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Build interactive AI apps for MCP Apps and ChatGPT. The Modern TypeScript Way.

=18">

Quick Start • Documentation • Examples • Issues


Features at a Glance

| Feature | Description | | --------------------------------- | ------------------------------------------------------------------ | | File-Based Development | Tools, widgets, and workflows auto-discovered from your filesystem | | Convention over Configuration | tools/get-weather.tsgetWeather tool, automatically | | Colocated Widgets | React UIs in ui/widgets/ auto-bind to matching tools | | Type-Safe End-to-End | Full TypeScript inference from inputs to UI props | | Dual Platform | Single codebase deploys to MCP Apps & ChatGPT | | Hot Module Reload | Vite-powered HMR with React Fast Refresh for widgets | | Zero Boilerplate | No manifest files to maintain — codegen handles it |


Quick Start

npx @mcp-apps-kit/create-app@latest my-app
cd my-app && npm run dev

Or manually set up a file-based project:

npm install @mcp-apps-kit/core @mcp-apps-kit/codegen zod

How It Works

MCP AppsKit uses file-based conventions to eliminate boilerplate. Drop files in the right directories and everything wires up automatically.

Project Structure

my-app/
├── mcp.config.ts              # App configuration (single source of truth)
├── tools/
│   ├── get-weather.ts         # → getWeather tool
│   └── search-location.ts     # → searchLocation tool
├── workflows/
│   └── daily-briefing.ts      # → dailyBriefing workflow
├── ui/widgets/
│   ├── get-weather.tsx        # → Auto-bound to getWeather tool
│   └── daily-briefing.tsx     # → Auto-bound to dailyBriefing
├── middleware/
│   └── logging.ts             # Runs on every tool call
├── handlers/
│   └── app-lifecycle.ts       # Server events (start, shutdown)
└── __generated__/             # Auto-generated (gitignored)
    └── app-manifest.ts

Configuration

// mcp.config.ts
import { defineConfig } from "@mcp-apps-kit/codegen";

export default defineConfig({
  name: "weather-app",
  version: "1.0.0",
  directories: {
    tools: "tools",
    workflows: "workflows",
    uiWidgets: "ui/widgets",
    middleware: "middleware",
    handlers: "handlers",
  },
  config: {
    protocol: "mcp", // or "openai" for ChatGPT
    cors: { origin: true },
  },
});

Define a Tool

// tools/get-weather.ts
import { tool } from "@mcp-apps-kit/core";
import { z } from "zod";

export default tool
  .describe("Get current weather for a location")
  .input({
    location: z.string().describe("City name"),
  })
  .output(
    z.object({
      temperature: z.number(),
      conditions: z.string(),
      humidity: z.number(),
    })
  )
  .handle(async ({ location }) => {
    const data = await fetchWeather(location);
    return {
      temperature: data.temp,
      conditions: data.weather,
      humidity: data.humidity,
    };
  });

Create a Widget

Widgets in ui/widgets/ automatically bind to tools with matching filenames:

// ui/widgets/get-weather.tsx
import { useToolResult, useHostContext } from "@mcp-apps-kit/ui-react";
import type { WidgetMetadata } from "@mcp-apps-kit/core";

export default function WeatherWidget() {
  const result = useToolResult();
  const { theme } = useHostContext();

  if (!result) return Loading...;

  return (
    
      {result.temperature}°C
      {result.conditions}
    
  );
}

// Widget metadata (optional)
export const ui: WidgetMetadata = {
  name: "Weather Display",
  prefersBorder: true,
};

Run Your App

npm run dev

The codegen watches for changes and regenerates the manifest. Your tools and widgets are instantly available. Widget changes are picked up by Vite's HMR with React Fast Refresh — no full reload needed.


Naming Conventions

Files are automatically converted to camelCase identifiers:

| File | Tool Name | | ------------------------ | ------------------------------- | | get-current-weather.ts | getCurrentWeather | | search_locations.ts | searchLocations | | DailyBriefing.ts | dailyBriefing | | _shared.ts | (ignored — underscore prefix) |


Packages

| Package | Description | | ----------------------------------------------------------------------- | -------------------------------------------- | | [@mcp-apps-kit/core](packages/core/README.md) | Server framework with tool/workflow builders | | [@mcp-apps-kit/codegen](packages/codegen/README.md) | File-based discovery and manifest generation | | [@mcp-apps-kit/ui](packages/ui/README.md) | Client SDK (vanilla JS) | | [@mcp-apps-kit/ui-react](packages/ui-react/README.md) | React bindings and hooks | | [@mcp-apps-kit/ui-react-builder](packages/ui-react-builder/README.md) | Vite plugin for widget bundling and HMR | | [@mcp-apps-kit/create-app](packages/create-app/README.md) | CLI scaffolding tool | | [@mcp-apps-kit/testing](packages/testing/README.md) | Test utilities and mocks |


Advanced Features

Middleware

Add cross-cutting concerns like logging, auth, or metrics:

// middleware/logging.ts
import { defineMiddleware } from "@mcp-apps-kit/codegen";

export default defineMiddleware({
  before: async (ctx) => {
    ctx.state.set("startTime", Date.now());
    console.log(`Tool called: ${ctx.toolName}`);
  },
  after: async (ctx) => {
    const duration = Date.now() - ctx.state.get("startTime");
    console.log(`Completed in ${duration}ms`);
  },
});

Event Handlers

React to server lifecycle events:

// handlers/app-lifecycle.ts
import { defineHandler, Events } from "@mcp-apps-kit/codegen";

export default defineHandler({
  event: Events.APP_START,
  handler: async ({ port }) => {
    console.log(`Server started on port ${port}`);
  },
});

Multi-Version APIs

Support multiple API versions from a single codebase:

// mcp.config.ts
export default defineConfig({
  name: "my-api",
  versions: {
    v1: {
      version: "1.0.0",
      // Uses versions/v1/tools, versions/v1/workflows, etc.
    },
    v2: {
      version: "2.0.0",
      config: { debug: { level: "debug" } },
    },
  },
});

Workflow Engine

Compose multi-step operations:

// workflows/order-process.ts
import { workflow, toolStep } from "@mcp-apps-kit/core";
import { z } from "zod";

export default workflow("process_order")
  .input({ orderId: z.string() })
  .output({ success: z.boolean() })
  .step("validate", toolStep("validate_order"))
  .step("payment", toolStep("process_payment"), {
    retry: { maxAttempts: 3, backoff: "exponential" },
  })
  .parallel("notify", [toolStep("send_email"), toolStep("send_sms")])
  .build();

Platform Support

| Feature | MCP Apps | ChatGPT Apps | | ----------------- | -------- | ------------ | | Tool Calling | Yes | Yes | | Structured Output | Yes | Yes | | React Widgets | Yes | Yes | | OAuth 2.1 | Yes | Yes | | Theme Support | Yes | Yes | | Persisted State | No | Yes | | Tool Cancellation | Yes | No |


Examples

Weather App

Full-featured example with tools, widgets, middleware, and workflows:

git clone https://github.com/AndurilCode/mcp-apps-kit.git
cd mcp-apps-kit/examples/weather-app
pnpm install && pnpm dev

Kanban Demo

Production-ready example with tool calling, React widgets, plugins, middleware, and events:

git clone https://github.com/AndurilCode/kanban-mcp-example.git
cd kanban-mcp-example
npm install && npm run dev

Deployment

Express (default)

// Handled automatically by codegen
npm run start

Stdio Mode

// mcp.config.ts
export default defineConfig({
  // ...
  config: {
    transport: "stdio",
  },
});

Serverless

import { createFileBasedApp } from "@mcp-apps-kit/codegen";

const app = await createFileBasedApp();

export default {
  async fetch(request: Request) {
    return app.handleRequest(request);
  },
};

Compatibility

  • Node.js: >= 18 (runtime), >= 20 (development/CLI)
  • React: 18.x or 19.x
  • Zod: ^4.0.0
  • Vite: 5.x, 6.x, or 7.x

API Reference

Full Documentation — TypeDoc-generated API reference

Package documentation:

  • [Core API](packages/core/README.md)
  • [UI SDK](packages/ui/README.md)
  • [React Hooks](packages/ui-react/README.md)
  • [Widget Builder](packages/ui-react-builder/README.md)
  • [Testing](packages/testing/README.md)

Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup. Issues and pull requests welcome.


License

[MIT](LICENSE)

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.