Connect ACP agents to OpenPencil MCP tools
Pass openpencil-mcp as a stdio MCP server to the ACP session so agents get all design tools (create shapes, render JSX, export images, etc.) instead of just plain conversation. - Add makeFigma option to createServer for external FigmaAPI injection - Skip file lifecycle tools (open/save/new) when using external FigmaAPI - Pass MCP server config in ACP newSession mcpServers - Add bun to Tauri shell scope for MCP server subprocess
This commit is contained in:
parent
f02bd84aec
commit
e79fb5ac5d
|
|
@ -24,7 +24,8 @@
|
|||
"allow": [
|
||||
{ "name": "claude-code-acp", "cmd": "claude-code-acp", "args": true },
|
||||
{ "name": "codex-acp", "cmd": "codex-acp", "args": true },
|
||||
{ "name": "gemini", "cmd": "gemini", "args": true }
|
||||
{ "name": "gemini", "cmd": "gemini", "args": true },
|
||||
{ "name": "bun", "cmd": "bun", "args": true }
|
||||
]
|
||||
},
|
||||
"shell:allow-stdin-write",
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ type McpResult = { content: McpContent[]; isError?: boolean }
|
|||
export interface CreateServerOptions {
|
||||
enableEval?: boolean
|
||||
fileRoot?: string | null
|
||||
makeFigma?: () => FigmaAPI
|
||||
}
|
||||
|
||||
function ok(data: unknown): McpResult {
|
||||
|
|
@ -61,10 +62,13 @@ export function createServer(version: string, options: CreateServerOptions = {})
|
|||
? null
|
||||
: resolve(options.fileRoot)
|
||||
|
||||
const externalMakeFigma = options.makeFigma ?? null
|
||||
|
||||
let graph: SceneGraph | null = null
|
||||
let currentPageId: string | null = null
|
||||
|
||||
function makeFigma(): FigmaAPI {
|
||||
if (externalMakeFigma) return externalMakeFigma()
|
||||
if (!graph) throw new Error('No document loaded. Use open_file or new_document first.')
|
||||
const g = graph
|
||||
const api = new FigmaAPI(g)
|
||||
|
|
@ -112,6 +116,8 @@ export function createServer(version: string, options: CreateServerOptions = {})
|
|||
}
|
||||
|
||||
const register = server.registerTool.bind(server) as (...args: unknown[]) => void
|
||||
|
||||
if (!externalMakeFigma) {
|
||||
register(
|
||||
'open_file',
|
||||
{
|
||||
|
|
@ -170,6 +176,7 @@ export function createServer(version: string, options: CreateServerOptions = {})
|
|||
}
|
||||
}
|
||||
)
|
||||
} // end if (!externalMakeFigma)
|
||||
|
||||
register(
|
||||
'export_image_file',
|
||||
|
|
|
|||
|
|
@ -27,10 +27,14 @@ export class ACPChatTransport implements ChatTransport<UIMessage> {
|
|||
private session: ACPSession | null = null
|
||||
private agentDef: ACPAgentDef
|
||||
private cwd: string
|
||||
private mcpCommand?: string
|
||||
private mcpArgs: string[]
|
||||
|
||||
constructor(options: { agentDef: ACPAgentDef; cwd?: string }) {
|
||||
constructor(options: { agentDef: ACPAgentDef; cwd?: string; mcpCommand?: string; mcpArgs?: string[] }) {
|
||||
this.agentDef = options.agentDef
|
||||
this.cwd = options.cwd ?? '.'
|
||||
this.mcpCommand = options.mcpCommand
|
||||
this.mcpArgs = options.mcpArgs ?? []
|
||||
}
|
||||
|
||||
async sendMessages({
|
||||
|
|
@ -199,9 +203,13 @@ export class ACPChatTransport implements ChatTransport<UIMessage> {
|
|||
clientCapabilities: {}
|
||||
})
|
||||
|
||||
const mcpServers = this.mcpCommand
|
||||
? [{ name: 'open-pencil', command: this.mcpCommand, args: this.mcpArgs, env: [] }]
|
||||
: []
|
||||
|
||||
const sessionResult = await connection.newSession({
|
||||
cwd: this.cwd,
|
||||
mcpServers: []
|
||||
mcpServers
|
||||
})
|
||||
|
||||
const session: ACPSession = {
|
||||
|
|
|
|||
|
|
@ -209,8 +209,20 @@ async function createACPTransport() {
|
|||
if (!agentDef) throw new Error(`Unknown ACP agent: ${agentId}`)
|
||||
|
||||
const { ACPChatTransport } = await import('@/ai/acp-transport')
|
||||
const { homeDir } = await import('@tauri-apps/api/path')
|
||||
await acpTransportInstance?.destroy()
|
||||
const transport = new ACPChatTransport({ agentDef })
|
||||
|
||||
const mcpCommand = import.meta.env.DEV ? 'bun' : 'npx'
|
||||
const mcpArgs = import.meta.env.DEV
|
||||
? [import.meta.env.VITE_PROJECT_ROOT + '/packages/mcp/src/index.ts']
|
||||
: ['-y', '@open-pencil/mcp']
|
||||
|
||||
const transport = new ACPChatTransport({
|
||||
agentDef,
|
||||
cwd: await homeDir(),
|
||||
mcpCommand,
|
||||
mcpArgs
|
||||
})
|
||||
acpTransportInstance = transport
|
||||
return transport
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ import { automationPlugin } from './src/automation/vite-plugin'
|
|||
const host = process.env.TAURI_DEV_HOST
|
||||
|
||||
export default defineConfig(async () => ({
|
||||
define: {
|
||||
'import.meta.env.VITE_PROJECT_ROOT': JSON.stringify(__dirname)
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve(__dirname, 'src'),
|
||||
|
|
|
|||
Loading…
Reference in a new issue