fix(mcp): add shared operations and secure scene APIs
This commit is contained in:
@@ -5,6 +5,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
||||
import type { SceneGraph } from '@pascal-app/core/clone-scene-graph'
|
||||
import { type AnyNodeId, AnyNode as AnyNodeSchema } from '@pascal-app/core/schema'
|
||||
import { SceneBridge } from '../../bridge/scene-bridge'
|
||||
import { createSceneOperations } from '../../operations'
|
||||
import {
|
||||
InMemorySceneStore,
|
||||
parseToolText,
|
||||
@@ -56,8 +57,9 @@ async function setup(): Promise<{
|
||||
bridge.setScene({}, [])
|
||||
bridge.loadDefault()
|
||||
const store = new InMemorySceneStore()
|
||||
const operations = createSceneOperations({ bridge, store })
|
||||
const server = new McpServer({ name: 'test', version: '0.0.0' })
|
||||
registerGenerateVariants(server, bridge, store)
|
||||
registerGenerateVariants(server, operations)
|
||||
const [srvT, cliT] = InMemoryTransport.createLinkedPair()
|
||||
const client = new Client({ name: 'test-client', version: '0.0.0' })
|
||||
await Promise.all([server.connect(srvT), client.connect(cliT)])
|
||||
|
||||
@@ -2,8 +2,7 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
||||
import { forkSceneGraph, type SceneGraph } from '@pascal-app/core/clone-scene-graph'
|
||||
import { type AnyNode, AnyNode as AnyNodeSchema } from '@pascal-app/core/schema'
|
||||
import { z } from 'zod'
|
||||
import type { SceneBridge } from '../../bridge/scene-bridge'
|
||||
import type { SceneStore } from '../../storage/types'
|
||||
import type { SceneOperations } from '../../operations'
|
||||
import { ErrorCode, throwMcpError } from '../errors'
|
||||
import { applyMutation, describeVariant, type MutationKind, mulberry32 } from './mutations'
|
||||
|
||||
@@ -93,17 +92,13 @@ function countInvalidNodes(graph: SceneGraph): number {
|
||||
return invalid
|
||||
}
|
||||
|
||||
export function registerGenerateVariants(
|
||||
server: McpServer,
|
||||
bridge: SceneBridge,
|
||||
store: SceneStore,
|
||||
): void {
|
||||
export function registerGenerateVariants(server: McpServer, bridge: SceneOperations): void {
|
||||
server.registerTool(
|
||||
'generate_variants',
|
||||
{
|
||||
title: 'Generate variants',
|
||||
description:
|
||||
'Generate N variations of a base scene by forking and applying seeded mutations. Example: "give me 5 variations of this kitchen". If `save=true`, each variant is persisted via the SceneStore and returned with an id + URL; otherwise the graph is returned inline.',
|
||||
'Generate N variations of a base scene by forking and applying seeded mutations. Example: "give me 5 variations of this kitchen". If `save=true`, each variant is persisted via scene operations and returned with an id + URL; otherwise the graph is returned inline.',
|
||||
inputSchema: generateVariantsInput,
|
||||
outputSchema: generateVariantsOutput,
|
||||
},
|
||||
@@ -112,19 +107,14 @@ export function registerGenerateVariants(
|
||||
let base: SceneGraph
|
||||
let baseName = 'scene'
|
||||
if (baseSceneId) {
|
||||
const loaded = await store.load(baseSceneId)
|
||||
const loaded = await bridge.loadStoredScene(baseSceneId)
|
||||
if (!loaded) {
|
||||
throwMcpError(ErrorCode.InvalidParams, 'scene_not_found', { id: baseSceneId })
|
||||
}
|
||||
base = loaded.graph
|
||||
baseName = loaded.name
|
||||
} else {
|
||||
const exported = bridge.exportJSON()
|
||||
base = {
|
||||
nodes: exported.nodes,
|
||||
rootNodeIds: exported.rootNodeIds,
|
||||
collections: exported.collections as SceneGraph['collections'],
|
||||
}
|
||||
base = bridge.exportSceneGraph()
|
||||
}
|
||||
|
||||
// 2. Seed the RNG. Default seed is a time-ish number so runs vary, but
|
||||
@@ -167,7 +157,7 @@ export function registerGenerateVariants(
|
||||
|
||||
if (save) {
|
||||
try {
|
||||
const meta = await store.save({
|
||||
const meta = await bridge.saveScene({
|
||||
name: `${baseName}-variant-${i + 1}`,
|
||||
graph: forked,
|
||||
})
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
||||
import type { SceneBridge } from '../../bridge/scene-bridge'
|
||||
import type { SceneStore } from '../../storage/types'
|
||||
import type { SceneOperations } from '../../operations'
|
||||
import { registerGenerateVariants } from './generate-variants'
|
||||
|
||||
/**
|
||||
* Register the variant-generation MCP tools against the given server. Uses the
|
||||
* supplied `SceneStore` both to load a `baseSceneId` (when provided) and to
|
||||
* persist variants when `save=true`.
|
||||
* Register the variant-generation MCP tools against shared scene operations.
|
||||
*/
|
||||
export function registerVariantTools(
|
||||
server: McpServer,
|
||||
bridge: SceneBridge,
|
||||
store: SceneStore,
|
||||
): void {
|
||||
registerGenerateVariants(server, bridge, store)
|
||||
export function registerVariantTools(server: McpServer, bridge: SceneOperations): void {
|
||||
registerGenerateVariants(server, bridge)
|
||||
}
|
||||
|
||||
export {
|
||||
|
||||
Reference in New Issue
Block a user