@github/computer-use-mcp 0.1.19 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -10
- package/dist/prebuilds/darwin-arm64/computer.node +0 -0
- package/dist/prebuilds/darwin-x64/computer.node +0 -0
- package/dist/prebuilds/win32-arm64/computer.node +0 -0
- package/dist/prebuilds/win32-x64/computer.node +0 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ export interface AsyncComputer {
|
|
|
65
65
|
};
|
|
66
66
|
isMinimized: boolean;
|
|
67
67
|
}>>;
|
|
68
|
-
prepareForInput(displayId: string,
|
|
68
|
+
prepareForInput(displayId: string, allowedAppIds: string[]): Promise<boolean>;
|
|
69
69
|
foregroundTargetId(): Promise<string | null>;
|
|
70
70
|
activateApplication(applicationId: string): Promise<boolean>;
|
|
71
71
|
concealApplication(applicationId: string): Promise<boolean>;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{McpServer as
|
|
1
|
+
import{McpServer as ne}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as u}from"zod";var x=class{knownApplications=new Map;allowedAppIds=new Set;accessActive=!1;allowAll=!1;rememberApplications(e){this.knownApplications.clear();for(let t of e)this.knownApplications.set(t.id,t);if(this.allowAll)for(let t of e)this.allowedAppIds.add(t.id)}getKnownApplications(e){return e.map(t=>{let i=this.knownApplications.get(t);if(!i)throw new Error(`Unknown application id '${t}'. Call list_applications first.`);return i})}allowApplications(e,t=!1){this.getKnownApplications(e),this.accessActive=!0;for(let i of e)this.allowedAppIds.add(i);if(t){this.allowAll=!0;for(let i of this.knownApplications.keys())this.allowedAppIds.add(i)}return this.getState()}areAllowedForAccess(e){return this.getKnownApplications(e),this.allowAll||e.every(t=>this.allowedAppIds.has(t))}getState(){return{accessActive:this.accessActive,allowedAppIds:[...this.allowedAppIds],allowAll:this.allowAll}}};function C(n){let e=new Map,t=[...n].sort((i,s)=>`${i.applicationName}\0${i.title}\0${i.windowId}`.localeCompare(`${s.applicationName}\0${s.title}\0${s.windowId}`));for(let i of t){let s=i.applicationName||i.title||i.applicationId,o=e.get(i.applicationId);o||(o={id:i.applicationId,displayName:s,windows:[]},e.set(i.applicationId,o)),o.windows.push({windowId:i.windowId,title:i.title,displayId:i.displayId,isMinimized:i.isMinimized})}return[...e.values()].sort((i,s)=>`${i.displayName}\0${i.id}`.localeCompare(`${s.displayName}\0${s.id}`))}var X=new Set(["ctrl","control","shift","alt","option","super","meta","cmd","command","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","return","enter","tab","space","backspace","delete","forwarddelete","escape","esc","up","down","left","right","home","end","pageup","pagedown","insert","capslock","f1","f2","f3","f4","f5","f6","f7","f8","f9","f10","f11","f12","-","minus","=","equal","plus","[","]","\\",";","'",",",".","/","`"]),G={arrowup:"up",arrowdown:"down",arrowleft:"left",arrowright:"right",page_up:"pageup",page_down:"pagedown",backslash:"\\",semicolon:";",slash:"/",grave:"`",bracketleft:"[",bracketright:"]",super_l:"super",gui:"super",caps_lock:"capslock",caps:"capslock",del:"delete"};function B(n){n==="+"?n="plus":n.length>2&&n.endsWith("++")&&(n=n.slice(0,-1)+"plus");let e=n.split("+").map(i=>i.trim().toLowerCase()).filter(Boolean);if(e.length===0)throw new Error("Key combo must contain at least one key.");return e.map(i=>{let s=G[i]??i;if(!X.has(s))throw new Error(`Unknown key "${i}" in combo "${n}".`);return s}).join("+")}import{existsSync as K,mkdirSync as J,readFileSync as Q,writeFileSync as R}from"fs";import{homedir as V}from"os";import{join as E}from"path";var F="<!-- LOG -->",W=class{constructor(e,t=E(V(),".copilot","logs","github-computer-use-mcp")){this.inner=e;this.logDir=t,this.path=E(this.logDir,`${this.timestamp()}.html`),K(this.logDir)||J(this.logDir,{recursive:!0}),R(this.path,`<!DOCTYPE html>
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
@@ -16,16 +16,16 @@ import{McpServer as V}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as
|
|
|
16
16
|
<body>
|
|
17
17
|
<table>
|
|
18
18
|
<tr><th>Time</th><th>Action</th><th>Arguments</th></tr>
|
|
19
|
-
${
|
|
19
|
+
${F}
|
|
20
20
|
</table>
|
|
21
21
|
</body>
|
|
22
22
|
</html>
|
|
23
|
-
`)}inner;logDir;path;startTime=performance.now();timestamp(){let e=new Date,t=(i,s=2)=>String(i).padStart(s,"0");return`${e.getFullYear()}${t(e.getMonth()+1)}${t(e.getDate())}-${t(e.getHours())}${t(e.getMinutes())}${t(e.getSeconds())}.${t(Math.floor(e.getMilliseconds()/10))}`}elapsed(){return`${((performance.now()-this.startTime)/1e3).toFixed(2)}s`}insert(e){let t=
|
|
24
|
-
`)}async checkPermissions(e){return this.inner.checkPermissions(e)}async requestPermissions(e){return this.inner.requestPermissions(e)}async capabilities(){let e=await this.inner.capabilities();return this.row("capabilities",JSON.stringify(e)),e}async click(e,t,i,s,
|
|
25
|
-
`)}else this.row("screenshot",'<span class="error">failed</span>');return a}};import{createRequire as
|
|
26
|
-
`)}function
|
|
27
|
-
`)}var
|
|
28
|
-
`),requestedSchema:{type:"object",properties:{action:{type:"string",title:`Grant ${i.join(" and ")} permission${i.length>1?"s":""}`,oneOf:[{const:"open",title:"1. Open System Settings"},{const:"done",title:"2. I've granted the permissions"},{const:"skip",title:"3. Skip (things may not work)"}]}},required:["action"]}}),
|
|
29
|
-
`),requestedSchema:{type:"object",properties:{action:{type:"string",title:"Confirm permissions",oneOf:[{const:"done",title:"1. I've granted the permissions"},{const:"skip",title:"2. Skip (things may not work)"}]}},required:["action"]}});if((l.action==="accept"?l.content?.action:void 0)!=="done")break}else if(p!=="done")break;if(s=await t.checkPermissions("accessibility"),n=await t.checkPermissions("screen"),!s||!n){let l=[];throw s||l.push("Accessibility"),n||l.push("Screen Recording"),new Error(`${l.join(" and ")} permission${l.length>1?"s are":" is"} still not detected. This usually means you need to restart your terminal after granting the permission. Please quit and reopen your terminal, then try again.`)}}break}}}async activeDisplayId(e){return this.selectedDisplay!==""?this.selectedDisplay:(await e.listDisplays()).find(i=>i.isPrimary)?.displayId??""}async requireAccess(){let e=this.accessStore.getState();if(!e.accessActive)throw new Error("No access session is active. Call request_access first to start a session.");return{computer:await this.computer(),approvedAppIds:e.approvedAppIds}}async prepareForInput(e,t){let i=await this.capabilities();if(!i.canListWindows||t.length===0)return;let s=await this.activeDisplayId(e),n=new Set(t),a=(await e.listWindows()).filter(p=>!p.isMinimized&&p.displayId===s&&n.has(p.applicationId));if(a.length===0)throw new Error("No approved visible windows are available on the selected display.");if(await e.prepareForInput(s,t))return;let c=await e.foregroundTargetId();if(!a.some(p=>p.windowId===c||p.applicationId===c)){if(i.canActivateWindow){await e.activateWindow(a[0].windowId);return}i.canActivateApplication&&await e.activateApplication(a[0].applicationId)}}};function se(o,e){o.registerTool("list_displays",{description:"List available displays and the currently selected display used for screenshots, zoom, cursor position, and coordinate-based actions.",annotations:f},async()=>{let n=await(await e.computer()).listDisplays();return b({displays:n,selectedDisplay:e.selectedDisplay})}),o.registerTool("select_display",{description:"Select the active display used for screenshots, zoom, cursor position, and coordinate-based actions. Omit display_id or pass an empty string to use the default display.",inputSchema:ee.shape,annotations:N},async({display_id:s})=>{let n=s??"",a=await(await e.computer()).listDisplays();if(n!==""&&!a.some(p=>p.displayId===n))throw new Error(`Unknown display id '${n}'. Call list_displays first.`);e.selectedDisplay=n;let c=n===""?a.find(p=>p.isPrimary)??null:a.find(p=>p.displayId===n)??null;return b({selectedDisplay:e.selectedDisplay,status:"selected",message:n===""?"Using the default display for screenshots, zoom, cursor position, and coordinate-based actions.":`Selected display '${c?.label??n}' for screenshots, zoom, cursor position, and coordinate-based actions.`})}),o.registerTool("list_applications",{description:"List running desktop applications with stable ids that can be approved via request_access.",annotations:f},async()=>{let s=await e.computer(),n=M(await s.listWindows());return e.accessStore.rememberApplications(n),b({applications:n})}),o.registerTool("request_access",{description:"Request access to previously listed applications using client-side form elicitation. Pass an empty apps array to request desktop-only access (clipboard and empty desktop screenshots). IMPORTANT: Call `list_applications` first to discover apps, then call this tool before using access-gated tools such as screenshot, click, type, or clipboard. If you launch a new app (via Start, Dock, script, etc.), call `list_applications` and `request_access` again to add it to the approved set \u2014 it won't be visible in screenshots until approved.",inputSchema:{apps:u.array(Q).describe("Applications to approve. Pass an empty array for desktop-only access."),reason:u.string().min(1).optional().describe("Optional reason text shown in the approval dialog.")},annotations:N},async({apps:s,reason:n})=>{if(await e.requestPermission(o),(await e.capabilities()).canListWindows&&s&&s.length>0){let d=s.map(v=>v.id),g=e.accessStore.getKnownApplications(d),w=g.length,S=w===1?"app":"apps";if(e.accessStore.areApprovedForAccess(d)){let v=e.accessStore.getState();return b({approved:!0,status:"approved",decision:"session",approvedAppIds:v.approvedAppIds,accessActive:v.accessActive,message:w===1?`'${g[0].displayName}' is already shared for this session.`:"The requested apps are already shared for this session."})}if(!o.server.getClientCapabilities()?.elicitation?.form)throw new Error("The connected MCP client does not support form elicitation, so request_access cannot continue yet.");let D=await o.server.elicitInput({mode:"form",message:te(g.map(v=>v.displayName),n),requestedSchema:{type:"object",properties:{decision:{type:"string",title:"Choose whether to allow these apps for this session",oneOf:[{const:"allow",title:`1. Allow for this session (${w} ${S})`},{const:"deny",title:"2. Deny, and tell Copilot what to do differently (Esc)"}]}},required:["decision"]}}),E=D.action==="accept"?D.content?.decision:void 0;if(D.action!=="accept"||E!=="allow")return b({approved:!1,status:"denied",approvedAppIds:e.accessStore.getState().approvedAppIds,accessActive:e.accessStore.getState().accessActive,message:w===1?`The user declined to share '${g[0].displayName}'.`:"The user declined to share the requested apps."});let R=e.accessStore.approveApplications(d);return b({approved:!0,status:"approved",decision:"session",approvedAppIds:R.approvedAppIds,accessActive:R.accessActive,message:w===1?`Access session started for '${g[0].displayName}'.`:"Access session started for the requested apps."})}if(e.accessStore.getState().accessActive){let d=e.accessStore.getState();return b({approved:!0,status:"approved",decision:"session",approvedAppIds:d.approvedAppIds,accessActive:d.accessActive,message:"Desktop access is already shared for this session."})}if(!o.server.getClientCapabilities()?.elicitation?.form)throw new Error("The connected MCP client does not support form elicitation, so request_access cannot continue yet.");let c=await o.server.elicitInput({mode:"form",message:ie(n),requestedSchema:{type:"object",properties:{decision:{type:"string",title:"Choose whether to allow desktop access for this session",oneOf:[{const:"allow",title:"1. Allow for this session"},{const:"deny",title:"2. Deny, and tell Copilot what to do differently (Esc)"}]}},required:["decision"]}}),p=c.action==="accept"?c.content?.decision:void 0;if(c.action!=="accept"||p!=="allow")return b({approved:!1,status:"denied",approvedAppIds:e.accessStore.getState().approvedAppIds,accessActive:e.accessStore.getState().accessActive,message:"The user declined desktop access."});let l=e.accessStore.approveDesktopAccess();return b({approved:!0,status:"approved",decision:"session",approvedAppIds:l.approvedAppIds,accessActive:l.accessActive,message:"Access session started for the desktop."})}),o.registerTool("screenshot",{description:"Capture the current screen. Take a screenshot before clicking to determine coordinates and after each action to verify the result. Screenshots are filtered to show only approved application windows. If no apps are approved (desktop-only session), shows an empty desktop with the dock."+h,annotations:f},async()=>{let{computer:s,approvedAppIds:n}=await e.requireAccess(),r=await s.screenshot(e.selectedDisplay,n,0,0,void 0,C);return F(r,"Screenshot failed",C)}),o.registerTool("cursor_position",{description:"Get the current cursor position in pixel coordinates. Returns {x, y}."+h,annotations:f},async()=>{let n=await(await e.computer()).cursorPosition(e.selectedDisplay);return m(`${n.x},${n.y}`)});let t={coordinate:$.optional().describe("{x, y} pixel coordinate to click at. Clicks at current cursor position if omitted.")},i=(s,n,r,a)=>{o.registerTool(s,{description:n+h,inputSchema:t,annotations:y},async({coordinate:c})=>{let{computer:p,approvedAppIds:l}=await e.requireAccess();await e.prepareForInput(p,l),c&&await p.move(c.x,c.y,e.selectedDisplay);let d=c??await p.cursorPosition(e.selectedDisplay);return await p.click(d.x,d.y,r,a,e.selectedDisplay),m(`${s}${c?` at (${c.x},${c.y})`:""}`)})};i("left_click","Click the left mouse button. Optionally move to a coordinate first.","left",1),i("right_click","Click the right mouse button. Optionally move to a coordinate first.","right",1),i("middle_click","Click the middle mouse button. Optionally move to a coordinate first.","middle",1),i("double_click","Double-click the left mouse button. Optionally move to a coordinate first.","left",2),i("triple_click","Triple-click the left mouse button. Optionally move to a coordinate first.","left",3),o.registerTool("mouse_move",{description:"Move the mouse cursor to the specified pixel coordinate."+h,inputSchema:{coordinate:$.describe("{x, y} pixel coordinate to move the cursor to.")},annotations:y},async({coordinate:s})=>{let{computer:n,approvedAppIds:r}=await e.requireAccess();return await e.prepareForInput(n,r),await n.move(s.x,s.y,e.selectedDisplay),m(`Moved to (${s.x},${s.y})`)}),o.registerTool("left_click_drag",{description:"Click and drag from a start coordinate to an end coordinate."+h,inputSchema:{start_coordinate:$.describe("{x, y} pixel coordinate to start the drag from."),coordinate:$.describe("{x, y} pixel coordinate to drag to.")},annotations:y},async({start_coordinate:s,coordinate:n})=>{let{computer:r,approvedAppIds:a}=await e.requireAccess();return await e.prepareForInput(r,a),await r.drag(s.x,s.y,n.x,n.y,e.selectedDisplay),m(`Dragged (${s.x},${s.y}) -> (${n.x},${n.y})`)}),o.registerTool("left_mouse_down",{description:"Press and hold the left mouse button at the current cursor position."+h,annotations:y},async()=>{let{computer:s,approvedAppIds:n}=await e.requireAccess();await e.prepareForInput(s,n);let r=await s.cursorPosition(e.selectedDisplay);return await s.mouseDown(r.x,r.y,e.selectedDisplay),m(`Mouse down at (${r.x},${r.y})`)}),o.registerTool("left_mouse_up",{description:"Release the left mouse button at the current cursor position."+h,annotations:y},async()=>{let{computer:s,approvedAppIds:n}=await e.requireAccess();await e.prepareForInput(s,n);let r=await s.cursorPosition(e.selectedDisplay);return await s.mouseUp(r.x,r.y,e.selectedDisplay),m(`Mouse up at (${r.x},${r.y})`)}),o.registerTool("type",{description:"Type a string of text using the keyboard."+h,inputSchema:{text:u.string().describe("The text to type.")},annotations:y},async({text:s})=>{let{computer:n,approvedAppIds:r}=await e.requireAccess();return await e.prepareForInput(n,r),await n.type(s),m(`Typed ${s.length} chars`)}),o.registerTool("key",{description:"Press a key or key combination. Examples: 'Return', 'ctrl+s', 'alt+Tab', 'BackSpace'."+h,inputSchema:{text:u.string().describe("Key combo to press (e.g. 'Return', 'ctrl+s', 'alt+Tab').")},annotations:y},async({text:s})=>{let{computer:n,approvedAppIds:r}=await e.requireAccess();await e.prepareForInput(n,r);let a=x(s);return await n.key(a),m(`Pressed ${a}`)}),o.registerTool("hold_key",{description:"Hold a key down for a specified duration in seconds."+h,inputSchema:{text:u.string().describe("Key name to hold (e.g. 'shift', 'ctrl')."),duration:u.number().nonnegative().max(100).describe("Seconds to hold the key (max 100).")},annotations:y},async({text:s,duration:n})=>{let{computer:r,approvedAppIds:a}=await e.requireAccess();await e.prepareForInput(r,a);let c=x(s);return await r.key(c),m(`Held ${c} for ${n}s`)}),o.registerTool("scroll",{description:"Scroll the screen in a given direction at an optional coordinate."+h,inputSchema:{scroll_direction:u.enum(["up","down","left","right"]).describe("Direction to scroll."),coordinate:$.optional().describe("{x, y} pixel coordinate to scroll at. Scrolls at current cursor position if omitted."),scroll_amount:u.number().int().nonnegative().max(100).optional().describe("Number of scroll clicks (default 3).")},annotations:y},async({scroll_direction:s,coordinate:n,scroll_amount:r})=>{let{computer:a,approvedAppIds:c}=await e.requireAccess();await e.prepareForInput(a,c);let p=r??3,l=await a.cursorPosition(e.selectedDisplay),d=n?.x??l.x,g=n?.y??l.y,w=s==="left"?-p:s==="right"?p:0,S=s==="down"?p:s==="up"?-p:0;return await a.scroll(d,g,w,S,e.selectedDisplay),m(`Scrolled ${s} ${p} at (${d},${g})`)}),o.registerTool("wait",{description:"Pause for a specified duration in seconds.",inputSchema:{duration:u.number().nonnegative().max(100).describe("Seconds to wait (max 100).")},annotations:{...f,idempotentHint:!0}},async({duration:s})=>(await new Promise(n=>setTimeout(n,s*1e3)),m(`Waited ${s}s`))),o.registerTool("get_clipboard",{description:"Get the current text contents of the system clipboard."+h,annotations:f},async()=>{let{computer:s}=await e.requireAccess(),n=await s.getClipboard();return m(n)}),o.registerTool("set_clipboard",{description:"Set the system clipboard to the specified text."+h,inputSchema:{text:u.string().describe("The text to copy to the clipboard.")},annotations:N},async({text:s})=>{let{computer:n}=await e.requireAccess();return await n.setClipboard(s),m(`Clipboard set (${s.length} chars)`)}),o.registerTool("zoom",{description:"Capture a specific region of the screen at full resolution for detailed inspection. The region is defined by top-left (x1, y1) and bottom-right (x2, y2) coordinates in the screenshot coordinate space. Like screenshots, only approved application windows are shown."+h,inputSchema:{region:Z.describe("{x1, y1, x2, y2} coordinates defining top-left and bottom-right corners of the region to capture.")},annotations:f},async({region:s})=>{let{computer:n,approvedAppIds:r}=await e.requireAccess(),a=await n.screenshot(e.selectedDisplay,r,0,0,[s.x1,s.y1,s.x2,s.y2],C);return F(a,"Zoom screenshot failed",C)})}function Ae(){let o=new V({name:"computer-use",version:"1.0.0"},{instructions:["This MCP server provides desktop automation tools (mouse, keyboard, screenshots, clipboard).","Before using access-gated tools (screenshot, click, type, clipboard, etc.), you MUST call `request_access` to start an access session.","If available, call `list_applications` first to discover apps, then pass the desired app IDs to `request_access`.","For tasks that only need the clipboard or a view of the desktop (dock, wallpaper), call `request_access` with an empty apps array.","Screenshots and zoom captures are composited to show ONLY the windows of approved applications (plus system UI like the Dock). Unapproved app windows are not visible.","If you launch a new app during the session, call `list_applications` and `request_access` again to add it \u2014 newly launched apps are not visible or interactable until approved."].join(`
|
|
30
|
-
`)}),e=new
|
|
23
|
+
`)}inner;logDir;path;startTime=performance.now();timestamp(){let e=new Date,t=(i,s=2)=>String(i).padStart(s,"0");return`${e.getFullYear()}${t(e.getMonth()+1)}${t(e.getDate())}-${t(e.getHours())}${t(e.getMinutes())}${t(e.getSeconds())}.${t(Math.floor(e.getMilliseconds()/10))}`}elapsed(){return`${((performance.now()-this.startTime)/1e3).toFixed(2)}s`}insert(e){let t=Q(this.path,"utf-8");R(this.path,t.replace(F,e+F))}row(e,t){this.insert(`<tr><td class="time">${this.elapsed()}</td><td class="action">${e}</td><td>${t}</td></tr>
|
|
24
|
+
`)}async checkPermissions(e){return this.inner.checkPermissions(e)}async requestPermissions(e){return this.inner.requestPermissions(e)}async capabilities(){let e=await this.inner.capabilities();return this.row("capabilities",JSON.stringify(e)),e}async click(e,t,i,s,o=""){await this.inner.click(e,t,i,s,o),this.row("click",`(${e}, ${t}) button=${i} count=${s}${o?` display=${o}`:""}`)}async move(e,t,i=""){await this.inner.move(e,t,i),this.row("move",`(${e}, ${t})${i?` display=${i}`:""}`)}async drag(e,t,i,s,o=""){await this.inner.drag(e,t,i,s,o),this.row("drag",`(${e}, ${t}) \u2192 (${i}, ${s})${o?` display=${o}`:""}`)}async mouseDown(e,t,i=""){await this.inner.mouseDown(e,t,i),this.row("mouseDown",`(${e}, ${t})${i?` display=${i}`:""}`)}async mouseUp(e,t,i=""){await this.inner.mouseUp(e,t,i),this.row("mouseUp",`(${e}, ${t})${i?` display=${i}`:""}`)}async type(e){await this.inner.type(e);let t=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");this.row("type",`"${t}"`)}async key(e){await this.inner.key(e),this.row("key",e)}async scroll(e,t,i,s,o=""){await this.inner.scroll(e,t,i,s,o),this.row("scroll",`(${e}, ${t}) dx=${i} dy=${s}${o?` display=${o}`:""}`)}async cursorPosition(e=""){let t=await this.inner.cursorPosition(e);return this.row("cursorPosition",`(${t.x}, ${t.y})${e?` display=${e}`:""}`),t}async display(e=""){let t=await this.inner.display(e);return this.row("display",`${t.width}\xD7${t.height}${e?` display=${e}`:""}`),t}async listDisplays(){let e=await this.inner.listDisplays();return this.row("listDisplays",`${e.length} displays`),e}async listWindows(){let e=await this.inner.listWindows();return this.row("listWindows",`${e.length} windows`),e}async foregroundTargetId(){let e=await this.inner.foregroundTargetId();return this.row("foregroundTargetId",e??"null"),e}async activateApplication(e){let t=await this.inner.activateApplication(e);return this.row("activateApplication",`${e} -> ${t}`),t}async concealApplication(e){let t=await this.inner.concealApplication(e);return this.row("concealApplication",`${e} -> ${t}`),t}async restoreApplication(e){let t=await this.inner.restoreApplication(e);return this.row("restoreApplication",`${e} -> ${t}`),t}async activateWindow(e){let t=await this.inner.activateWindow(e);return this.row("activateWindow",`${e} -> ${t}`),t}async concealWindow(e){let t=await this.inner.concealWindow(e);return this.row("concealWindow",`${e} -> ${t}`),t}async restoreWindow(e){let t=await this.inner.restoreWindow(e);return this.row("restoreWindow",`${e} -> ${t}`),t}async getClipboard(){let e=await this.inner.getClipboard(),t=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");return this.row("getClipboard",`"${t.slice(0,200)}${t.length>200?"\u2026":""}"`),e}async setClipboard(e){await this.inner.setClipboard(e);let t=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");this.row("setClipboard",`"${t.slice(0,200)}${t.length>200?"\u2026":""}" (${e.length} chars)`)}async prepareForInput(e,t){let i=await this.inner.prepareForInput(e,t);return this.row("prepareForInput",`${e} -> ${i} (${t.length} apps)`),i}async screenshot(e,t,i,s,o,r){let a=await this.inner.screenshot(e,t,i,s,o,r);if(a){let c=r===void 0?"png":"jpg",l=`${this.timestamp()}.${c}`;R(E(this.logDir,l),a);let p=i&&s?` (${i}\xD7${s})`:"",d=o?` crop=[${o.join(",")}]`:"";this.insert(`<tr><td class="time">${this.elapsed()}</td><td class="action">screenshot</td><td>${p}${d}<br><img src="${l}"></td></tr>
|
|
25
|
+
`)}else this.row("screenshot",'<span class="error">failed</span>');return a}};import{createRequire as Z}from"module";import{dirname as ee,join as te}from"path";import{fileURLToPath as ie}from"url";var se=Z(import.meta.url),oe=ee(ie(import.meta.url)),T=class n{constructor(e){this.native=e}native;static create(){let e=te(oe,"prebuilds",`${process.platform}-${process.arch}`,"computer.node"),t;try{t=se(e)}catch(i){let s=i instanceof Error?i.message:String(i);throw new Error(`Native computer bindings not available for ${process.platform}-${process.arch}: ${s} (path: ${e})`,{cause:i})}return new n(t)}async checkPermissions(e){return this.native.checkPermissions(e)}async requestPermissions(e){this.native.requestPermissions(e)}async click(e,t,i,s,o=""){let r=this.resolveCoordinateSpace(o);this.assertPointInBounds(r,e,t);let[a,c]=this.toNative(r,e,t);this.native.click(a,c,i,s)}async move(e,t,i=""){let s=this.resolveCoordinateSpace(i);this.assertPointInBounds(s,e,t);let[o,r]=this.toNative(s,e,t);this.native.move(o,r)}async drag(e,t,i,s,o=""){let r=this.resolveCoordinateSpace(o);this.assertPointInBounds(r,e,t),this.assertPointInBounds(r,i,s);let[a,c]=this.toNative(r,e,t),[l,p]=this.toNative(r,i,s);this.native.drag(a,c,l,p)}async mouseDown(e,t,i=""){let s=this.resolveCoordinateSpace(i);this.assertPointInBounds(s,e,t);let[o,r]=this.toNative(s,e,t);this.native.mouseDown(o,r)}async mouseUp(e,t,i=""){let s=this.resolveCoordinateSpace(i);this.assertPointInBounds(s,e,t);let[o,r]=this.toNative(s,e,t);this.native.mouseUp(o,r)}async type(e){this.native.type(e)}async key(e){this.native.key(e)}async scroll(e,t,i,s,o=""){let r=this.resolveCoordinateSpace(o);this.assertPointInBounds(r,e,t);let[a,c]=this.toNative(r,e,t);this.native.scroll(a,c,i,s)}async cursorPosition(e=""){let t=this.native.cursorPosition(),i=this.resolveCoordinateSpace(e),[s,o]=this.fromNative(i,t.x,t.y);return{x:s,y:o}}async display(e=""){let t=this.resolveCoordinateSpace(e);return{width:t.targetWidth,height:t.targetHeight}}async screenshot(e,t,i,s,o,r){let a=this.resolveCoordinateSpace(e,i,s),c=r??-1;if(o){this.assertRegionEdgeInBounds(a,o[0],o[1]),this.assertRegionEdgeInBounds(a,o[2],o[3]);let[l,p,d,y]=this.toNativeCrop(a,o[0],o[1],o[2],o[3]);return this.native.screenshot(e,t,0,0,l,p,d,y,c)}return this.native.screenshot(e,t,a.targetWidth,a.targetHeight,0,0,0,0,c)}async capabilities(){return this.native.capabilities()}async listDisplays(){return this.native.listDisplays()}async listWindows(){return this.native.listWindows()}async foregroundTargetId(){return this.native.foregroundTargetId?this.native.foregroundTargetId():null}async activateApplication(e){return this.native.activateApplication(e)}async concealApplication(e){return this.native.concealApplication(e)}async restoreApplication(e){return this.native.restoreApplication(e)}async activateWindow(e){return this.native.activateWindow(e)}async concealWindow(e){return this.native.concealWindow(e)}async restoreWindow(e){return this.native.restoreWindow(e)}async getClipboard(){return this.native.getClipboard()}async setClipboard(e){this.native.setClipboard(e)}async prepareForInput(e,t){return this.native.prepareForInput(e,t)}resolveDisplay(e){let t=this.native.listDisplays();return e!==""?t.find(i=>i.displayId===e):t.find(i=>i.isPrimary)??t[0]}targetSizeForDisplay(e,t,i=0,s=0){if(i>0&&s>0)return{targetWidth:i,targetHeight:s};let a=Math.min(1,1568/Math.max(e,t),Math.sqrt(115e4/(e*t)));return{targetWidth:Math.floor(e*a),targetHeight:Math.floor(t*a)}}resolveCoordinateSpace(e,t=0,i=0){let s=this.resolveDisplay(e),o=s?.bounds.x??0,r=s?.bounds.y??0,a=s?void 0:this.native.display(),c=s?.bounds.width??a?.width??1,l=s?.bounds.height??a?.height??1,{targetWidth:p,targetHeight:d}=this.targetSizeForDisplay(c,l,t,i);return{originX:o,originY:r,displayWidth:c,displayHeight:l,scaleX:p/c,scaleY:d/l,targetWidth:p,targetHeight:d}}toNative(e,t,i){return[e.originX+t/e.scaleX,e.originY+i/e.scaleY]}toNativeCrop(e,t,i,s,o){return[Math.floor(t/e.scaleX),Math.floor(i/e.scaleY),Math.ceil(s/e.scaleX),Math.ceil(o/e.scaleY)]}assertPointInBounds(e,t,i){if(!Number.isFinite(t)||!Number.isFinite(i))throw new RangeError(`Coordinates must be finite numbers: x=${t}, y=${i}`);if(t<0||i<0||t>=e.targetWidth||i>=e.targetHeight)throw new RangeError(`Coordinates out of bounds for target display: x=${t}, y=${i}, width=${e.targetWidth}, height=${e.targetHeight}`)}assertRegionEdgeInBounds(e,t,i){if(!Number.isFinite(t)||!Number.isFinite(i))throw new RangeError(`Coordinates must be finite numbers: x=${t}, y=${i}`);if(t<0||i<0||t>e.targetWidth||i>e.targetHeight)throw new RangeError(`Crop coordinates out of bounds for target display: x=${t}, y=${i}, width=${e.targetWidth}, height=${e.targetHeight}`)}fromNative(e,t,i){return[Math.round((t-e.originX)*e.scaleX),Math.round((i-e.originY)*e.scaleY)]}};function m(n,e){let t=[{type:"text",text:n}];return e?{content:t,isError:!0}:{content:t}}function q(n){return m(JSON.stringify(n,null,2))}var _=.8,v={readOnlyHint:!0,destructiveHint:!1,openWorldHint:!1},f={readOnlyHint:!1,destructiveHint:!0,openWorldHint:!0},j={readOnlyHint:!1,destructiveHint:!1,openWorldHint:!1},h=" Requires an active access session via `request_access`.",O=" If you do not see an expected application window, you MUST call `list_applications` then `request_access` to add it before retrying.";function L(n,e,t){return n?{content:[{type:"image",data:n.toString("base64"),mimeType:t!==void 0?"image/jpeg":"image/png",_meta:{screenshot:!0}}]}:m(e,!0)}var I=u.coerce.number().transform(Math.round),S=u.object({x:I.describe("Horizontal pixel coordinate."),y:I.describe("Vertical pixel coordinate.")}),re=u.object({x1:I.describe("Left edge of the region in screenshot pixel coordinates."),y1:I.describe("Top edge of the region in screenshot pixel coordinates."),x2:I.describe("Right edge of the region in screenshot pixel coordinates."),y2:I.describe("Bottom edge of the region in screenshot pixel coordinates.")}).refine(({x1:n,x2:e})=>e>n,{message:"x2 must be greater than x1.",path:["x2"]}).refine(({y1:n,y2:e})=>e>n,{message:"y2 must be greater than y1.",path:["y2"]}),ae=u.object({id:u.string().min(1).describe("Stable application id returned by list_applications.")}),le=u.object({display_id:u.string().optional().describe("Display id to select. Omit or pass an empty string to use the default display.")});function ce(n,e){let t=n.length===0?["","Computer Use runs on your actual desktop and can send mouse and keyboard input.","","Computer Use wants to control your desktop."]:["","Computer Use runs on your actual desktop and can send mouse and keyboard input to the apps you share.","","Computer Use wants to control these apps:","",...n.map(i=>`- ${i}`)];return e&&t.push("","Reason:",e),t.join(`
|
|
26
|
+
`)}function pe(n){let e=["","Computer Use runs on your actual desktop and can send mouse and keyboard input.","","Computer Use wants access to your desktop for this session."];return n&&e.push("","Reason:",n),e.join(`
|
|
27
|
+
`)}var H=class{_computer;_caps;accessStore=new x;selectedDisplay="";async computer(){return this._computer||(this._computer=T.create(),process.env.DEBUG&&(this._computer=new W(this._computer))),this._computer}async capabilities(){if(!this._caps){let e=await this.computer();this._caps=await e.capabilities()}return this._caps}async requestPermission(e){switch(process.platform){case"linux":{await(await this.computer()).display();break}case"darwin":{let t=await this.computer(),i=[],s=await t.checkPermissions("accessibility");s||i.push("Accessibility");let o=await t.checkPermissions("screen");if(o||i.push("Screen Recording"),i.length>0){if(!e.server.getClientCapabilities()?.elicitation?.form)throw new Error(`macOS requires ${i.join(" and ")} permission${i.length>1?"s":""}. Grant them in System Settings > Privacy & Security, then restart your terminal.`);let a=["",`Computer Use needs the following macOS permission${i.length>1?"s":""} to control your desktop:`,"",...i.map(p=>`\u2022 ${p}`),"",'Clicking "Open System Settings" will open the relevant settings page(s).',`Enable the permission${i.length>1?"s":""} for your terminal app, then click "I've granted the permissions".`,"","Note: You may need to restart your terminal after granting permissions for them to take effect."],c=await e.server.elicitInput({mode:"form",message:a.join(`
|
|
28
|
+
`),requestedSchema:{type:"object",properties:{action:{type:"string",title:`Grant ${i.join(" and ")} permission${i.length>1?"s":""}`,oneOf:[{const:"open",title:"1. Open System Settings"},{const:"done",title:"2. I've granted the permissions"},{const:"skip",title:"3. Skip (things may not work)"}]}},required:["action"]}}),l=c.action==="accept"?c.content?.action:void 0;if(l==="open"){s||await t.requestPermissions("accessibility"),o||await t.requestPermissions("screen");let p=await e.server.elicitInput({mode:"form",message:["","System Settings has been opened.","",`Enable ${i.join(" and ")} for your terminal app.`,i.length>1?"Both settings pages have been opened \u2014 check each one.":"","",`After granting permissions, click "I've granted the permissions" below.`,"If the toggle was already on, try removing and re-adding your terminal app."].filter(Boolean).join(`
|
|
29
|
+
`),requestedSchema:{type:"object",properties:{action:{type:"string",title:"Confirm permissions",oneOf:[{const:"done",title:"1. I've granted the permissions"},{const:"skip",title:"2. Skip (things may not work)"}]}},required:["action"]}});if((p.action==="accept"?p.content?.action:void 0)!=="done")break}else if(l!=="done")break;if(s=await t.checkPermissions("accessibility"),o=await t.checkPermissions("screen"),!s||!o){let p=[];throw s||p.push("Accessibility"),o||p.push("Screen Recording"),new Error(`${p.join(" and ")} permission${p.length>1?"s are":" is"} still not detected. This usually means you need to restart your terminal after granting the permission. Please quit and reopen your terminal, then try again.`)}}break}}}async activeDisplayId(e){return this.selectedDisplay!==""?this.selectedDisplay:(await e.listDisplays()).find(i=>i.isPrimary)?.displayId??""}async requireAccess(){let e=this.accessStore.getState();if(!e.accessActive)throw new Error("No access session is active. Call request_access first to start a session.");let t=await this.computer();if(e.allowAll&&(await this.capabilities()).canListWindows){let s=C(await t.listWindows());this.accessStore.rememberApplications(s),e=this.accessStore.getState()}return{computer:t,allowedAppIds:e.allowedAppIds}}async prepareForInput(e,t){let i=await this.capabilities();if(!i.canListWindows||t.length===0)return;let s=await this.activeDisplayId(e),o=new Set(t),a=(await e.listWindows()).filter(l=>!l.isMinimized&&l.displayId===s&&o.has(l.applicationId));if(a.length===0)throw new Error("No allowed visible windows are available on the selected display.");if(await e.prepareForInput(s,t))return;let c=await e.foregroundTargetId();if(!a.some(l=>l.windowId===c||l.applicationId===c)){if(i.canActivateWindow){await e.activateWindow(a[0].windowId);return}i.canActivateApplication&&await e.activateApplication(a[0].applicationId)}}};function de(n,e){n.registerTool("list_displays",{description:"List available displays and the currently selected display used for screenshots, zoom, cursor position, and coordinate-based actions.",annotations:v},async()=>{let o=await(await e.computer()).listDisplays();return q({displays:o,selectedDisplay:e.selectedDisplay})}),n.registerTool("select_display",{description:"Select the active display used for screenshots, zoom, cursor position, and coordinate-based actions. Omit display_id or pass an empty string to use the default display.",inputSchema:le.shape,annotations:j},async({display_id:s})=>{let o=s??"",a=await(await e.computer()).listDisplays();if(o!==""&&!a.some(l=>l.displayId===o))throw new Error(`Unknown display id '${o}'. Call list_displays first.`);e.selectedDisplay=o;let c=o===""?a.find(l=>l.isPrimary)??null:a.find(l=>l.displayId===o)??null;return q({selectedDisplay:e.selectedDisplay,status:"selected",message:o===""?"Using the default display for screenshots, zoom, cursor position, and coordinate-based actions.":`Selected display '${c?.label??o}' for screenshots, zoom, cursor position, and coordinate-based actions.`})}),n.registerTool("list_applications",{description:"List running desktop applications with stable ids that can be allowed via request_access.",annotations:v},async()=>{let s=await e.computer(),o=C(await s.listWindows());return e.accessStore.rememberApplications(o),q({applications:o})}),n.registerTool("request_access",{description:"Request access to previously listed applications using client-side form elicitation. Pass an empty apps array to request access to all apps on the selected display. IMPORTANT: Call `list_applications` first to discover apps when you want to allow specific apps, then call this tool before using access-gated tools such as screenshot, click, type, or clipboard. Returns: `{ allowed: boolean, allowAll: boolean, allowedAppIds?: string[], message: string }`. If `allowAll` is true, all current and future apps are allowed for this session and you do not need to call `request_access` again. Otherwise, if you launch a new app (via Start, Dock, script, etc.), call `list_applications` and `request_access` again to add it to the allowed set.",inputSchema:{apps:u.array(ae).describe("Applications to allow. Pass an empty array to allow all apps on the selected display."),reason:u.string().min(1).optional().describe("Optional reason text shown in the access dialog.")},annotations:j},async({apps:s,reason:o})=>{await e.requestPermission(n);let r=await e.capabilities();if(!n.server.getClientCapabilities()?.elicitation?.form)throw new Error("The connected MCP client does not support form elicitation, so request_access cannot continue yet.");let c=(g,$,N)=>q({allowed:g,allowAll:$.allowAll,...$.allowAll?{}:{allowedAppIds:$.allowedAppIds},message:N}),l,p,d,y;if(r.canListWindows){let g=await e.computer(),$=await g.listWindows(),N=C($);e.accessStore.rememberApplications(N);let U=s&&s.length>0?"":await e.activeDisplayId(g),P=s&&s.length>0?e.accessStore.getKnownApplications(s.map(w=>w.id)):C($.filter(w=>!w.isMinimized&&(U===""||w.displayId===U))),D=P.map(w=>w.id),M=e.accessStore.getState(),b=P.length,Y=b===1?"app":"apps";p=["allow","allow_all"],d=D.length===0?M.allowAll||M.accessActive:e.accessStore.areAllowedForAccess(D),y=D.length===0?M.allowAll?"Access is already configured to auto-allow future requests for this session, so you do not need to call request_access again.":"Desktop access is already active for this session.":b===1?`'${P[0].displayName}' is already shared for this session.`:"The requested apps are already shared for this session.",l={choices:[{const:"allow",title:b===0?"1. Allow for this session":`1. Allow for this session (${b} ${Y})`},{const:"allow_all",title:"2. Allow all and don't ask again for this session"},{const:"deny",title:"3. Deny, and tell Copilot what to do differently (Esc)"}],message:ce(P.map(w=>w.displayName),o),denyMessage:b===0?"The user declined desktop access.":b===1?`The user declined to share '${P[0].displayName}'.`:"The user declined to share the requested apps.",allow:w=>e.accessStore.allowApplications(D,w==="allow_all"),allowedMessage:w=>w==="allow_all"?"All current and future apps are allowed for the rest of this session, so you do not need to call request_access again.":b===0?"Desktop access is active for this session.":b===1?`Access session started for '${P[0].displayName}'.`:"Access session started for the requested apps."}}else{let g=e.accessStore.getState();p=["allow_all"],d=g.allowAll||g.accessActive,y=g.allowAll?"Access is already configured to auto-allow future requests for this session, so you do not need to call request_access again.":"Desktop access is already active for this session.",l={choices:[{const:"allow_all",title:"1. Allow all for this session"},{const:"deny",title:"2. Deny, and tell Copilot what to do differently (Esc)"}],message:pe(o),denyMessage:"The user declined desktop access.",allow:()=>e.accessStore.allowApplications([],!0),allowedMessage:()=>"Access session started for the desktop. All current and future apps are allowed for the rest of this session, so you do not need to call request_access again."}}if(d){let g=e.accessStore.getState();return c(!0,g,y)}let k=await n.server.elicitInput({mode:"form",message:l.message,requestedSchema:{type:"object",properties:{decision:{type:"string",title:"Choose how to allow access for this session",oneOf:l.choices}},required:["decision"]}}),A=k.action==="accept"?k.content?.decision:void 0;if(k.action!=="accept"||!A||!p.includes(A)){let g=e.accessStore.getState();return c(!1,g,l.denyMessage)}let z=l.allow(A);return c(!0,z,l.allowedMessage(A))}),n.registerTool("screenshot",{description:"Capture the current screen. Take a screenshot before clicking to determine coordinates and after each action to verify the result. Screenshots are filtered to show only allowed application windows."+O+h,annotations:v},async()=>{let{computer:s,allowedAppIds:o}=await e.requireAccess(),r=await s.screenshot(e.selectedDisplay,o,0,0,void 0,_);return L(r,"Screenshot failed",_)}),n.registerTool("cursor_position",{description:"Get the current cursor position in pixel coordinates. Returns {x, y}."+h,annotations:v},async()=>{let o=await(await e.computer()).cursorPosition(e.selectedDisplay);return m(`${o.x},${o.y}`)});let t={coordinate:S.optional().describe("{x, y} pixel coordinate to click at. Clicks at current cursor position if omitted.")},i=(s,o,r,a)=>{n.registerTool(s,{description:o+h,inputSchema:t,annotations:f},async({coordinate:c})=>{let{computer:l,allowedAppIds:p}=await e.requireAccess();await e.prepareForInput(l,p),c&&await l.move(c.x,c.y,e.selectedDisplay);let d=c??await l.cursorPosition(e.selectedDisplay);return await l.click(d.x,d.y,r,a,e.selectedDisplay),m(`${s}${c?` at (${c.x},${c.y})`:""}`)})};i("left_click","Click the left mouse button. Optionally move to a coordinate first.","left",1),i("right_click","Click the right mouse button. Optionally move to a coordinate first.","right",1),i("middle_click","Click the middle mouse button. Optionally move to a coordinate first.","middle",1),i("double_click","Double-click the left mouse button. Optionally move to a coordinate first.","left",2),i("triple_click","Triple-click the left mouse button. Optionally move to a coordinate first.","left",3),n.registerTool("mouse_move",{description:"Move the mouse cursor to the specified pixel coordinate."+h,inputSchema:{coordinate:S.describe("{x, y} pixel coordinate to move the cursor to.")},annotations:f},async({coordinate:s})=>{let{computer:o,allowedAppIds:r}=await e.requireAccess();return await e.prepareForInput(o,r),await o.move(s.x,s.y,e.selectedDisplay),m(`Moved to (${s.x},${s.y})`)}),n.registerTool("left_click_drag",{description:"Click and drag from a start coordinate to an end coordinate."+h,inputSchema:{start_coordinate:S.describe("{x, y} pixel coordinate to start the drag from."),coordinate:S.describe("{x, y} pixel coordinate to drag to.")},annotations:f},async({start_coordinate:s,coordinate:o})=>{let{computer:r,allowedAppIds:a}=await e.requireAccess();return await e.prepareForInput(r,a),await r.drag(s.x,s.y,o.x,o.y,e.selectedDisplay),m(`Dragged (${s.x},${s.y}) -> (${o.x},${o.y})`)}),n.registerTool("left_mouse_down",{description:"Press and hold the left mouse button at the current cursor position."+h,annotations:f},async()=>{let{computer:s,allowedAppIds:o}=await e.requireAccess();await e.prepareForInput(s,o);let r=await s.cursorPosition(e.selectedDisplay);return await s.mouseDown(r.x,r.y,e.selectedDisplay),m(`Mouse down at (${r.x},${r.y})`)}),n.registerTool("left_mouse_up",{description:"Release the left mouse button at the current cursor position."+h,annotations:f},async()=>{let{computer:s,allowedAppIds:o}=await e.requireAccess();await e.prepareForInput(s,o);let r=await s.cursorPosition(e.selectedDisplay);return await s.mouseUp(r.x,r.y,e.selectedDisplay),m(`Mouse up at (${r.x},${r.y})`)}),n.registerTool("type",{description:"Type a string of text using the keyboard."+h,inputSchema:{text:u.string().describe("The text to type.")},annotations:f},async({text:s})=>{let{computer:o,allowedAppIds:r}=await e.requireAccess();return await e.prepareForInput(o,r),await o.type(s),m(`Typed ${s.length} chars`)}),n.registerTool("key",{description:"Press a key or key combination. Examples: 'Return', 'ctrl+s', 'alt+Tab', 'BackSpace'."+h,inputSchema:{text:u.string().describe("Key combo to press (e.g. 'Return', 'ctrl+s', 'alt+Tab').")},annotations:f},async({text:s})=>{let{computer:o,allowedAppIds:r}=await e.requireAccess();await e.prepareForInput(o,r);let a=B(s);return await o.key(a),m(`Pressed ${a}`)}),n.registerTool("scroll",{description:"Scroll the screen in a given direction at an optional coordinate."+h,inputSchema:{scroll_direction:u.enum(["up","down","left","right"]).describe("Direction to scroll."),coordinate:S.optional().describe("{x, y} pixel coordinate to scroll at. Scrolls at current cursor position if omitted."),scroll_amount:u.number().int().nonnegative().max(100).optional().describe("Number of scroll clicks (default 3).")},annotations:f},async({scroll_direction:s,coordinate:o,scroll_amount:r})=>{let{computer:a,allowedAppIds:c}=await e.requireAccess();await e.prepareForInput(a,c);let l=r??3,p=await a.cursorPosition(e.selectedDisplay),d=o?.x??p.x,y=o?.y??p.y,k=s==="left"?-l:s==="right"?l:0,A=s==="down"?l:s==="up"?-l:0;return await a.scroll(d,y,k,A,e.selectedDisplay),m(`Scrolled ${s} ${l} at (${d},${y})`)}),n.registerTool("wait",{description:"Pause for a specified duration in seconds.",inputSchema:{duration:u.number().nonnegative().max(100).describe("Seconds to wait (max 100).")},annotations:{...v,idempotentHint:!0}},async({duration:s})=>(await new Promise(o=>setTimeout(o,s*1e3)),m(`Waited ${s}s`))),n.registerTool("get_clipboard",{description:"Get the current text contents of the system clipboard."+h,annotations:v},async()=>{let{computer:s}=await e.requireAccess(),o=await s.getClipboard();return m(o)}),n.registerTool("set_clipboard",{description:"Set the system clipboard to the specified text."+h,inputSchema:{text:u.string().describe("The text to copy to the clipboard.")},annotations:j},async({text:s})=>{let{computer:o}=await e.requireAccess();return await o.setClipboard(s),m(`Clipboard set (${s.length} chars)`)}),n.registerTool("zoom",{description:"Capture a specific region of the screen at full resolution for detailed inspection. The region is defined by top-left (x1, y1) and bottom-right (x2, y2) coordinates in the screenshot coordinate space. Like screenshots, only allowed application windows are shown."+O+h,inputSchema:{region:re.describe("{x1, y1, x2, y2} coordinates defining top-left and bottom-right corners of the region to capture.")},annotations:v},async({region:s})=>{let{computer:o,allowedAppIds:r}=await e.requireAccess(),a=await o.screenshot(e.selectedDisplay,r,0,0,[s.x1,s.y1,s.x2,s.y2],_);return L(a,"Zoom screenshot failed",_)})}function De(){let n=new ne({name:"computer-use",version:"1.0.0"},{instructions:["This MCP server provides desktop automation tools (mouse, keyboard, screenshots, clipboard).","Before using access-gated tools (screenshot, click, type, clipboard, etc.), you MUST call `request_access` to start an access session.","If available, call `list_applications` first to discover apps, then pass the desired app IDs to `request_access`.","Calling `request_access` with an empty apps array allows all visible apps on the selected display. If none are visible, it falls back to desktop access and empty desktop screenshots until apps are allowed.","Screenshots and zoom captures are composited to show ONLY the windows of allowed applications (plus system UI like the Dock). Disallowed app windows are not visible.","If `request_access` returns `allowAll=true`, all current and future apps are allowed for the rest of this session and you do not need to call `request_access` again.","Otherwise, if you launch a new app during the session, call `list_applications` and `request_access` again to add it."].join(`
|
|
30
|
+
`)}),e=new H;return de(n,e),n}export{De as createServer};
|
|
31
31
|
//# sourceMappingURL=index.js.map
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|