From eebbef502d4038c45e39095702c56e25c38b48fb Mon Sep 17 00:00:00 2001 From: Adrian Perez Date: Sat, 18 Apr 2026 17:50:47 +0200 Subject: [PATCH] feat(mcp): finalize scaffolding and factory entry Adds packages/mcp/.gitignore, src/index.ts (public API barrel), src/server.ts (createPascalMcpServer factory), and a smoke test for the public API. Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/mcp/.gitignore | 2 ++ packages/mcp/scripts/spike.ts | 2 +- packages/mcp/src/index.test.ts | 11 +++++++++++ packages/mcp/src/index.ts | 4 ++++ packages/mcp/src/server.ts | 24 ++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 packages/mcp/.gitignore create mode 100644 packages/mcp/src/index.test.ts create mode 100644 packages/mcp/src/index.ts create mode 100644 packages/mcp/src/server.ts diff --git a/packages/mcp/.gitignore b/packages/mcp/.gitignore new file mode 100644 index 00000000..4bf7b955 --- /dev/null +++ b/packages/mcp/.gitignore @@ -0,0 +1,2 @@ +dist/ +*.tsbuildinfo diff --git a/packages/mcp/scripts/spike.ts b/packages/mcp/scripts/spike.ts index 6153a697..7f199c4c 100644 --- a/packages/mcp/scripts/spike.ts +++ b/packages/mcp/scripts/spike.ts @@ -13,8 +13,8 @@ if (typeof (globalThis as any).requestAnimationFrame === 'undefined') { } } -import useScene from '@pascal-app/core/store' import { WallNode } from '@pascal-app/core/schema' +import useScene from '@pascal-app/core/store' function assert(cond: unknown, msg: string): asserts cond { if (!cond) throw new Error(`ASSERT FAILED: ${msg}`) diff --git a/packages/mcp/src/index.test.ts b/packages/mcp/src/index.test.ts new file mode 100644 index 00000000..16486af3 --- /dev/null +++ b/packages/mcp/src/index.test.ts @@ -0,0 +1,11 @@ +import { expect, test } from 'bun:test' + +test('version module loads', async () => { + const mod = await import('./index') + expect(mod.version).toBe('0.1.0') +}) + +test('createPascalMcpServer is a function', async () => { + const mod = await import('./index') + expect(typeof mod.createPascalMcpServer).toBe('function') +}) diff --git a/packages/mcp/src/index.ts b/packages/mcp/src/index.ts new file mode 100644 index 00000000..1c0b5afc --- /dev/null +++ b/packages/mcp/src/index.ts @@ -0,0 +1,4 @@ +export { SceneBridge } from './bridge/scene-bridge' +export { type CreatePascalMcpServerOptions, createPascalMcpServer } from './server' + +export const version = '0.1.0' diff --git a/packages/mcp/src/server.ts b/packages/mcp/src/server.ts new file mode 100644 index 00000000..382cd67f --- /dev/null +++ b/packages/mcp/src/server.ts @@ -0,0 +1,24 @@ +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' +import type { SceneBridge } from './bridge/scene-bridge' +import { registerPrompts } from './prompts' +import { registerResources } from './resources' +import { registerTools } from './tools' +import { registerVisionTools } from './tools/vision' + +export type CreatePascalMcpServerOptions = { + bridge: SceneBridge + name?: string + version?: string +} + +export function createPascalMcpServer(opts: CreatePascalMcpServerOptions): McpServer { + const server = new McpServer({ + name: opts.name ?? 'pascal-mcp', + version: opts.version ?? '0.1.0', + }) + registerTools(server, opts.bridge) + registerVisionTools(server, opts.bridge) + registerResources(server, opts.bridge) + registerPrompts(server, opts.bridge) + return server +}