如何把 Pascal Editor 的 MCP 服务器嵌入自己的 Agent 框架:InMemory 实战指南
【免费下载链接】editorOpen-source 3D architectural editor with a local CLI, MCP tools, and practical workflows for humans and AI agents.项目地址: https://gitcode.com/GitHub_Trending/editor93/editor
如果你正在自建 Agent 框架,希望模型能直接做 3D 建模,Pascal Editor 的@pascal-app/mcp包支持 InMemory 内嵌方式,把整个 MCP 服务器装进你的 Node/Bun 进程:不起子进程、不占端口、不依赖外部数据库,Agent 在同一次运行里就能建墙、开门窗、摆家具、撤销重做并导出 JSON。
拆成三个对象,一次说清进程内装配
MCP(Model Context Protocol)是一套让模型以标准方式调用工具、读取资源的协议,客户端和服务器之间靠"传输"通信。内嵌场景只需要三个对象,各管一事:
SceneBridge:无头场景桥,直连@pascal-app/core的 Zustand store,所有变更走真实 store,所以撤销/重做天然可用。类比"接线板"——它把服务器接到真实车间,而不是模拟车间。createPascalMcpServer:服务器工厂,接收bridge、store等选项,返回装配好的McpServer。类比"装配线"——零件塞进去,成品拿出来。InMemoryTransport:内存传输对,createLinkedPair()返回两个端点,客户端与服务器各接一端即可对话。类比一根"电话线"——两头都在同一间屋子里。
三者组合的价值在于:stdio、HTTP、内存三种传输暴露的 tools / resources / prompts 完全一致,选内存方式只是省掉进程边界,因此同一套代码可以直接写进 Agent 框架的单测。
跑通最小链路,让 Agent 建起第一面墙
官方示例 embed-in-agent.ts 给了可直接运行的参考,核心就两段代码。
import { Client } from '@modelcontextprotocol/sdk/client/index.js' import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js' import { createPascalMcpServer, SceneBridge } from '@pascal-app/mcp' const bridge = new SceneBridge() bridge.loadDefault() // 预置 Site → Building → Level 三层结构 const server = createPascalMcpServer({ bridge }) // 按选项装配全部工具 const [srvT, cliT] = InMemoryTransport.createLinkedPair() // 一对相连端点 const client = new Client({ name: 'my-agent', version: '0.1.0' }) await Promise.all([server.connect(srvT), client.connect(cliT)])loadDefault()在空 store 里种出 Site → Building → Level,实现细节见 scene-bridge.ts;createPascalMcpServer的装配顺序见 server.ts。连接完成后,调用工具就和调用本地函数一样:
const tools = await client.listTools() const scene = await client.callTool({ name: 'get_scene', arguments: {} }) // 查楼层 → 建 5 米墙 → 一步撤销 const levels = await client.callTool({ name: 'find_nodes', arguments: { type: 'level' } }) await client.callTool({ name: 'create_wall', arguments: { levelId, start: [0, 0], end: [5, 0] } }) await client.callTool({ name: 'undo', arguments: { steps: 1 } })示例文件里还串了validate_scene校验与export_json导出,从查询到落盘一条链走完。
盘点工具清单,知道它替你做了什么
内嵌后你的 Agent 立刻拥有 30 余个建筑建模工具,全部经 Zod 校验,变更操作由 Zundo 捕获为单个可撤销步骤。分组速览:
| 分组 | 常用工具 |
|---|---|
| 场景查询 | get_scene/get_node/describe_node/find_nodes/get_level_summary/measure |
| 结构建模 | create_story_shell/create_room/create_wall/create_level/create_roof/duplicate_level |
| 门窗开洞 | add_door/add_window/cut_opening |
| 家具布置 | place_item/furnish_room/set_zone |
| 批量变更 | apply_patch(create/update/delete 原子提交,先校验再落库) |
| 校验导出 | validate_scene/verify_scene/check_collisions/export_json |
| 时间轴 | undo/redo |
完整参数与返回结构在 packages/mcp/README.md 的工具表里。除工具外,服务器还暴露了 5 个资源(如pascal://scene/current场景快照、pascal://agent/guide给 Agent 的建造规则)和 3 个提示模板(from_brief、iterate_on_feedback、renovation_from_photos),把"80㎡两居室"这类文字需求转成增量修改序列。
把工具表喂给 LLM,闭上 ReAct 环
内嵌的落点只有一个:工具调用在你的代码里路由。listTools()返回的就是 MCP 工具定义(名称、描述、输入 schema),可直接映射成 LLM 的 function-calling 格式;模型返回工具调用后,再喂回callTool():
const llmCall = await llm.decide({ tools: tools.tools, message }) const result = await client.callTool({ name: llmCall.name, arguments: llmCall.args, }) // result 作为观察结果喂回 LLM,循环继续为什么这样接:没有进程边界,"思考 → 调工具 → 读场景 → 再思考"可以发生在同一事件循环里,比 stdio 子进程少了进程启停与序列化开销,单测里也能秒级拉起完整客户端-服务器对跑。
拧动三个注入点,把扩展做进骨架
createPascalMcpServer的选项是官方预留的扩展位,类型定义见 server.ts:
store:实现 SceneStore 接口(save/load/list/delete/rename等),注入后服务器自动注册save_scene、load_scene、list_scenes等持久化工具。包内置本地 SQLite 实现 createSceneStore,也可换成 Supabase 或自研库。场景:会话结束后把场景落盘,下次运行直接加载。executeTool:包装每一次工具调用,拿到name、AbortSignal和execute回调。场景:审计日志、耗时统计、按工具名做权限拦截。operations:替换整套场景操作层(operations/),工具不再走默认实现。场景:多场景协同、自定义提交策略或业务校验。
const server = createPascalMcpServer({ bridge, store: await createSceneStore(), // 本地 SQLite 持久化 executeTool: ({ name, execute }) => { console.log(`[audit] ${name}`) // 每次调用记一条审计 return execute() }, })过一遍避坑清单,少走弯路
- 坐标拿不准:Pascal 是右手系,X/Z 为地面平面、Y 朝上,长度单位米、旋转弧度,2D 平面点
[x, z]直接映射世界坐标;拿不准时先读 coordinate-conventions-demo.md。 - 写入报版本冲突:与编辑器共享数据目录时,MCP 写入会做版本检查,冲突返回
live_sync_version_conflict——用load_scene重新加载再改。 - 能力边界:
export_glb依赖浏览器渲染器,无头模式返回not_implemented,改用export_json;视觉工具(analyze_floorplan_image等)要求客户端声明 sampling 能力,否则直接调用会失败。 - 内存悄悄涨:无头模式下
dirtyNodes会累积,需要可观测性时调用bridge.flushDirty()排空。
一条链收束,全链路长这样
new SceneBridge().loadDefault()→createPascalMcpServer({ bridge })→InMemoryTransport.createLinkedPair()→client.callTool(...):预置场景、装配工具、内存接线、函数级调用,四步走完,你的 Agent 就在一行箭头里拥有了完整建筑建模能力。更多生成公寓、照片转场景等工作流,可看 packages/mcp/examples/ 目录。
【免费下载链接】editorOpen-source 3D architectural editor with a local CLI, MCP tools, and practical workflows for humans and AI agents.项目地址: https://gitcode.com/GitHub_Trending/editor93/editor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考