-
Notifications
You must be signed in to change notification settings - Fork 163
Add standalone OpenGenerativeUI MCP Server #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
17058d1
bdd69c2
cf5978c
82cf3eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| node_modules/ | ||
| npm-debug.log | ||
| .git | ||
| .gitignore | ||
| README.md | ||
| .env.example | ||
| .DS_Store | ||
| dist/ | ||
| .turbo/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # Server Configuration | ||
| MCP_PORT=3100 | ||
| NODE_ENV=development | ||
|
|
||
| # CORS (comma-separated origins, default: * for development) | ||
| ALLOWED_ORIGINS=* | ||
|
|
||
| # Skills directory (default: ./skills relative to package root) | ||
| SKILLS_DIR=./skills | ||
|
|
||
| # Logging | ||
| LOG_LEVEL=info |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| node_modules/ | ||
| dist/ | ||
| .env | ||
| .env.local | ||
| *.log | ||
| npm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| .DS_Store | ||
| .turbo/ | ||
| .venv/ | ||
| pnpm-lock.yaml | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| # Multi-stage build for production | ||
| FROM node:20-alpine AS builder | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Install build dependencies | ||
| RUN apk add --no-cache python3 make g++ | ||
|
|
||
| # Copy package files | ||
| COPY package.json pnpm-lock.yaml ./ | ||
|
|
||
| # Install pnpm | ||
| RUN npm install -g pnpm@9 | ||
|
|
||
| # Install dependencies | ||
| RUN pnpm install --prod --frozen-lockfile | ||
|
|
||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug:
Should be: RUN pnpm install --frozen-lockfileOr split into two stages — full install for build, then prune to prod for the runtime image. |
||
| # Copy source | ||
| COPY tsconfig.json ./ | ||
| COPY src ./src | ||
| COPY skills ./skills | ||
|
|
||
| # Build | ||
| RUN pnpm build | ||
|
|
||
| # Production image | ||
| FROM node:20-alpine | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Install dumb-init for proper signal handling | ||
| RUN apk add --no-cache dumb-init | ||
|
|
||
| # Copy built application from builder | ||
| COPY --from=builder /app/dist ./dist | ||
| COPY --from=builder /app/skills ./skills | ||
| COPY --from=builder /app/node_modules ./node_modules | ||
| COPY package.json ./ | ||
|
|
||
| # Non-root user | ||
| RUN addgroup -g 1001 -S nodejs && \ | ||
| adduser -S nodejs -u 1001 | ||
|
|
||
| USER nodejs | ||
|
|
||
| # Health check | ||
| HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ | ||
| CMD wget --no-verbose --tries=1 --spider http://localhost:${MCP_PORT:-3100}/health || exit 1 | ||
|
|
||
| EXPOSE 3100 | ||
|
|
||
| ENTRYPOINT ["/sbin/dumb-init", "--"] | ||
| CMD ["node", "dist/index.js"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,261 @@ | ||
| # OpenGenerativeUI MCP Server | ||
|
|
||
| A standalone, independently deployable [Model Context Protocol](https://modelcontextprotocol.io) server that exposes OpenGenerativeUI's design system, skills, and document renderer to any MCP-compatible client. | ||
|
|
||
| ## Features | ||
|
|
||
| - **Design System Tool** — `assemble_document` wraps HTML fragments with OpenGenerativeUI's complete CSS design system and bridge JavaScript | ||
| - **Skill Resources** — Browse and read skill instruction documents via `skills://list` and `skills://{name}` | ||
| - **Prompt Templates** — Pre-composed prompts for common visualization tasks: `create_widget`, `create_svg_diagram`, `create_visualization` | ||
| - **Standalone** — No dependencies on other packages; can be deployed independently | ||
| - **Configurable** — Environment variables for port, CORS origins, skills directory, and logging | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ### Prerequisites | ||
| - Node.js >= 18 | ||
| - pnpm or npm | ||
|
|
||
| ### Installation | ||
|
|
||
| ```bash | ||
| # Navigate to the MCP package | ||
| cd apps/mcp | ||
|
|
||
| # Install dependencies | ||
| pnpm install | ||
|
|
||
| # Start the development server | ||
| pnpm dev | ||
| # → MCP server running on http://localhost:3100/mcp | ||
|
|
||
| # Health check | ||
| curl http://localhost:3100/health | ||
| # → {"status":"ok"} | ||
| ``` | ||
|
|
||
| ### Build for Production | ||
|
|
||
| ```bash | ||
| pnpm build | ||
| pnpm start | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| Create a `.env` file in the package root (copy from `.env.example`): | ||
|
|
||
| ```bash | ||
| # Server port (default: 3100) | ||
| MCP_PORT=3100 | ||
|
|
||
| # CORS origins, comma-separated (default: * for development) | ||
| ALLOWED_ORIGINS=* | ||
|
|
||
| # Skills directory path (default: ./skills) | ||
| SKILLS_DIR=./skills | ||
|
|
||
| # Log level (default: info) | ||
| LOG_LEVEL=info | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| ### From Claude Code | ||
|
|
||
| Add to `.mcp.json`: | ||
|
|
||
| ```json | ||
| { | ||
| "openGenerativeUI": { | ||
| "url": "http://localhost:3100/mcp" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Then use the available tools and resources in Claude conversations. | ||
|
|
||
| ### From Any MCP Client | ||
|
|
||
| Connect via HTTP MCP transport to `http://localhost:3100/mcp`. | ||
|
|
||
| ## API Reference | ||
|
|
||
| ### Tool: `assemble_document` | ||
|
|
||
| Wraps an HTML fragment with the complete OpenGenerativeUI design system. | ||
|
|
||
| **Input:** | ||
| ```typescript | ||
| { | ||
| title: string; // Short title, e.g., "Binary Search Visualization" | ||
| description: string; // One-sentence explanation | ||
| html: string; // Self-contained HTML fragment (inline <style> and <script> OK) | ||
| } | ||
| ``` | ||
|
|
||
| **Output:** | ||
| ```typescript | ||
| { | ||
| content: [{ | ||
| type: "text", | ||
| text: string // Complete HTML document, ready to render in iframe | ||
| }] | ||
| } | ||
| ``` | ||
|
|
||
| **Example:** | ||
| ```javascript | ||
| const result = await client.callTool("assemble_document", { | ||
| title: "Interactive Algorithm Visualizer", | ||
| description: "Step-by-step visualization of the quicksort algorithm", | ||
| html: ` | ||
| <div id="viz"> | ||
| <p>Click to start visualization</p> | ||
| <script> | ||
| // Your visualization code here | ||
| </script> | ||
| </div> | ||
| ` | ||
| }); | ||
|
|
||
| // result.content[0].text is a complete HTML document | ||
| // Render in: <iframe sandbox="allow-scripts allow-same-origin" srcdoc={result.content[0].text} /> | ||
| ``` | ||
|
|
||
| ### Resource: `skills://list` | ||
|
|
||
| Returns a JSON array of available skill names. | ||
|
|
||
| **Example:** | ||
| ```bash | ||
| curl -X POST http://localhost:3100/mcp \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "jsonrpc": "2.0", | ||
| "id": 1, | ||
| "method": "resources/read", | ||
| "params": { "uri": "skills://list" } | ||
| }' | ||
| ``` | ||
|
|
||
| ### Resource: `skills://{name}` | ||
|
|
||
| Retrieve the full text content of a specific skill. | ||
|
|
||
| Available skills: | ||
| - `master-agent-playbook` — When and how to create interactive HTML widgets | ||
| - `svg-diagram-skill` — SVG diagram templates and patterns | ||
| - `agent-skills-vol2` — Advanced visualizations, dashboards, simulations | ||
|
|
||
| **Example:** | ||
| ```bash | ||
| curl -X POST http://localhost:3100/mcp \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "jsonrpc": "2.0", | ||
| "id": 1, | ||
| "method": "resources/read", | ||
| "params": { "uri": "skills://master-agent-playbook" } | ||
| }' | ||
| ``` | ||
|
|
||
| ### Prompts | ||
|
|
||
| #### `create_widget` | ||
| Instructions for creating interactive HTML widgets. | ||
|
|
||
| #### `create_svg_diagram` | ||
| Instructions for creating inline SVG diagrams with canonical templates. | ||
|
|
||
| #### `create_visualization` | ||
| Advanced visualization instructions: dashboards, simulations, UI mockups. | ||
|
|
||
| ## Deployment | ||
|
|
||
| ### Docker | ||
|
|
||
| ```bash | ||
| # Build image | ||
| docker build -t open-generative-ui-mcp . | ||
|
|
||
| # Run container | ||
| docker run -p 3100:3100 open-generative-ui-mcp | ||
|
|
||
| # With custom port and CORS | ||
| docker run \ | ||
| -p 3100:3100 \ | ||
| -e MCP_PORT=3100 \ | ||
| -e ALLOWED_ORIGINS="http://localhost:3000,https://myapp.com" \ | ||
| open-generative-ui-mcp | ||
| ``` | ||
|
|
||
| ### Node.js | ||
|
|
||
| ```bash | ||
| # Install globally or locally | ||
| npm install -g open-generative-ui-mcp | ||
|
|
||
| # Run | ||
| MCP_PORT=3100 ALLOWED_ORIGINS="*" open-generative-ui-mcp | ||
|
|
||
| # Or with node | ||
| node dist/index.js | ||
| ``` | ||
|
|
||
| ### Cloud Deployment | ||
|
|
||
| The server is a standard Node.js application and can be deployed to: | ||
| - **Heroku**: `Procfile: web: node dist/index.js` | ||
| - **Railway**: Connect the repo, select Node.js, set `start` script | ||
| - **Vercel**: Use serverless function (requires adapter) | ||
| - **AWS Lambda**: Package with Node.js runtime | ||
| - **Google Cloud Run**: Use Dockerfile | ||
|
|
||
| ## Development | ||
|
|
||
| ### Project Structure | ||
|
|
||
| ``` | ||
| apps/mcp/ | ||
| ├── package.json # Standalone package definition | ||
| ├── tsconfig.json # TypeScript config | ||
| ├── .env.example # Configuration template | ||
| ├── Dockerfile # Container definition | ||
| ├── skills/ # Skill instruction files (copied from source) | ||
| └── src/ | ||
| ├── index.ts # Hono HTTP server entry point | ||
| ├── server.ts # MCP server construction | ||
| ├── skills.ts # Skill file loader | ||
| └── renderer.ts # Design system CSS + assembleDocument | ||
| ``` | ||
|
|
||
| ### Extending Skills | ||
|
|
||
| Add new skill files to `skills/` directory as `.txt` files. They'll automatically be available as resources and can be used in prompts. | ||
|
|
||
| ### Modifying the Design System | ||
|
|
||
| Edit `src/renderer.ts` to update: | ||
| - `THEME_CSS` — Theme colors and variables | ||
| - `SVG_CLASSES_CSS` — Pre-built SVG helper classes | ||
| - `FORM_STYLES_CSS` — Form element styling | ||
| - `BRIDGE_JS` — Communication bridge between iframe and parent | ||
|
|
||
| ## License | ||
|
|
||
| MIT | ||
|
|
||
| ## Support | ||
|
|
||
| For issues, feature requests, or questions, visit the [OpenGenerativeUI repository](https://github.com/CopilotKit/OpenGenerativeUI). | ||
|
|
||
| ## Contributing | ||
|
|
||
| This is a standalone deployment package. To contribute improvements: | ||
|
|
||
| 1. Fork the main [OpenGenerativeUI repository](https://github.com/CopilotKit/OpenGenerativeUI) | ||
| 2. Make changes to `apps/mcp/` (or the source files it's forked from) | ||
| 3. Submit a pull request | ||
|
|
||
| When updating skills or the design system in the main repo, the MCP package should be updated accordingly. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| { | ||
| "name": "open-generative-ui-mcp", | ||
| "version": "0.1.0", | ||
| "description": "Standalone MCP server for OpenGenerativeUI design system and skills", | ||
| "type": "module", | ||
| "main": "dist/index.js", | ||
| "scripts": { | ||
| "dev": "tsx watch src/index.ts", | ||
| "build": "tsc", | ||
| "start": "node dist/index.js", | ||
| "lint": "tsc --noEmit" | ||
| }, | ||
| "keywords": ["mcp", "model-context-protocol", "generative-ui", "design-system"], | ||
| "author": "CopilotKit", | ||
| "license": "MIT", | ||
| "dependencies": { | ||
| "@hono/node-server": "^1", | ||
| "@modelcontextprotocol/sdk": "^1.25.3", | ||
| "hono": "^4", | ||
| "zod": "^3.23" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/node": "^20", | ||
| "tsx": "^4", | ||
| "typescript": "^5" | ||
| }, | ||
| "engines": { | ||
| "node": ">=18" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conflict with Dockerfile: The
.gitignoreexcludespnpm-lock.yaml, but the Dockerfile (line 11) copies it for--frozen-lockfileinstall. The Docker build will fail unless the lockfile exists at build time.Either remove this line (and commit the lockfile) or update the Dockerfile to not rely on
--frozen-lockfile.