@dyrra/mcp 0.1.1
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/README.md +37 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/status.d.ts +20 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +100 -0
- package/dist/status.js.map +1 -0
- package/dist/tools.d.ts +9 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +314 -0
- package/dist/tools.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @dyrra/mcp
|
|
2
|
+
|
|
3
|
+
MCP-сервер Dyrra: ИИ-агент видит экран Mac, кликает и печатает
|
|
4
|
+
в пределах прав, которые выдал владелец Mac.
|
|
5
|
+
|
|
6
|
+
## Claude Code
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
claude mcp add --env DYRRA_API_KEY=dk_live_… --env DYRRA_TARGET=con_… --transport stdio dyrra -- npx -y @dyrra/mcp
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Файл .mcp.json
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"mcpServers": {
|
|
17
|
+
"dyrra": {
|
|
18
|
+
"command": "npx",
|
|
19
|
+
"args": ["-y", "@dyrra/mcp"],
|
|
20
|
+
"env": { "DYRRA_API_KEY": "dk_live_…", "DYRRA_TARGET": "con_…" }
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Ключ и идентификатор подключения выдаёт консоль Dyrra.
|
|
27
|
+
|
|
28
|
+
Сервер регистрирует только инструменты, на которые у подключения есть
|
|
29
|
+
права: при всех правах их 17. Если видны только четыре — сервер не смог
|
|
30
|
+
узнать права (неверный ключ, цель или адрес), причина печатается в поток
|
|
31
|
+
ошибок.
|
|
32
|
+
|
|
33
|
+
| Переменная | Что это |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `DYRRA_API_KEY` | ключ API |
|
|
36
|
+
| `DYRRA_TARGET` | подключение `con_…` или облачный Mac `cmc_…` |
|
|
37
|
+
| `DYRRA_API_BASE_URL` | адрес gateway, по умолчанию `https://api.dyrra.dev` |
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import { Dyrra } from "@dyrra/sdk";
|
|
6
|
+
import { DEFAULT_API_BASE_URL } from "@dyrra/protocol";
|
|
7
|
+
import { registerTools } from "./tools.js";
|
|
8
|
+
/**
|
|
9
|
+
* MCP-сервер Dyrra (ТЗ 9.1).
|
|
10
|
+
*
|
|
11
|
+
* Инструменты, на которые у подключения нет прав, НЕ регистрируются:
|
|
12
|
+
* агент не видит того, что ему всё равно запретят.
|
|
13
|
+
*/
|
|
14
|
+
async function main() {
|
|
15
|
+
const apiKey = process.env["DYRRA_API_KEY"];
|
|
16
|
+
const target = process.env["DYRRA_TARGET"];
|
|
17
|
+
if (!apiKey || !target) {
|
|
18
|
+
console.error("Нужны переменные окружения DYRRA_API_KEY и DYRRA_TARGET.\n" +
|
|
19
|
+
"Готовый конфиг можно скопировать в консоли Dyrra.");
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
const client = new Dyrra(apiKey, {
|
|
23
|
+
baseUrl: process.env["DYRRA_API_BASE_URL"] ?? DEFAULT_API_BASE_URL,
|
|
24
|
+
});
|
|
25
|
+
const scopes = await resolveScopes(client, target);
|
|
26
|
+
const server = new McpServer({
|
|
27
|
+
name: "dyrra",
|
|
28
|
+
// Версия берётся из package.json, а не дублируется здесь: иначе она
|
|
29
|
+
// расходится с настоящей при первом же выпуске.
|
|
30
|
+
version: packageVersion(),
|
|
31
|
+
});
|
|
32
|
+
registerTools(server, client, target, {
|
|
33
|
+
scopes,
|
|
34
|
+
screenshotAfterAction: process.env["DYRRA_SCREENSHOT_AFTER_ACTION"] === "true",
|
|
35
|
+
});
|
|
36
|
+
await server.connect(new StdioServerTransport());
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Права берём у самого подключения. Для облачного Mac права полные,
|
|
40
|
+
* а список подключений к нему не относится.
|
|
41
|
+
*/
|
|
42
|
+
async function resolveScopes(client, target) {
|
|
43
|
+
if (!target.startsWith("con_")) {
|
|
44
|
+
return ["screen", "input", "shell", "files", "clipboard"];
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const connection = await client.connections.get(target);
|
|
48
|
+
return connection.scopes;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error(`Не удалось получить права подключения ${target}: ${String(error)}.\n` +
|
|
52
|
+
"Регистрирую только инструменты экрана.");
|
|
53
|
+
return ["screen"];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Версия пакета для рукопожатия MCP. */
|
|
57
|
+
function packageVersion() {
|
|
58
|
+
try {
|
|
59
|
+
const require = createRequire(import.meta.url);
|
|
60
|
+
return require("../package.json").version;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return "0.0.0";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
main().catch((error) => {
|
|
67
|
+
console.error("Не удалось запустить MCP-сервер Dyrra:", error);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAA+B,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;GAKG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAE3C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CACX,4DAA4D;YAC1D,mDAAmD,CACtD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE;QAC/B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,oBAAoB;KACnE,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,OAAO;QACb,oEAAoE;QACpE,gDAAgD;QAChD,OAAO,EAAE,cAAc,EAAE;KAC1B,CAAC,CAAC;IAEH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;QACpC,MAAM;QACN,qBAAqB,EAAE,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,KAAK,MAAM;KAC/E,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,aAAa,CAAC,MAAa,EAAE,MAAc;IACxD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC;QACH,MAAM,UAAU,GAAe,MAAM,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpE,OAAO,UAAU,CAAC,MAAM,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,yCAAyC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,KAAK;YACpE,wCAAwC,CAC3C,CAAC;QACF,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,yCAAyC;AACzC,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,OAAQ,OAAO,CAAC,iBAAiB,CAAyB,CAAC,OAAO,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Connection, Scope } from "@dyrra/protocol";
|
|
2
|
+
export interface StatusReport {
|
|
3
|
+
connectionId: string;
|
|
4
|
+
scopes: Scope[];
|
|
5
|
+
missingScopes: Scope[];
|
|
6
|
+
/** Можно ли сейчас смотреть на экран. */
|
|
7
|
+
canSee: boolean;
|
|
8
|
+
/** Можно ли сейчас управлять мышью и клавиатурой. */
|
|
9
|
+
canControl: boolean;
|
|
10
|
+
blockers: {
|
|
11
|
+
see: string[];
|
|
12
|
+
control: string[];
|
|
13
|
+
};
|
|
14
|
+
/** Права изменились после запуска MCP-сервера — список инструментов устарел. */
|
|
15
|
+
toolsOutdated: string | null;
|
|
16
|
+
machine: Connection["machine"];
|
|
17
|
+
}
|
|
18
|
+
export declare function statusReport(connection: Connection, registeredScopes: readonly Scope[]): StatusReport;
|
|
19
|
+
export declare function formatStatus(report: StatusReport): string;
|
|
20
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAyBzD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,aAAa,EAAE,KAAK,EAAE,CAAC;IACvB,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/C,gFAAgF;IAChF,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;CAChC;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,SAAS,KAAK,EAAE,GAAG,YAAY,CAiDrG;AAsBD,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAoBzD"}
|
package/dist/status.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Что агент может сделать прямо сейчас (ТЗ 9.1).
|
|
3
|
+
*
|
|
4
|
+
* Найдено на живом Mac: mac_status отдавал только состояние машины,
|
|
5
|
+
* и подключение без права input выглядело как `availability: "ready"`.
|
|
6
|
+
* Агент считал, что может работать, и получал отказ на каждом действии.
|
|
7
|
+
* Состояние Mac и права подключения — разные вещи, поэтому сводим их здесь.
|
|
8
|
+
*/
|
|
9
|
+
/** Что даёт каждое право — простыми словами и названиями инструментов. */
|
|
10
|
+
const SCOPE_ABILITIES = {
|
|
11
|
+
screen: "видеть экран (mac_screenshot, mac_ui_tree, mac_list_windows)",
|
|
12
|
+
input: "управлять мышью и клавиатурой, открывать приложения и ссылки " +
|
|
13
|
+
"(mac_click, mac_click_element, mac_drag, mac_scroll, mac_type, mac_key, mac_set_value, mac_open_app, mac_open_url)",
|
|
14
|
+
shell: "выполнять команды в терминале (mac_shell)",
|
|
15
|
+
files: "читать и записывать файлы в выбранных пользователем папках (mac_read_file)",
|
|
16
|
+
clipboard: "читать и записывать буфер обмена (mac_clipboard_get, mac_clipboard_set)",
|
|
17
|
+
record: "передавать записи сессий платформе",
|
|
18
|
+
};
|
|
19
|
+
const ALL_SCOPES = Object.keys(SCOPE_ABILITIES);
|
|
20
|
+
export function statusReport(connection, registeredScopes) {
|
|
21
|
+
const machine = connection.machine;
|
|
22
|
+
const has = (scope) => connection.scopes.includes(scope);
|
|
23
|
+
// Общее для любых действий: без связи, на паузе или во сне не сделать ничего.
|
|
24
|
+
const machineBlockers = [];
|
|
25
|
+
if (connection.status !== "active") {
|
|
26
|
+
machineBlockers.push("подключение отозвано пользователем");
|
|
27
|
+
}
|
|
28
|
+
if (!machine.online) {
|
|
29
|
+
machineBlockers.push(machine.lastSeenAt
|
|
30
|
+
? `Mac не на связи (последний раз ${machine.lastSeenAt})`
|
|
31
|
+
: "Mac ещё ни разу не выходил на связь");
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
if (machine.paused)
|
|
35
|
+
machineBlockers.push("пользователь поставил агента на паузу");
|
|
36
|
+
if (machine.availability !== "ready") {
|
|
37
|
+
machineBlockers.push(`Mac недоступен: ${machine.availability}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const see = [...machineBlockers];
|
|
41
|
+
if (!has("screen"))
|
|
42
|
+
see.push("нет права screen");
|
|
43
|
+
if (machine.permissions.screenRecording === false) {
|
|
44
|
+
see.push("на Mac не выдано разрешение macOS «Запись экрана»");
|
|
45
|
+
}
|
|
46
|
+
const control = [...machineBlockers];
|
|
47
|
+
if (!has("input")) {
|
|
48
|
+
control.push("нет права input: мышь, клавиатура, открытие приложений и ссылок будут отклонены. " +
|
|
49
|
+
"Выдать право может только пользователь — переподключив Mac с правом «Управлять мышью и клавиатурой»");
|
|
50
|
+
}
|
|
51
|
+
if (machine.permissions.accessibility === false) {
|
|
52
|
+
control.push("на Mac не выдано разрешение macOS «Универсальный доступ»");
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
connectionId: connection.id,
|
|
56
|
+
scopes: connection.scopes,
|
|
57
|
+
missingScopes: ALL_SCOPES.filter((scope) => !has(scope)),
|
|
58
|
+
canSee: see.length === 0,
|
|
59
|
+
canControl: control.length === 0,
|
|
60
|
+
blockers: { see, control },
|
|
61
|
+
toolsOutdated: describeOutdatedTools(connection.scopes, registeredScopes),
|
|
62
|
+
machine,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** Инструменты регистрируются при запуске: после смены прав их список расходится с правами. */
|
|
66
|
+
function describeOutdatedTools(live, registered) {
|
|
67
|
+
const revoked = registered.filter((scope) => !live.includes(scope));
|
|
68
|
+
const added = live.filter((scope) => !registered.includes(scope));
|
|
69
|
+
if (revoked.length === 0 && added.length === 0)
|
|
70
|
+
return null;
|
|
71
|
+
const parts = [];
|
|
72
|
+
if (revoked.length > 0) {
|
|
73
|
+
parts.push(`права ${revoked.join(", ")} отозваны после запуска MCP — их инструменты ещё видны, но будут отклонены`);
|
|
74
|
+
}
|
|
75
|
+
if (added.length > 0) {
|
|
76
|
+
parts.push(`права ${added.join(", ")} выданы после запуска MCP — их инструменты появятся после перезапуска MCP-клиента`);
|
|
77
|
+
}
|
|
78
|
+
return parts.join("; ");
|
|
79
|
+
}
|
|
80
|
+
export function formatStatus(report) {
|
|
81
|
+
const yesNo = (ok, blockers) => (ok ? "да" : `нет — ${blockers.join("; ")}`);
|
|
82
|
+
const lines = [
|
|
83
|
+
`Смотреть экран: ${yesNo(report.canSee, report.blockers.see)}`,
|
|
84
|
+
`Управлять мышью и клавиатурой: ${yesNo(report.canControl, report.blockers.control)}`,
|
|
85
|
+
"",
|
|
86
|
+
`Выданные права: ${report.scopes.join(", ") || "нет"}`,
|
|
87
|
+
...report.scopes.map((scope) => ` + ${scope}: ${SCOPE_ABILITIES[scope]}`),
|
|
88
|
+
...(report.missingScopes.length > 0
|
|
89
|
+
? [
|
|
90
|
+
"Не выданы:",
|
|
91
|
+
...report.missingScopes.map((scope) => ` − ${scope}: ${SCOPE_ABILITIES[scope]}`),
|
|
92
|
+
]
|
|
93
|
+
: []),
|
|
94
|
+
];
|
|
95
|
+
if (report.toolsOutdated)
|
|
96
|
+
lines.push("", `Внимание: ${report.toolsOutdated}.`);
|
|
97
|
+
lines.push("", JSON.stringify(report, null, 2));
|
|
98
|
+
return lines.join("\n");
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { Dyrra } from "@dyrra/sdk";
|
|
3
|
+
import type { Scope } from "@dyrra/protocol";
|
|
4
|
+
export interface ToolOptions {
|
|
5
|
+
scopes: Scope[];
|
|
6
|
+
screenshotAfterAction: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function registerTools(server: McpServer, client: Dyrra, targetId: string, options: ToolOptions): void;
|
|
9
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,KAAK,EAAU,KAAK,EAAc,MAAM,iBAAiB,CAAC;AAGjE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,qBAAqB,EAAE,OAAO,CAAC;CAChC;AA6DD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,KAAK,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GACnB,IAAI,CAsVN"}
|
package/dist/tools.js
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { DyrraApiError } from "@dyrra/sdk";
|
|
3
|
+
import { formatStatus, statusReport } from "./status.js";
|
|
4
|
+
/** Понятный текст вместо голого кода ошибки — агенту так проще исправиться. */
|
|
5
|
+
function explain(error) {
|
|
6
|
+
if (error instanceof DyrraApiError) {
|
|
7
|
+
switch (error.code) {
|
|
8
|
+
case "machine_paused":
|
|
9
|
+
return "Пользователь поставил агента на паузу. Действия сейчас невозможны.";
|
|
10
|
+
case "machine_unavailable":
|
|
11
|
+
return `Mac недоступен: ${String(error.details?.["reason"] ?? "неизвестно")}. Не пытайтесь разбудить его — дождитесь пользователя.`;
|
|
12
|
+
case "machine_offline":
|
|
13
|
+
return "Приложение Dyrra на Mac не подключено.";
|
|
14
|
+
case "machine_busy":
|
|
15
|
+
return "На этом Mac уже идёт другая управляющая сессия. Повторите через секунду.";
|
|
16
|
+
case "hidden_app_active":
|
|
17
|
+
return "Пользователь скрыл это приложение от агентов. Действие отклонено.";
|
|
18
|
+
case "denied_by_user":
|
|
19
|
+
return "Пользователь отклонил подтверждение этого действия.";
|
|
20
|
+
case "confirmation_timeout":
|
|
21
|
+
return "Пользователь не ответил на запрос подтверждения.";
|
|
22
|
+
case "permission_missing":
|
|
23
|
+
return `На Mac не выдано разрешение macOS: ${String(error.details?.["permission"] ?? "")}.`;
|
|
24
|
+
case "scope_denied":
|
|
25
|
+
return "У подключения нет права на это действие.";
|
|
26
|
+
case "snapshot_expired":
|
|
27
|
+
return "Снимок структуры экрана устарел. Запросите mac_ui_tree заново.";
|
|
28
|
+
case "app_not_frontmost": {
|
|
29
|
+
const expected = String(error.details?.["expected"] ?? "нужное приложение");
|
|
30
|
+
const actual = String(error.details?.["actualName"] || error.details?.["actual"] || "другое приложение");
|
|
31
|
+
return (`Активно «${actual}», а не ${expected}. Действие не выполнено — текст никуда не ушёл. ` +
|
|
32
|
+
"Вызовите mac_open_app для нужного приложения и повторите.");
|
|
33
|
+
}
|
|
34
|
+
default:
|
|
35
|
+
return `${error.code}: ${error.message}`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return String(error);
|
|
39
|
+
}
|
|
40
|
+
function text(value) {
|
|
41
|
+
return { content: [{ type: "text", text: value }] };
|
|
42
|
+
}
|
|
43
|
+
function fail(error) {
|
|
44
|
+
return { content: [{ type: "text", text: explain(error) }], isError: true };
|
|
45
|
+
}
|
|
46
|
+
function image(shot) {
|
|
47
|
+
return {
|
|
48
|
+
content: [
|
|
49
|
+
{ type: "image", data: shot.data, mimeType: shot.mime },
|
|
50
|
+
{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: `Экран ${shot.widthPoints}×${shot.heightPoints} точек. Координаты действий задавайте в точках.`,
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function registerTools(server, client, targetId, options) {
|
|
58
|
+
const target = client.targets(targetId);
|
|
59
|
+
const has = (scope) => options.scopes.includes(scope);
|
|
60
|
+
/* ── Наблюдение ─────────────────────────────────────────────────────── */
|
|
61
|
+
if (has("screen")) {
|
|
62
|
+
server.registerTool("mac_ui_tree", {
|
|
63
|
+
title: "Структура экрана",
|
|
64
|
+
description: "Список элементов активного окна с координатами и заголовками. " +
|
|
65
|
+
"Начинайте с него: это точнее и дешевле скриншота. " +
|
|
66
|
+
"Скриншот берите, когда структуры недостаточно (картинки, графика, вёрстка). " +
|
|
67
|
+
"По элементу можно кликнуть через mac_click_element, не угадывая пиксели.",
|
|
68
|
+
inputSchema: {
|
|
69
|
+
scope: z.enum(["frontmost", "all_windows", "menu_bar"]).default("frontmost"),
|
|
70
|
+
interactiveOnly: z.boolean().default(true),
|
|
71
|
+
},
|
|
72
|
+
}, async ({ scope, interactiveOnly }) => {
|
|
73
|
+
try {
|
|
74
|
+
const tree = await target.uiTree({ scope, interactiveOnly, format: "compact" });
|
|
75
|
+
const header = tree.app ? `Приложение: ${tree.app.name} (${tree.app.bundleId})\n` : "";
|
|
76
|
+
const body = tree.compact ?? JSON.stringify(tree.elements, null, 2);
|
|
77
|
+
const tail = tree.truncated ? "\n\n(дерево обрезано по лимиту элементов)" : "";
|
|
78
|
+
return text(`${header}snapshotId: ${tree.snapshotId}\n\n${body}${tail}`);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return fail(error);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
server.registerTool("mac_screenshot", {
|
|
85
|
+
title: "Снимок экрана",
|
|
86
|
+
description: "Картинка экрана. Координаты в ответе — логические точки; " +
|
|
87
|
+
"их же передавайте в действия.",
|
|
88
|
+
inputSchema: {
|
|
89
|
+
maxWidth: z.number().int().min(320).max(4096).optional(),
|
|
90
|
+
format: z.enum(["jpeg", "png"]).default("jpeg"),
|
|
91
|
+
},
|
|
92
|
+
}, async ({ maxWidth, format }) => {
|
|
93
|
+
try {
|
|
94
|
+
return image(await target.screenshot({ maxWidth, format }));
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
return fail(error);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
server.registerTool("mac_list_windows", { title: "Список окон", description: "Открытые окна и их положение." }, async () => {
|
|
101
|
+
try {
|
|
102
|
+
const { data } = await target.windows();
|
|
103
|
+
return text(JSON.stringify(data, null, 2));
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
return fail(error);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
server.registerTool("mac_status", {
|
|
110
|
+
title: "Состояние Mac",
|
|
111
|
+
description: "Что агент может сделать прямо сейчас: какие права выданы подключению, " +
|
|
112
|
+
"на связи ли Mac, не на паузе ли агент, выданы ли разрешения macOS. " +
|
|
113
|
+
"Вызывайте перед началом работы: availability говорит только о Mac, а не о правах.",
|
|
114
|
+
}, async () => {
|
|
115
|
+
try {
|
|
116
|
+
if (!targetId.startsWith("con_"))
|
|
117
|
+
return text("Облачный Mac: состояние доступно в консоли.");
|
|
118
|
+
const connection = await client.connections.get(targetId);
|
|
119
|
+
return text(formatStatus(statusReport(connection, options.scopes)));
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
return fail(error);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/* ── Управление ─────────────────────────────────────────────────────── */
|
|
127
|
+
if (has("input")) {
|
|
128
|
+
/**
|
|
129
|
+
* Последнее приложение, открытое через mac_open_app.
|
|
130
|
+
*
|
|
131
|
+
* Ввод текста и клавиш идёт в активное приложение. Без проверки текст
|
|
132
|
+
* уходил туда, где фокус был до этого, — например, в окно самого клиента
|
|
133
|
+
* агента. Поэтому mac_type и mac_key просят Mac сверить, что активно оно.
|
|
134
|
+
*/
|
|
135
|
+
let expectedApp;
|
|
136
|
+
const perform = async (actions, expectBundleId) => {
|
|
137
|
+
try {
|
|
138
|
+
await target.actions(actions, expectBundleId ? { expectBundleId } : {});
|
|
139
|
+
if (!options.screenshotAfterAction)
|
|
140
|
+
return text("Готово");
|
|
141
|
+
return image(await target.screenshot({ maxWidth: 1280 }));
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
return fail(error);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
server.registerTool("mac_click_element", {
|
|
148
|
+
title: "Клик по элементу",
|
|
149
|
+
description: "Нажать элемент из последнего mac_ui_tree по его id. " +
|
|
150
|
+
"Надёжнее, чем клик по координатам.",
|
|
151
|
+
inputSchema: { snapshotId: z.string(), elementId: z.string() },
|
|
152
|
+
}, ({ snapshotId, elementId }) => perform([{ type: "click_element", snapshotId, elementId }]));
|
|
153
|
+
server.registerTool("mac_set_value", {
|
|
154
|
+
title: "Заполнить поле",
|
|
155
|
+
description: "Ввести текст в поле из последнего mac_ui_tree.",
|
|
156
|
+
inputSchema: { snapshotId: z.string(), elementId: z.string(), text: z.string() },
|
|
157
|
+
}, ({ snapshotId, elementId, text: value }) => perform([{ type: "set_value", snapshotId, elementId, text: value }]));
|
|
158
|
+
server.registerTool("mac_click", {
|
|
159
|
+
title: "Клик по координатам",
|
|
160
|
+
description: "Координаты — логические точки экрана, как в ответе mac_screenshot.",
|
|
161
|
+
inputSchema: {
|
|
162
|
+
x: z.number(),
|
|
163
|
+
y: z.number(),
|
|
164
|
+
button: z.enum(["left", "right", "middle"]).default("left"),
|
|
165
|
+
count: z.number().int().min(1).max(3).default(1),
|
|
166
|
+
modifiers: z.array(z.enum(["cmd", "shift", "alt", "ctrl", "fn"])).default([]),
|
|
167
|
+
},
|
|
168
|
+
}, ({ x, y, button, count, modifiers }) => perform([{ type: "click", x, y, button, count, modifiers }]));
|
|
169
|
+
server.registerTool("mac_type", {
|
|
170
|
+
title: "Ввести текст",
|
|
171
|
+
description: "Печатает текст в активное поле. Поддерживает любой язык и эмодзи. " +
|
|
172
|
+
"Печать выполнится, только если активно ожидаемое приложение — по умолчанию " +
|
|
173
|
+
"последнее открытое через mac_open_app. Иначе вернётся ошибка, и текст никуда не уйдёт.",
|
|
174
|
+
inputSchema: {
|
|
175
|
+
text: z.string().max(10_000),
|
|
176
|
+
app: z
|
|
177
|
+
.string()
|
|
178
|
+
.optional()
|
|
179
|
+
.describe("bundle id приложения, в которое печатаем; по умолчанию — последнее открытое"),
|
|
180
|
+
},
|
|
181
|
+
}, ({ text: value, app }) => perform([{ type: "type", text: value }], app ?? expectedApp));
|
|
182
|
+
server.registerTool("mac_key", {
|
|
183
|
+
title: "Нажать клавиши",
|
|
184
|
+
description: 'Сочетание клавиш, например ["cmd","s"] или ["return"]. ' +
|
|
185
|
+
"Как и mac_type, выполнится, только если активно ожидаемое приложение.",
|
|
186
|
+
inputSchema: {
|
|
187
|
+
keys: z.array(z.string()).min(1).max(8),
|
|
188
|
+
app: z
|
|
189
|
+
.string()
|
|
190
|
+
.optional()
|
|
191
|
+
.describe("bundle id приложения, которому адресованы клавиши; по умолчанию — последнее открытое"),
|
|
192
|
+
},
|
|
193
|
+
}, ({ keys, app }) => perform([{ type: "key", keys }], app ?? expectedApp));
|
|
194
|
+
server.registerTool("mac_scroll", {
|
|
195
|
+
title: "Прокрутить",
|
|
196
|
+
description: "Прокрутка в точке. Положительный dy прокручивает вверх.",
|
|
197
|
+
inputSchema: { x: z.number(), y: z.number(), dx: z.number().default(0), dy: z.number().default(0) },
|
|
198
|
+
}, ({ x, y, dx, dy }) => perform([{ type: "scroll", x, y, dx, dy }]));
|
|
199
|
+
server.registerTool("mac_drag", {
|
|
200
|
+
title: "Перетащить",
|
|
201
|
+
inputSchema: {
|
|
202
|
+
fromX: z.number(),
|
|
203
|
+
fromY: z.number(),
|
|
204
|
+
toX: z.number(),
|
|
205
|
+
toY: z.number(),
|
|
206
|
+
durationMs: z.number().int().min(0).max(5000).default(300),
|
|
207
|
+
},
|
|
208
|
+
}, ({ fromX, fromY, toX, toY, durationMs }) => perform([
|
|
209
|
+
{
|
|
210
|
+
type: "drag",
|
|
211
|
+
from: { x: fromX, y: fromY },
|
|
212
|
+
to: { x: toX, y: toY },
|
|
213
|
+
button: "left",
|
|
214
|
+
durationMs,
|
|
215
|
+
},
|
|
216
|
+
]));
|
|
217
|
+
server.registerTool("mac_open_app", {
|
|
218
|
+
title: "Открыть приложение",
|
|
219
|
+
description: "Открывает приложение и дожидается, пока оно станет активным. " +
|
|
220
|
+
"Следующие mac_type и mac_key проверяют, что активно именно оно.",
|
|
221
|
+
inputSchema: { bundleId: z.string().optional(), name: z.string().optional() },
|
|
222
|
+
}, async ({ bundleId, name }) => {
|
|
223
|
+
try {
|
|
224
|
+
const opened = await target.openApp({ bundleId, name });
|
|
225
|
+
expectedApp = opened.bundleId ?? bundleId;
|
|
226
|
+
return text(`Открыто и активно: ${opened.name || opened.bundleId || bundleId || name || ""}`);
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
return fail(error);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
server.registerTool("mac_open_url", {
|
|
233
|
+
title: "Открыть ссылку",
|
|
234
|
+
description: "http и https открываются сразу; другие схемы пользователь подтверждает.",
|
|
235
|
+
inputSchema: { url: z.string().url() },
|
|
236
|
+
}, async ({ url }) => {
|
|
237
|
+
try {
|
|
238
|
+
await target.openUrl(url);
|
|
239
|
+
return text("Открыто");
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
return fail(error);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
/* ── Буфер обмена ───────────────────────────────────────────────────── */
|
|
247
|
+
if (has("clipboard")) {
|
|
248
|
+
server.registerTool("mac_clipboard_get", { title: "Прочитать буфер обмена" }, async () => {
|
|
249
|
+
try {
|
|
250
|
+
const { text: value } = await target.getClipboard();
|
|
251
|
+
return text(value);
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
return fail(error);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
server.registerTool("mac_clipboard_set", { title: "Записать в буфер обмена", inputSchema: { text: z.string() } }, async ({ text: value }) => {
|
|
258
|
+
try {
|
|
259
|
+
await target.setClipboard(value);
|
|
260
|
+
return text("Записано");
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
return fail(error);
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/* ── Терминал ───────────────────────────────────────────────────────── */
|
|
268
|
+
if (has("shell")) {
|
|
269
|
+
server.registerTool("mac_shell", {
|
|
270
|
+
title: "Выполнить команду",
|
|
271
|
+
description: "Команда в zsh на Mac пользователя. " +
|
|
272
|
+
"Пользователь может подтверждать каждую команду вручную — тогда ответ придёт не сразу.",
|
|
273
|
+
inputSchema: {
|
|
274
|
+
command: z.string().min(1),
|
|
275
|
+
cwd: z.string().optional(),
|
|
276
|
+
timeoutMs: z.number().int().min(1000).max(900_000).default(60_000),
|
|
277
|
+
},
|
|
278
|
+
}, async ({ command, cwd, timeoutMs }) => {
|
|
279
|
+
try {
|
|
280
|
+
const result = await target.shell({ command, cwd, timeoutMs });
|
|
281
|
+
if ("status" in result)
|
|
282
|
+
return text(`Команда поставлена в очередь: ${result.commandId}`);
|
|
283
|
+
const parts = [`exit ${result.exitCode}`];
|
|
284
|
+
if (result.stdout)
|
|
285
|
+
parts.push(`stdout:\n${result.stdout}`);
|
|
286
|
+
if (result.stderr)
|
|
287
|
+
parts.push(`stderr:\n${result.stderr}`);
|
|
288
|
+
if (result.timedOut)
|
|
289
|
+
parts.push("(команда прервана по таймауту)");
|
|
290
|
+
return text(parts.join("\n\n"));
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
return fail(error);
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
/* ── Файлы ──────────────────────────────────────────────────────────── */
|
|
298
|
+
if (has("files")) {
|
|
299
|
+
server.registerTool("mac_read_file", {
|
|
300
|
+
title: "Прочитать файл",
|
|
301
|
+
description: "Только внутри папок, которые пользователь разрешил.",
|
|
302
|
+
inputSchema: { path: z.string().min(1) },
|
|
303
|
+
}, async ({ path }) => {
|
|
304
|
+
try {
|
|
305
|
+
const file = await target.readFile(path);
|
|
306
|
+
return text(Buffer.from(file.data, "base64").toString("utf8"));
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
return fail(error);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dyrra/mcp",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "MCP-сервер Dyrra: доступ ИИ-агента к Mac",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"dyrra-mcp": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@modelcontextprotocol/sdk": "1.30.0",
|
|
12
|
+
"zod": "4.6.2",
|
|
13
|
+
"@dyrra/sdk": "0.1.1",
|
|
14
|
+
"@dyrra/protocol": "0.1.1"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/node": "24.10.1"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/ceodaredevil/dyrra.git",
|
|
23
|
+
"directory": "packages/mcp"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/ceodaredevil/dyrra",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/ceodaredevil/dyrra/issues"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"keywords": [
|
|
36
|
+
"mac",
|
|
37
|
+
"macos",
|
|
38
|
+
"ai-agent",
|
|
39
|
+
"computer-use",
|
|
40
|
+
"mcp",
|
|
41
|
+
"automation"
|
|
42
|
+
],
|
|
43
|
+
"types": "./dist/index.d.ts",
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc -p tsconfig.build.json",
|
|
46
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
47
|
+
"lint": "oxlint src",
|
|
48
|
+
"test": "vitest run --passWithNoTests",
|
|
49
|
+
"start": "node dist/index.js"
|
|
50
|
+
}
|
|
51
|
+
}
|