* feat(MCP): follow agent activity in canvas * fix(fig): preserve imported design fidelity Keep component overrides, variable-backed icon colors, page backgrounds, and fixed text sizing intact across lazy FIG materialization. * feat: add selection-context MCP tools and mode * chore: scope work branch to MCP selection and canvas follow * fix: honor MCP-only tool contracts in CI * refactor(mcp): drop the follow and selection-context tools this branch carried Following agents landed in #725, through the agents registry and the chat's follow toggle, so this branch's MCP follow setting and its follow-agent module are superseded. The see_user_selection and get_user_selection_details tools duplicated get_selection, get_node, describe, get_page_tree, and export_image; the selection-only workflow they served is rebuilt on those tools in the following commits. Co-authored-by: Victor Wads <victor@wads.dev> * feat(mcp): make get_selection the compact entry point with a depth get_selection returned every selected layer's whole subtree, which is too much as the first call when the user points at a large frame. It now returns the selection with direct children by default, counts deeper children as childCount, and takes a depth. Co-authored-by: Victor Wads <victor@wads.dev> * feat(mcp): share only the selection with MCP clients A selection scope, set with Share only the selection in the local server settings or OPENPENCIL_MCP_SCOPE=selection, limits MCP clients to get_selection, get_node, get_page_tree, describe, and export_image on the selected layers and what they hold. The server enforces the scope on everything it sends to the app: MCP sessions and /rpc, which stdio clients also go through, carry only those tool calls and the session-closed notice, each stamped with the scope, so a client cannot reach other tools or the settings that would widen it. The app's bridge rejects node IDs outside the selection, points describe and export_image at the selection when they name no nodes, and asks get_page_tree for a root inside it. A stdio client can ask for the scope itself while the server shares the whole document. Co-authored-by: Victor Wads <victor@wads.dev> * fix(mcp): keep selection-scoped clients from writing files or listing wider tools export_image writes its result to a file when given a path and an MCP root is set, which reaches past reading the selection. A path is now refused in selection scope, by the tool registration before the call and by the app's bridge, so a client with a stale scope cannot write either; the image itself is still returned. A stdio client follows the narrower of its own scope and the scope the server records, instead of letting OPENPENCIL_MCP_SCOPE=document list tools a selection-scoped server rejects. Co-authored-by: Victor Wads <victor@wads.dev> * test(mcp): name the selection scope's tools instead of reading the allowlist The server test compared the listed tools with SELECTION_SCOPE_TOOLS, the same list that decides registration, so a tool added to it by mistake would still pass. It now names the five tools the scope offers. Co-authored-by: Victor Wads <victor@wads.dev> --------- Co-authored-by: Danila Poyarkov <dev@dannote.net>
84 lines
2 KiB
JSON
84 lines
2 KiB
JSON
{
|
|
"name": "@open-pencil/mcp",
|
|
"version": "0.15.1",
|
|
"license": "MIT",
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "git+https://github.com/open-pencil/open-pencil.git",
|
|
"directory": "packages/mcp"
|
|
},
|
|
"bin": {
|
|
"openpencil-mcp": "./dist/stdio.mjs",
|
|
"openpencil-mcp-http": "./dist/index.mjs"
|
|
},
|
|
"files": [
|
|
"dist",
|
|
"src"
|
|
],
|
|
"type": "module",
|
|
"main": "./dist/server.mjs",
|
|
"imports": {
|
|
"#mcp/*": {
|
|
"types": "./src/*.ts",
|
|
"bun": "./src/*.ts",
|
|
"default": "./dist/*.mjs"
|
|
}
|
|
},
|
|
"exports": {
|
|
".": {
|
|
"types": "./dist/server.d.mts",
|
|
"import": "./dist/server.mjs",
|
|
"default": "./dist/server.mjs"
|
|
},
|
|
"./stdio": {
|
|
"types": "./dist/stdio.d.mts",
|
|
"import": "./dist/stdio.mjs",
|
|
"default": "./dist/stdio.mjs"
|
|
},
|
|
"./transport": {
|
|
"types": "./dist/transport.d.mts",
|
|
"bun": "./src/transport/paths.ts",
|
|
"import": "./dist/transport.mjs",
|
|
"default": "./dist/transport.mjs"
|
|
},
|
|
"./discovery": {
|
|
"types": "./dist/discovery.d.mts",
|
|
"bun": "./src/transport/discovery.ts",
|
|
"import": "./dist/discovery.mjs",
|
|
"default": "./dist/discovery.mjs"
|
|
},
|
|
"./tools": {
|
|
"types": "./dist/tools.d.mts",
|
|
"bun": "./src/tool/index.ts",
|
|
"import": "./dist/tools.mjs",
|
|
"default": "./dist/tools.mjs"
|
|
}
|
|
},
|
|
"publishConfig": {
|
|
"access": "public",
|
|
"provenance": true
|
|
},
|
|
"scripts": {
|
|
"build": "bunx tsdown --config tsdown.config.ts",
|
|
"prepublishOnly": "bun run build"
|
|
},
|
|
"dependencies": {
|
|
"@hono/node-server": "^1.19.17",
|
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
"@open-pencil/core": "workspace:*",
|
|
"@open-pencil/design-jsx": "workspace:*",
|
|
"@open-pencil/scene-graph": "workspace:*",
|
|
"@valibot/to-json-schema": "^1.8.0",
|
|
"es-toolkit": "^1.52.0",
|
|
"hono": "^4.13.13",
|
|
"js-base64": "^3.9.3",
|
|
"package-manager-detector": "^1.8.0",
|
|
"valibot": "^1.5.0",
|
|
"ws": "^8.21.3"
|
|
},
|
|
"devDependencies": {
|
|
"@types/node": "^25.9.9",
|
|
"@types/ws": "^8.18.1"
|
|
}
|
|
}
|