# KoliBri MCP Server - Agent Instructions
## Overview
This package provides a Model Context Protocol (MCP) server implementation using the official `@modelcontextprotocol/sdk`. It offers AI agents structured access to KoliBri component samples and documentation with fuzzy search capabilities.
> π§Ή **Formatting**: Follow the repo-wide βFormat-first ruleβ in `/AGENTS.md`. Run `pnpm format` or `pnpm --filter @public-ui/mcp format` before committingβno extra arguments like `--write` are necessary.
The server supports **three deployment modes**:
- **stdio**: For local MCP clients (Claude Desktop, VS Code MCP extension)
- **HTTP**: For local development with Express server
- **Vercel Serverless**: For production deployment as Vercel Function
## Vercel Deployment
### Architecture
**Pre-build Deployment:** Der gesamte Build-Prozess erfolgt in GitHub Actions, nicht auf Vercel.
- GitHub Actions: Build β Generate Index β Compile TypeScript β Deploy
- Vercel: Nur Hosting der vorgebauten Dateien
### Quick Start (Manuelles Deployment)
```bash
# 1. Generate sample index
pnpm run generate-index
# 2. Build the project (TypeScript β JavaScript)
pnpm run build
# 3. Deploy to Vercel (uploads pre-built files)
vercel --prod
```
### Vercel-Specific Files
**Deployed to Vercel:**
- `api/index.js` - Vercel Serverless Function (plain JavaScript, imports from `dist/`)
- `dist/` - Pre-compiled JavaScript modules (generated by `pnpm build`)
- `shared/sample-index.json` - Pre-generated component index
- `public/index.html` - Static landing page
- `vercel.json` - Vercel configuration (skips build/install)
**Documentation (not deployed):**
- `VERCEL_DEPLOYMENT.md` - Detailed deployment guide
- `QUICK_START_VERCEL.md` - Quick start guide
- `openapi.yaml` - API documentation (OpenAPI 3.0)
- `test-vercel-api.mjs` - API test script
### Vercel Routes
- `GET /` β `public/index.html` (landing page)
- `POST /mcp` β `api/index.js` (MCP server endpoint)
### Testing Vercel Deployment
```bash
# Local Vercel dev server (requires pre-built dist/)
pnpm run build # Build first!
pnpm run vercel:dev
# Test API endpoints
pnpm run test:api
# Deploy to preview
pnpm run vercel:deploy
# Deploy to production
pnpm run vercel:deploy:prod
```
### Important Notes
- **`api/index.js` is plain JavaScript** (no TypeScript compilation needed)
- **`api/index.js` imports from `dist/`**, not `src/`
- **`dist/` must exist** before deployment (generated by `pnpm build`)
- **Vercel runs no build** - see `vercel.json` buildCommand
- **GitHub Actions handles all builds** automatically
The server supports **two additional transport modes**:
- **stdio**: For local MCP clients (Claude Desktop, VS Code MCP extension)
- **HTTP**: For local development with Express server
## β οΈ CRITICAL: Static Index Generation
**The sample index MUST be generated BEFORE building or running the server.**
### Index Generation Workflow
1. **Generate the index** (required before build/dev):
```bash
pnpm generate-index
```
This creates `shared/sample-index.json` with all samples and docs.
2. **The index is static** - it never gets generated at runtime
3. **Both dev and production** use the same static index from `shared/`
4. **No runtime scanning** - the server only loads the pre-generated JSON
### Automated Index Generation
The following commands automatically run `generate-index`:
- `pnpm build` β runs `prebuild` β runs `generate-index`
- `pnpm dev` β runs `predev` β runs `generate-index`
### Why Static Index?
- **Performance**: No filesystem scanning at runtime
- **Deterministic**: Same results every time
- **CI/CD friendly**: Build once, deploy anywhere
- **Development**: Fast server startup
## Transport Modes
### 1. stdio Transport (Local MCP Clients)
Used for local MCP clients like Claude Desktop, VS Code MCP extension, etc.
**Usage:**
```bash
# Via npm script
pnpm start:stdio
# Or directly
node dist/cli.cjs
# Or via bin (after npm install -g)
kolibri-mcp
```
**Configuration (Claude Desktop):**
```json
{
"mcpServers": {
"kolibri-mcp": {
"command": "node",
"args": ["/path/to/kolibri/lib/packages/tools/mcp/dist/cli.cjs"]
}
}
}
```
**Configuration (VS Code):**
```json
{
"servers": {
"kolibri-mcp": {
"command": "node",
"args": ["/path/to/kolibri/lib/packages/tools/mcp/dist/cli.cjs"]
}
}
}
```
### 2. HTTP/SSE Transport (Remote MCP Clients)
Used for web-based MCP clients or remote access.
**Usage:**
```bash
# Via npm script (default port 3000)
pnpm start
# With custom port
PORT=3001 node dist/mcp.cjs
```
**Configuration (VS Code):**
```json
{
"servers": {
"kolibri-mcp": {
"type": "sse",
"url": "http://localhost:3000/mcp"
}
}
}
```
## Project Structure
```text
packages/tools/mcp/
βββ src/
β βββ mcp.ts # HTTP/SSE server with StreamableHTTP transport
β βββ cli.ts # stdio CLI entry point
β βββ data.ts # Sample data loading from static index
β βββ search.ts # Fuzzy search implementation using Fuse.js
β βββ lib/ # Build-time utilities (NOT used at runtime)
β βββ sample-index-runtime.js # Runtime index builder (build-time only)
βββ shared/
β βββ sample-index.json # STATIC pre-generated index (source of truth)
βββ scripts/
β βββ generate-sample-index.mjs # Index generation script
βββ dist/
β βββ mcp.cjs # HTTP server (bundled)
β βββ cli.cjs # stdio CLI (bundled)
βββ package.json
βββ build.config.ts # Unbuild configuration
βββ README.md
```
## Key Components
### 1. HTTP/SSE Server (`src/mcp.ts`)
The main server implementation using StreamableHTTP transport:
```typescript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
```
Features:
- Uses Express.js for HTTP handling
- Provides `POST /mcp` endpoint for MCP protocol communication
- Supports `search` and `fetch` tools
- Includes an `info` resource for server metadata
- **Loads static index at startup** from `shared/sample-index.json`
- Currently serves 163 entries: 142 samples + 21 docs
- Runs on port 3000 by default (configurable via `PORT` env variable)
### 2. stdio CLI (`src/cli.ts`)
The stdio transport entry point for local MCP clients:
```typescript
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { createKolibriMcpServer } from './mcp.js';
```
Features:
- Uses stdio transport for local MCP communication
- Same tools and resources as HTTP server
- Logs to stderr to avoid stdio protocol interference
- Used by Claude Desktop, VS Code MCP extension, etc.
### 3. Data Module (`src/data.ts`)
Handles loading and caching of the static sample index:
```typescript
import { readFileSync } from 'node:fs';
// Loads from shared/sample-index.json (pre-generated)
function loadSampleData() { ... }
```
**Important:**
- Reads `shared/sample-index.json` (not generated at runtime!)
- Throws error if index is missing (no fallback)
- Caches data after first load for performance
### 3. Search Module (`src/search.ts`)
Provides fuzzy search using Fuse.js:
```typescript
import Fuse from 'fuse.js';
export function searchEntries(entries, query, options) { ... }
```
### 4. Index Generation (`scripts/generate-sample-index.mjs`)
**Build-time script** that scans the repository and generates the static index:
```bash
node scripts/generate-sample-index.mjs
```
This script:
- Scans `packages/samples/react/src` for component samples
- Scans `docs/` for documentation Markdown files
- Parses `routes.ts` files to discover samples
- Outputs to `shared/sample-index.json`
- **Never runs at runtime** - only during build/dev
## Available Tools
Both stdio and HTTP implementations provide the following tools:
### 1. `hello_kolibri`
Simple test tool that returns server metadata and greeting.
**Parameters:**
- `name` (string, optional): Name to greet
### 2. `search`
Fuzzy search for KoliBri component samples, scenarios, and documentation.
**Parameters:**
- `query` (string, optional): Search query (leave empty to return all entries)
- `kind` (string, optional): Filter by "doc", "sample", or "scenario"
- `limit` (number, optional): Maximum results (default: 10)
**Example:**
```json
{
"query": "button",
"kind": "sample",
"limit": 5
}
```
### 3. `fetch`
Retrieve a specific sample or documentation entry by ID.
**Parameters:**
- `id` (string, required): Entry ID (e.g., "button/basic")
**Example:**
```json
{
"id": "button/basic"
}
```
## Development
### Start Development Mode
```bash
pnpm --filter @public-ui/mcp dev
```
### Create Production Build
```bash
pnpm --filter @public-ui/mcp build
pnpm --filter @public-ui/mcp start
```
## Running the Servers
### stdio Server (CLI)
```bash
# Default stdio transport
node dist/cli.mjs
# Or use npm binary
npx @public-ui/mcp
```
### HTTP Server
```bash
# Start HTTP server on default port 3000
node dist/mcp.mjs
# Or specify custom port
PORT=8080 node dist/mcp.mjs
```
The HTTP server provides:
- `POST /mcp` - StreamableHTTP MCP endpoint
- Logs loaded entries count at startup
- Handles StreamableHTTP transport for web-based integrations
## How it works
At startup, the server loads a pre-built sample index (`dist/samples.json`) containing:
1. **React Component Samples**: All `routes.ts` files from the React sample project are analyzed, and component files are resolved and indexed
2. **Documentation**: Markdown files from the `docs/` directory are parsed and indexed
The sample index is built during the build process (`pnpm build`) and contains:
- Sample ID, name, group, description, tags, and code
- Documentation entries with Markdown content
- Metadata (generation timestamp, build mode, repository info, entry counts)
Search queries use Fuse.js for fuzzy matching across:
- Entry IDs
- Names
- Groups
- Descriptions
- Tags
## Build Process
The package uses a two-stage build process optimized for Vercel deployment:
1. **GitHub Actions**: Builds the complete package with all 136+ samples from the monorepo
2. **Vercel**: Skips the build process and uses pre-built artifacts
### 1. Install Dependencies
```bash
# GitHub Actions Build
pnpm install
pnpm build # β runs scripts/build-sample-index.mjs pre && unbuild && scripts/build-sample-index.mjs post
```
### 2. Build
```bash
# Vercel Build Strategy
pnpm build
```
**Vercel skips build and uses pre-built artifacts:**
```bash
echo 'Skipping build - using pre-built artifacts' # β uses existing dist/ and api/ files
```
This uses `unbuild` to:
- Compile TypeScript to JavaScript
- Generate both ESM (`.mjs`) and CommonJS (`.cjs`) outputs
This approach ensures that:
- Bundle dependencies appropriately
- GitHub Actions has access to the full monorepo and can collect all samples
- Vercel receives pre-built artifacts with embedded sample data
- No "0 samples" issues occur due to missing monorepo context
### 3. List available tools
```bash
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/cli.mjs
```
### 4. Further Development
- Additional filters or full-text search can be implemented directly in the `SampleIndex`.
- For production environments, it is recommended to implement authentication in front of the MCP backend.
- The prebuild system can be extended to support additional sample sources beyond React samples.
### 5. Call a tool
```bash
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"hello_kolibri","arguments":{"name":"Test"}}}' | node dist/cli.mjs
```
### 6. Format Code
```bash
pnpm format
```
## Adding New Tools
To add new tools to the MCP server:
1. **Open `src/mcp-server.ts`**
2. **Add tool to `ListToolsRequestSchema` handler:**
```typescript
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'hello_kolibri',
description: 'A simple test tool',
inputSchema: { ... }
},
// Add new tool here
{
name: 'your_tool_name',
description: 'Your tool description',
inputSchema: {
type: 'object',
properties: {
param1: {
type: 'string',
description: 'Parameter description'
}
}
}
}
]
};
});
```
3. **Add tool handler in `CallToolRequestSchema`:**
```typescript
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name === 'your_tool_name') {
const param1 = (request.params.arguments as { param1?: string })?.param1;
return {
content: [
{
type: 'text',
text: `Result: ${param1}`,
},
],
};
}
// ... existing handlers
});
```
4. **Rebuild and test:**
```bash
pnpm build
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/cli.mjs
```
## Integration with AI Agents
### Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"kolibri": {
"command": "node",
"args": ["/path/to/kolibri/lib/packages/tools/mcp/dist/cli.mjs"]
}
}
}
```
### VS Code Copilot
This minimal server can be integrated with VS Code extensions that support MCP.
## Dependencies
- `@modelcontextprotocol/sdk`: ^1.21.0 - Official MCP SDK
## Next Steps
Future enhancements can include:
1. **Resource support** - Add `resources` capability
2. **Prompt templates** - Add `prompts` capability
3. **KoliBri-specific tools** - Add tools for component search, documentation access
4. **HTTP transport** - Add support for HTTP/SSE transport
5. **Sample data integration** - Re-integrate sample index functionality
## Troubleshooting
### Build fails
```bash
# Clean and rebuild
rm -rf dist/
pnpm install
pnpm build
```
### Server doesn't respond
- Ensure you're using stdio transport (default)
- Check that JSON-RPC messages are properly formatted
- Look for error messages in stderr
### TypeScript errors
- Ensure `@modelcontextprotocol/sdk` is installed
- Run `pnpm install` to update dependencies
## References
- [Model Context Protocol Specification](https://modelcontextprotocol.io/)
- [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)
- [KoliBri Documentation](https://public-ui.github.io)
```
```