@smwb/onreel-git-mcp 0.5.0 → 0.7.0

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 CHANGED
@@ -609,12 +609,52 @@ await serveMcp({
609
609
  });
610
610
  ```
611
611
 
612
- Сервер отвечает `serverInfo` с `name: 'onreel'` и версией контракта host; согласовывает любую из
612
+ Сервер отвечает `serverInfo` с `name: 'onreel'` и версией: `serverVersion` вызывающего — например, версия его
613
+ CLI, — а без неё `formatVersion(HOST_CONTRACT_VERSION)`, версия контракта host. Согласовывает любую из
613
614
  `MCP_PROTOCOL_VERSIONS` (`2025-11-25` … `2024-11-05`) и отдаёт `structuredContent` от `2025-06-18`. Прочее:
614
615
  `notifications/progress` каждые `MCP_PROGRESS_INTERVAL_MS` (15 с), если клиент прислал `progressToken`; строка
615
616
  длиннее `MCP_MAX_LINE_BYTES` (8 МиБ) отбрасывается с ошибкой парсинга; после конца stdin начатые вызовы живут
616
617
  `MCP_EOF_GRACE_MS` (5 с).
617
618
 
619
+ **Своя строка таблицы.** `serveMcp`, `McpServerOptions` и `CommandExecutor` обобщены по типу строки таблицы
620
+ `S extends CommandSpec`, поэтому потребитель передаёт свою таблицу и своего исполнителя напрямую — без адаптера,
621
+ который обогащал бы строки полем `mutation` и искал строку потребителя по пути. Исполнитель получает тот же объект
622
+ строки, что лежит в `specs`, вместе с его собственными полями; `mcpToolSpecs` тип строки сохраняет. Без аргумента
623
+ типа `S` остаётся `CommandSpec`, так что прежние вызовы не меняются.
624
+
625
+ `readOnlyHint` инструмента по умолчанию считается из строки: команда без глагола контракта — только чтение,
626
+ у глагола признак берётся из `spec.mutation`. Когда признак живёт не в строке, а в реестре глаголов потребителя,
627
+ его подставляет необязательный хук `readOnly?: (spec: S) => boolean` — он же третий параметр `toolOf`.
628
+
629
+ ```ts
630
+ import { mcpToolSpecs, serveMcp, type CommandExecutor, type CommandSpec } from '@smwb/onreel-git-mcp/mcp';
631
+
632
+ // Строка таблицы onreel шире библиотечной: verb обязателен, признака мутации в строке нет вовсе.
633
+ type HostSpec = CommandSpec & { verb: string; preamble: string };
634
+
635
+ const hostVerbs: Readonly<Record<string, { mutation: boolean }>> = {
636
+ 'run.list': { mutation: false },
637
+ 'task.create': { mutation: true },
638
+ };
639
+ const hostTable: readonly HostSpec[] = [
640
+ /* строки своей таблицы */
641
+ ];
642
+
643
+ const execute: CommandExecutor<HostSpec> = async (spec, values, globals) => ({
644
+ result: { command: spec.path.join(' '), preamble: spec.preamble, values }, // своё поле строки читается без приведения типа
645
+ requestId: globals.requestId,
646
+ });
647
+
648
+ await serveMcp<HostSpec>({
649
+ specs: mcpToolSpecs(hostTable),
650
+ execute,
651
+ readOnly: (spec) => hostVerbs[spec.verb]?.mutation !== true, // readOnlyHint — из реестра глаголов
652
+ globals: { json: false, help: false },
653
+ io,
654
+ input: process.stdin,
655
+ });
656
+ ```
657
+
618
658
  **Принципал** (от чьего имени работает сервер) выбирают один раз при запуске: env агента
619
659
  (`ONREEL_HOST_URL` + `ONREEL_TOKEN`) — агент; явный `--data-dir` — владелец; иначе владелец по `host.json`,
620
660
  каталог для которого даёт `DiscoveryProvider` — библиотека не знает ни имени переменной, ни домашнего каталога CLI
package/dist/index.js CHANGED
@@ -59,7 +59,7 @@ import {
59
59
  // package.json
60
60
  var package_default = {
61
61
  name: "@smwb/onreel-git-mcp",
62
- version: "0.5.0",
62
+ version: "0.7.0",
63
63
  description: "\u0411\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430 \u043C\u043E\u0434\u0443\u043B\u0435\u0439, \u0432\u044B\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0445 \u0438\u0437 onreel: git-\u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0435 \u043F\u0443\u0442\u0438, \u0441\u043F\u0438\u0441\u043E\u043A \u0444\u0430\u0439\u043B\u043E\u0432 worktree, \u0436\u0438\u0437\u043D\u0435\u043D\u043D\u044B\u0439 \u0446\u0438\u043A\u043B worktree \u043F\u0440\u043E\u0442\u0438\u0432 \u043F\u043E\u0440\u0442\u0430 WorktreeStore, \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u044B \u0442\u0440\u0435\u043A\u0435\u0440\u043E\u0432 GitHub/GitLab/Jira/SourceCraft/\u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0438 MCP-\u0441\u0435\u0440\u0432\u0435\u0440 \u043D\u0430 stdio",
64
64
  keywords: [
65
65
  "git",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@smwb/onreel-git-mcp\",\n \"version\": \"0.5.0\",\n \"description\": \"Библиотека модулей, выделенных из onreel: git-операции и безопасные пути, список файлов worktree, жизненный цикл worktree против порта WorktreeStore, адаптеры трекеров GitHub/GitLab/Jira/SourceCraft/локального и MCP-сервер на stdio\",\n \"keywords\": [\n \"git\",\n \"worktree\",\n \"mcp\",\n \"issue-tracker\",\n \"github\",\n \"gitlab\",\n \"jira\",\n \"sourcecraft\",\n \"onreel\",\n \"typescript\"\n ],\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=24\"\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://git.sourcecraft.dev/elfenmail/onreel-git-mcp.git\"\n },\n \"homepage\": \"https://git.sourcecraft.dev/elfenmail/onreel-git-mcp\",\n \"license\": \"MIT\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./git\": {\n \"types\": \"./dist/git/index.d.ts\",\n \"import\": \"./dist/git/index.js\",\n \"default\": \"./dist/git/index.js\"\n },\n \"./files\": {\n \"types\": \"./dist/files/index.d.ts\",\n \"import\": \"./dist/files/index.js\",\n \"default\": \"./dist/files/index.js\"\n },\n \"./worktree\": {\n \"types\": \"./dist/worktree/index.d.ts\",\n \"import\": \"./dist/worktree/index.js\",\n \"default\": \"./dist/worktree/index.js\"\n },\n \"./tracker\": {\n \"types\": \"./dist/tracker/index.d.ts\",\n \"import\": \"./dist/tracker/index.js\",\n \"default\": \"./dist/tracker/index.js\"\n },\n \"./mcp\": {\n \"types\": \"./dist/mcp/index.d.ts\",\n \"import\": \"./dist/mcp/index.js\",\n \"default\": \"./dist/mcp/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"build\": \"tsup && tsc -p tsconfig.build.json\",\n \"typecheck\": \"tsc -p tsconfig.json && tsc -p tsconfig.examples.json\",\n \"lint\": \"oxlint --type-aware\",\n \"test\": \"node --test \\\"test/**/*.test.ts\\\"\",\n \"changeset\": \"changeset\",\n \"version\": \"changeset version\",\n \"release\": \"npm run build && changeset publish\"\n },\n \"dependencies\": {\n \"zod\": \"^4.6.5\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"2.29.2\",\n \"@types/node\": \"24.19.1\",\n \"oxlint\": \"1.87.0\",\n \"oxlint-tsgolint\": \"7.0.2003\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"7.0.2\"\n }\n}\n","// Корневой подпуть пакета @smwb/onreel-git-mcp: срез контракта (константы, схемы, типы, чистые\n// функции) и версия пакета. Всё без побочных эффектов при импорте (R-001). Швы ядра\n// (SecretSink, WorktreeStore, LocalIssueStore) и модули git/files/worktree/tracker/mcp\n// экспортируют свои подпути — см. exports в package.json и README.\nimport pkg from '../package.json' with { type: 'json' };\n\nexport * from './contract/contract.const.ts';\nexport * from './contract/contract.schema.ts';\nexport * from './contract/contract.types.ts';\nexport * from './contract/contract.lib.ts';\n\n// Версия пакета — из version в package.json: статический импорт JSON, его значение tsup подставляет\n// в бандл на сборке, поэтому VERSION не расходится с релизом changesets (тот правит только version).\nexport const VERSION: string = pkg.version;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,UAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,MAAQ;AAAA,EACR,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,OAAS;AAAA,IACP;AAAA,EACF;AAAA,EACA,aAAe;AAAA,EACf,eAAiB;AAAA,IACf,QAAU;AAAA,IACV,UAAY;AAAA,EACd;AAAA,EACA,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,EACT;AAAA,EACA,UAAY;AAAA,EACZ,SAAW;AAAA,EACX,SAAW;AAAA,IACT,KAAK;AAAA,MACH,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,WAAW;AAAA,MACT,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,cAAc;AAAA,MACZ,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,aAAa;AAAA,MACX,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,kBAAkB;AAAA,EACpB;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,WAAa;AAAA,IACb,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,WAAa;AAAA,IACb,SAAW;AAAA,IACX,SAAW;AAAA,EACb;AAAA,EACA,cAAgB;AAAA,IACd,KAAO;AAAA,EACT;AAAA,EACA,iBAAmB;AAAA,IACjB,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,QAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,MAAQ;AAAA,IACR,YAAc;AAAA,EAChB;AACF;;;AC1EO,IAAM,UAAkB,gBAAI;","names":[]}
1
+ {"version":3,"sources":["../package.json","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@smwb/onreel-git-mcp\",\n \"version\": \"0.7.0\",\n \"description\": \"Библиотека модулей, выделенных из onreel: git-операции и безопасные пути, список файлов worktree, жизненный цикл worktree против порта WorktreeStore, адаптеры трекеров GitHub/GitLab/Jira/SourceCraft/локального и MCP-сервер на stdio\",\n \"keywords\": [\n \"git\",\n \"worktree\",\n \"mcp\",\n \"issue-tracker\",\n \"github\",\n \"gitlab\",\n \"jira\",\n \"sourcecraft\",\n \"onreel\",\n \"typescript\"\n ],\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=24\"\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://git.sourcecraft.dev/elfenmail/onreel-git-mcp.git\"\n },\n \"homepage\": \"https://git.sourcecraft.dev/elfenmail/onreel-git-mcp\",\n \"license\": \"MIT\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./git\": {\n \"types\": \"./dist/git/index.d.ts\",\n \"import\": \"./dist/git/index.js\",\n \"default\": \"./dist/git/index.js\"\n },\n \"./files\": {\n \"types\": \"./dist/files/index.d.ts\",\n \"import\": \"./dist/files/index.js\",\n \"default\": \"./dist/files/index.js\"\n },\n \"./worktree\": {\n \"types\": \"./dist/worktree/index.d.ts\",\n \"import\": \"./dist/worktree/index.js\",\n \"default\": \"./dist/worktree/index.js\"\n },\n \"./tracker\": {\n \"types\": \"./dist/tracker/index.d.ts\",\n \"import\": \"./dist/tracker/index.js\",\n \"default\": \"./dist/tracker/index.js\"\n },\n \"./mcp\": {\n \"types\": \"./dist/mcp/index.d.ts\",\n \"import\": \"./dist/mcp/index.js\",\n \"default\": \"./dist/mcp/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"build\": \"tsup && tsc -p tsconfig.build.json\",\n \"typecheck\": \"tsc -p tsconfig.json && tsc -p tsconfig.examples.json\",\n \"lint\": \"oxlint --type-aware\",\n \"test\": \"node --test \\\"test/**/*.test.ts\\\"\",\n \"changeset\": \"changeset\",\n \"version\": \"changeset version\",\n \"release\": \"npm run build && changeset publish\"\n },\n \"dependencies\": {\n \"zod\": \"^4.6.5\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"2.29.2\",\n \"@types/node\": \"24.19.1\",\n \"oxlint\": \"1.87.0\",\n \"oxlint-tsgolint\": \"7.0.2003\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"7.0.2\"\n }\n}\n","// Корневой подпуть пакета @smwb/onreel-git-mcp: срез контракта (константы, схемы, типы, чистые\n// функции) и версия пакета. Всё без побочных эффектов при импорте (R-001). Швы ядра\n// (SecretSink, WorktreeStore, LocalIssueStore) и модули git/files/worktree/tracker/mcp\n// экспортируют свои подпути — см. exports в package.json и README.\nimport pkg from '../package.json' with { type: 'json' };\n\nexport * from './contract/contract.const.ts';\nexport * from './contract/contract.schema.ts';\nexport * from './contract/contract.types.ts';\nexport * from './contract/contract.lib.ts';\n\n// Версия пакета — из version в package.json: статический импорт JSON, его значение tsup подставляет\n// в бандл на сборке, поэтому VERSION не расходится с релизом changesets (тот правит только version).\nexport const VERSION: string = pkg.version;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACE,MAAQ;AAAA,EACR,SAAW;AAAA,EACX,aAAe;AAAA,EACf,UAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,MAAQ;AAAA,EACR,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,OAAS;AAAA,IACP;AAAA,EACF;AAAA,EACA,aAAe;AAAA,EACf,eAAiB;AAAA,IACf,QAAU;AAAA,IACV,UAAY;AAAA,EACd;AAAA,EACA,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,EACT;AAAA,EACA,UAAY;AAAA,EACZ,SAAW;AAAA,EACX,SAAW;AAAA,IACT,KAAK;AAAA,MACH,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,WAAW;AAAA,MACT,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,cAAc;AAAA,MACZ,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,aAAa;AAAA,MACX,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,SAAS;AAAA,MACP,OAAS;AAAA,MACT,QAAU;AAAA,MACV,SAAW;AAAA,IACb;AAAA,IACA,kBAAkB;AAAA,EACpB;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,WAAa;AAAA,IACb,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,WAAa;AAAA,IACb,SAAW;AAAA,IACX,SAAW;AAAA,EACb;AAAA,EACA,cAAgB;AAAA,IACd,KAAO;AAAA,EACT;AAAA,EACA,iBAAmB;AAAA,IACjB,mBAAmB;AAAA,IACnB,eAAe;AAAA,IACf,QAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,MAAQ;AAAA,IACR,YAAc;AAAA,EAChB;AACF;;;AC1EO,IAAM,UAAkB,gBAAI;","names":[]}
package/dist/mcp/index.js CHANGED
@@ -391,6 +391,9 @@ function toolName(spec) {
391
391
  function mcpToolSpecs(specs) {
392
392
  return specs.filter((spec) => spec.handler !== "mcp");
393
393
  }
394
+ function readOnlyOf(spec) {
395
+ return spec.verb === void 0 ? true : spec.mutation !== true;
396
+ }
394
397
  function typeOf(flag) {
395
398
  switch (flag.parse) {
396
399
  case "int":
@@ -432,7 +435,7 @@ function inputSchemaOf(spec, env) {
432
435
  };
433
436
  return { type: "object", properties, required: requiredFlagNames(spec, env), additionalProperties: false };
434
437
  }
435
- function toolOf(spec, env) {
438
+ function toolOf(spec, env, readOnly) {
436
439
  const command = spec.path.join(" ");
437
440
  const summary = spec.summary.replace(/\.$/, "");
438
441
  const description = `${summary}. \u0422\u043E \u0436\u0435, \u0447\u0442\u043E onreel ${command}.` + (spec.rule === void 0 ? "" : ` \u041F\u0440\u0430\u0432\u0438\u043B\u043E: ${spec.rule}`) + (spec.verb === void 0 ? "" : ` \u0413\u043B\u0430\u0433\u043E\u043B \u043A\u043E\u043D\u0442\u0440\u0430\u043A\u0442\u0430: ${spec.verb}.`);
@@ -441,7 +444,7 @@ function toolOf(spec, env) {
441
444
  title: `onreel ${command}`,
442
445
  description,
443
446
  inputSchema: inputSchemaOf(spec, env),
444
- annotations: { readOnlyHint: spec.verb === void 0 ? true : spec.mutation !== true, openWorldHint: false }
447
+ annotations: { readOnlyHint: readOnly === void 0 ? readOnlyOf(spec) : readOnly(spec), openWorldHint: false }
445
448
  };
446
449
  }
447
450
  function toolResult(output, structured) {
@@ -530,7 +533,7 @@ function negotiate(requested) {
530
533
  return MCP_PROTOCOL_VERSIONS.includes(requested) ? requested : MCP_PROTOCOL_VERSIONS[0];
531
534
  }
532
535
  function serveMcp(options) {
533
- const { execute, io } = options;
536
+ const { execute, io, readOnly } = options;
534
537
  const specs = mcpToolSpecs(options.specs);
535
538
  const byName = new Map(specs.map((spec) => [toolName(spec), spec]));
536
539
  const progressIntervalMs = options.progressIntervalMs ?? MCP_PROGRESS_INTERVAL_MS;
@@ -592,7 +595,11 @@ function serveMcp(options) {
592
595
  result: {
593
596
  protocolVersion,
594
597
  capabilities: { tools: { listChanged: false } },
595
- serverInfo: { name: MCP_SERVER_NAME, title: MCP_SERVER_TITLE, version: formatVersion(HOST_CONTRACT_VERSION) },
598
+ serverInfo: {
599
+ name: MCP_SERVER_NAME,
600
+ title: MCP_SERVER_TITLE,
601
+ version: options.serverVersion ?? formatVersion(HOST_CONTRACT_VERSION)
602
+ },
596
603
  instructions
597
604
  }
598
605
  });
@@ -602,7 +609,7 @@ function serveMcp(options) {
602
609
  send({ id, result: {} });
603
610
  return;
604
611
  case "tools/list":
605
- send({ id, result: { tools: specs.map((spec) => toolOf(spec, io.env)) } });
612
+ send({ id, result: { tools: specs.map((spec) => toolOf(spec, io.env, readOnly)) } });
606
613
  return;
607
614
  case "tools/call": {
608
615
  const parsed = toolsCallParamsSchema.safeParse(params);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/mcp.const.ts","../../src/mcp/mcp.schema.ts","../../src/mcp/args.lib.ts","../../src/mcp/envelope.lib.ts","../../src/mcp/principal.lib.ts","../../src/mcp/tools.lib.ts","../../src/mcp/server.lib.ts"],"sourcesContent":["// Константы сервера MCP: версии протокола, имя сервера, коды ошибок JSON-RPC 2.0 и инструкция\n// для модели. Протокол — подмножество MCP на stdio: initialize, ping, tools/list, tools/call.\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d, src/cli/mcp/mcp.const.ts; дословная копия,\n// кроме импорта CLI-инфраструктуры onreel: имя аргумента идемпотности (REQUEST_ID_FLAG из args.const.ts) и шаблон\n// длительности (DURATION_PATTERN оттуда же) объявлены здесь своими константами — в библиотеку args.const.ts не входит.\n\n/** Поддерживаемые версии протокола MCP (D-286); первая — последняя: ею отвечаем на незнакомую версию клиента. */\nexport const MCP_PROTOCOL_VERSIONS = ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'] as const;\n\n/** С этой версии результат инструмента несёт structuredContent. */\nexport const MCP_STRUCTURED_SINCE = '2025-06-18';\n\nexport const MCP_SERVER_NAME = 'onreel';\nexport const MCP_SERVER_TITLE = 'onreel orch';\n\n/** Пауза между notifications/progress долгого вызова с progressToken (D-284). */\nexport const MCP_PROGRESS_INTERVAL_MS = 15_000;\n\n/** Предел длины строки JSON-RPC (D-288): длиннее — ошибка -32600, строка отбрасывается до перевода строки. */\nexport const MCP_MAX_LINE_BYTES = 8 * 1024 * 1024;\n\n/** Сколько начатые вызовы могут дописывать ответ после конца stdin, прежде чем их прервут (D-287). */\nexport const MCP_EOF_GRACE_MS = 5_000;\n\n/** Аргумент инструмента с ключом идемпотентности — флаг --request-id CLI. */\nexport const MCP_REQUEST_ID_ARGUMENT = 'request-id';\n\n/** Длительность `<n>ms|s|m|h`, голое число — миллисекунды; значение флага parse: 'duration'. */\nexport const DURATION_PATTERN = /^\\s*(\\d+)(ms|s|m|h)?\\s*$/;\n\nexport const JSONRPC_PARSE_ERROR = -32700;\nexport const JSONRPC_INVALID_REQUEST = -32600;\nexport const JSONRPC_METHOD_NOT_FOUND = -32601;\nexport const JSONRPC_INVALID_PARAMS = -32602;\nexport const JSONRPC_INTERNAL_ERROR = -32603;\n\n/** Инструкция сервера модели (ответ initialize). */\nexport const MCP_INSTRUCTIONS =\n 'Инструменты onreel — те же команды, что `onreel orch …`, с теми же правами. Имя инструмента — путь команды через `_` ' +\n '(orch_task_create — это onreel orch task create), аргументы — флаги команды без `--`; request-id — ключ идемпотентности: ' +\n 'повтор с тем же значением вернёт результат первого выполнения. Результат — конверт как у `--json`: ' +\n '{ok: true, requestId, duplicate, result} или {ok: false, requestId, error: {code, message, nextSteps}}; ' +\n 'флаг `--x` в nextSteps — это аргумент x. Истёкшее ожидание orch_check и orch_ask — не ошибка (timedOut, answered: false): ' +\n 'повторите вызов; держите timeout короче таймаута вызова у клиента (например, 5m). Права — у токена, с которым запущен ' +\n 'сервер: владелец из host.json или агент из переменных ONREEL_*.';\n","import { z } from 'zod';\nimport { contractErrorSchema, requestIdSchema } from '../contract/contract.schema.ts';\n\n// Сообщения JSON-RPC 2.0 и параметры методов MCP, которые читает сервер. Параметры не строгие: поля новых версий\n// протокола не ломают разбор. Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d,\n// src/cli/mcp/mcp.schema.ts (дословно) + src/cli/output.schema.ts: конверт результата вызова добавлен сюда,\n// потому что output.schema.ts — CLI-инфраструктура onreel, а форма результата входит в контракт сервера MCP.\n\nexport const jsonRpcIdSchema = z.union([z.string(), z.number().int()]);\n\n/** Любое сообщение JSON-RPC: запрос (id и method), уведомление (только method) или ответ (result или error). */\nexport const jsonRpcMessageSchema = z.object({\n jsonrpc: z.literal('2.0'),\n id: jsonRpcIdSchema.nullable().optional(),\n method: z.string().optional(),\n params: z.unknown().optional(),\n result: z.unknown().optional(),\n error: z.unknown().optional(),\n});\n\nexport const initializeParamsSchema = z\n .object({ protocolVersion: z.string(), capabilities: z.unknown().optional(), clientInfo: z.unknown().optional() })\n .loose();\n\nexport const toolsCallParamsSchema = z\n .object({\n name: z.string().min(1),\n arguments: z.unknown().optional(),\n _meta: z.object({ progressToken: z.union([z.string(), z.number()]).optional() }).loose().optional(),\n })\n .loose();\n\nexport const cancelledParamsSchema = z.object({ requestId: jsonRpcIdSchema, reason: z.string().optional() }).loose();\n\n// Конверт результата команды (D-052): одна строка JSON в content, и им же structuredContent на новых версиях\n// протокола. requestId нет у локальных команд, и он равен null у локальных ошибок.\n\nexport const cliSuccessSchema = z.object({\n ok: z.literal(true),\n requestId: requestIdSchema.optional(),\n duplicate: z.boolean().optional(),\n result: z.unknown(),\n});\n\nexport const cliFailureSchema = z.object({\n ok: z.literal(false),\n requestId: requestIdSchema.nullable(),\n error: contractErrorSchema,\n});\n\nexport const cliOutputSchema = z.discriminatedUnion('ok', [cliSuccessSchema, cliFailureSchema]);\n\nexport type JsonRpcId = z.infer<typeof jsonRpcIdSchema>;\nexport type JsonRpcMessage = z.infer<typeof jsonRpcMessageSchema>;\nexport type InitializeParams = z.infer<typeof initializeParamsSchema>;\nexport type ToolsCallParams = z.infer<typeof toolsCallParamsSchema>;\nexport type CancelledParams = z.infer<typeof cancelledParamsSchema>;\nexport type CliOutput = z.infer<typeof cliOutputSchema>;\n","import { resolve } from 'node:path';\nimport { requestIdSchema } from '../contract/contract.schema.ts';\nimport { DURATION_PATTERN, MCP_REQUEST_ID_ARGUMENT } from './mcp.const.ts';\nimport { usageError } from './envelope.lib.ts';\nimport type { CommandSpec, FlagSpec } from './mcp.types.ts';\n\n// Разбор аргументов вызова инструмента: объект JSON `{\"флаг\": значение}` → значения флагов команды. Минимальная\n// копия той части src/cli/args.lib.ts onreel (@ b73407be076a5df73931d1340f70910ca13c908d), которая нужна серверу MCP:\n// хвост разбора (явные значения, env, default, конфликт полей тела, проверка обязательных) и разбор значений по\n// типу флага. Разбор argv (parseInvocation, ведущие позиционные, глобальные флаги) остаётся в CLI потребителя —\n// в библиотеке его нет, поэтому и ошибка всегда invalid_request с шагами как у CLI.\n\nconst durationUnits: Record<string, number> = { ms: 1, s: 1000, m: 60_000, h: 3_600_000 };\n\n/** Длительность `<n>ms|s|m|h`, голое число — миллисекунды; неверная запись — undefined. */\nexport function parseDuration(text: string): number | undefined {\n const match = DURATION_PATTERN.exec(text);\n if (match === null) return undefined;\n const value = Number(match[1]) * (durationUnits[match[2] ?? 'ms'] ?? 1);\n return Number.isSafeInteger(value) ? value : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction helpStep(path: readonly string[]): string {\n return `Справка: onreel ${[...path, '--help'].join(' ')}`;\n}\n\nfunction applyTemplate(template: string | undefined, value: unknown): unknown {\n return template === undefined || typeof value !== 'string' ? value : template.replaceAll('{value}', value);\n}\n\nfunction valueError(flag: FlagSpec, what: string, path: readonly string[]): Error {\n return usageError(`Неверное значение --${flag.name}: ${what}.`, [`Значение --${flag.name}: ${flag.help}`, helpStep(path)], {\n flag: flag.name,\n });\n}\n\n/** Значение одной строки флага по его типу разбора. */\nfunction parseOne(flag: FlagSpec, text: string, cwd: string, path: readonly string[]): unknown {\n const fail = (what: string): never => {\n throw valueError(flag, what, path);\n };\n switch (flag.parse) {\n case 'string':\n return text;\n case 'boolean':\n return text === 'true' || text === '1';\n case 'int': {\n const value = /^-?\\d+$/.test(text.trim()) ? Number(text) : Number.NaN;\n return Number.isSafeInteger(value) ? value : fail(`ожидается целое число, получено «${text}»`);\n }\n case 'csv':\n return text\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part !== '');\n case 'json':\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return fail('ожидается JSON');\n }\n case 'duration':\n return parseDuration(text) ?? fail(`ожидается длительность вида 30s, 5m, 1h или число миллисекунд, получено «${text}»`);\n case 'path':\n return text === '' ? fail('пустой путь') : resolve(cwd, text);\n }\n}\n\n/** Что ожидается в JSON-значении флага: текст ошибки неверного типа. */\nfunction expectedOf(flag: FlagSpec): string {\n switch (flag.parse) {\n case 'int':\n return 'ожидается целое число';\n case 'boolean':\n return 'ожидается true или false';\n case 'csv':\n return 'ожидается массив строк или строка через запятую';\n case 'duration':\n return 'ожидается длительность строкой (30s, 5m, 1h) или неотрицательное целое число миллисекунд';\n case 'json':\n return 'ожидается JSON';\n default:\n return 'ожидается строка';\n }\n}\n\nfunction typeError(flag: FlagSpec, path: readonly string[]): never {\n throw valueError(flag, expectedOf(flag), path);\n}\n\n/**\n * Одно JSON-значение флага (элемент массива у повторяемого флага): строки разбирает тот же parseOne, что argv,\n * числа и логические значения принимаются по типу флага. Шаблон флага применяется как в CLI.\n */\nfunction jsonScalar(flag: FlagSpec, value: unknown, cwd: string, path: readonly string[]): unknown {\n let parsed: unknown;\n if (typeof value === 'string' && flag.parse !== 'boolean') parsed = parseOne(flag, value, cwd, path);\n else if (flag.parse === 'boolean' && value === true) parsed = true;\n else if (flag.parse === 'int' && Number.isSafeInteger(value)) parsed = value;\n else if (flag.parse === 'duration' && Number.isSafeInteger(value) && (value as number) >= 0) parsed = value;\n else if (flag.parse === 'json' && typeof value !== 'string') parsed = value;\n else if (flag.parse === 'csv' && Array.isArray(value)) {\n // Элементы массива — как значения через запятую в argv: каждый разбирается тем же csv.\n parsed = value.map((item) => (typeof item === 'string' ? parseOne(flag, item, cwd, path) : typeError(flag, path))).flat();\n } else return typeError(flag, path);\n return applyTemplate(flag.template, parsed);\n}\n\n/** Значение флага из аргументов MCP; undefined — флага нет (null и false у переключателя — как отсутствие флага в argv). */\nfunction jsonFlagValue(flag: FlagSpec, value: unknown, cwd: string, path: readonly string[]): (() => unknown) | undefined {\n if (value === undefined || value === null || (flag.parse === 'boolean' && value === false)) return undefined;\n if (flag.multiple !== true || flag.parse === 'csv') return () => jsonScalar(flag, value, cwd, path);\n const items = Array.isArray(value) ? value : [value];\n if (items.length === 0) return undefined;\n return () => items.map((item) => jsonScalar(flag, item, cwd, path));\n}\n\n/** Ключ поля тела, в которое пишет флаг; флаг без field читает обработчик — ключ по имени флага. */\nfunction targetOf(flag: FlagSpec): string {\n return flag.field === undefined ? `flag:${flag.name}` : `field:${flag.field}`;\n}\n\n/** Флаг заполняется без явного значения: непустая переменная env или default. */\nfunction implicitlyFilled(flag: FlagSpec, env: NodeJS.ProcessEnv): boolean {\n const fromEnv = flag.env === undefined ? undefined : env[flag.env];\n return (fromEnv !== undefined && fromEnv !== '') || flag.default !== undefined;\n}\n\n/**\n * Флаги, без которых вызов не пройдёт проверку обязательных: required, и поле флага не заполнит ни env, ни default\n * (его или другого флага того же поля), ни другой флаг того же поля, заданный явно. Это обязательные свойства\n * входной схемы инструмента MCP.\n */\nexport function requiredFlagNames(spec: CommandSpec, env: NodeJS.ProcessEnv): string[] {\n return spec.flags\n .filter((flag) => {\n if (flag.required !== true) return false;\n const target = targetOf(flag);\n return !spec.flags.some((other) => targetOf(other) === target && (other !== flag || implicitlyFilled(other, env)));\n })\n .map((flag) => flag.name);\n}\n\n/** Явный флаг вызова и разбор его значения; разбор ленивый — ошибки идут в том же порядке, что флаги таблицы. */\ntype ExplicitFlag = readonly [FlagSpec, () => unknown];\n\n/**\n * Общий хвост разбора: явные значения (два флага с одним полем тела — ошибка), затем env и default,\n * затем проверка обязательных флагов.\n */\nfunction resolveFlagValues(spec: CommandSpec, explicit: readonly ExplicitFlag[], env: NodeJS.ProcessEnv, cwd: string): Record<string, unknown> {\n // Явные флаги: два флага с одним полем тела — ошибка.\n const values: Record<string, unknown> = {};\n const writers = new Map<string, string>();\n for (const [flag, parse] of explicit) {\n values[flag.name] = parse();\n const target = targetOf(flag);\n const other = writers.get(target);\n if (other !== undefined) {\n const what = flag.field === undefined ? 'одно и то же значение' : `одно и то же поле ${flag.field}`;\n throw usageError(`Флаги --${other} и --${flag.name} задают ${what}.`, [`Оставьте один из флагов: --${other} или --${flag.name}.`]);\n }\n writers.set(target, flag.name);\n }\n\n // env и default заполняют только поля, которые не задал явный флаг.\n for (const flag of spec.flags) {\n if (values[flag.name] !== undefined || writers.has(targetOf(flag))) continue;\n const fromEnv = flag.env === undefined ? undefined : env[flag.env];\n let value: unknown;\n if (fromEnv !== undefined && fromEnv !== '') value = applyTemplate(flag.envTemplate, parseOne(flag, fromEnv, cwd, spec.path));\n else if (flag.default !== undefined) value = flag.default;\n if (value === undefined) continue;\n values[flag.name] = value;\n writers.set(targetOf(flag), flag.name);\n }\n\n for (const flag of spec.flags) {\n if (flag.required !== true || writers.has(targetOf(flag))) continue;\n const steps: [string, ...string[]] = [`Добавьте --${flag.name} ${flag.placeholder ?? '<значение>'}: ${flag.help}`];\n if (flag.env !== undefined) steps.push(`Или задайте переменную ${flag.env}.`);\n steps.push(helpStep(spec.path));\n throw usageError(`Не задан обязательный флаг --${flag.name} команды onreel ${spec.path.join(' ')}.`, steps, { flag: flag.name });\n }\n return values;\n}\n\n/** Ошибка неверного request-id: тот же текст, что у флага --request-id в CLI. */\nfunction requestIdError(value: string): Error {\n return usageError(`Неверный --request-id: ${value}.`, [\n 'requestId — до 128 символов: латиница, цифры и . _ : -, первый символ — буква или цифра.',\n ]);\n}\n\n/**\n * Аргументы вызова инструмента MCP (объект JSON) → значения флагов команды: тот же разбор, шаблоны, env,\n * default, конфликт полей и проверка обязательных, что у argv. Ошибка — invalid_request (origin local).\n */\nexport function resolveJsonArguments(\n spec: CommandSpec,\n input: unknown,\n env: NodeJS.ProcessEnv,\n cwd: string,\n): { values: Readonly<Record<string, unknown>>; requestId?: string } {\n const command = `onreel ${spec.path.join(' ')}`;\n const args = input === undefined || input === null ? {} : input;\n if (!isRecord(args)) {\n throw usageError(`Неверные аргументы ${command}: ожидается объект JSON {\"флаг\": значение}.`, [helpStep(spec.path)]);\n }\n const byName = new Map(spec.flags.map((flag) => [flag.name, flag]));\n let requestId: string | undefined;\n for (const [key, value] of Object.entries(args)) {\n if (key === MCP_REQUEST_ID_ARGUMENT) {\n if (value === undefined || value === null) continue;\n if (typeof value !== 'string' || !requestIdSchema.safeParse(value).success) {\n throw requestIdError(typeof value === 'string' ? value : JSON.stringify(value));\n }\n requestId = value;\n } else if (!byName.has(key)) {\n const known = [...byName.keys(), MCP_REQUEST_ID_ARGUMENT].join(', ');\n const steps: [string, ...string[]] =\n key === 'data-dir'\n ? ['Каталог данных host задаётся при запуске сервера: onreel orch mcp --data-dir <каталог>.']\n : [`Аргументы ${command}: ${known}.`, helpStep(spec.path)];\n throw usageError(`Неизвестный аргумент ${key} команды ${command}.`, steps, { argument: key });\n }\n }\n\n // Явные значения — в порядке флагов таблицы, как у argv.\n const explicit: ExplicitFlag[] = [];\n for (const flag of spec.flags) {\n const parse = jsonFlagValue(flag, args[flag.name], cwd, spec.path);\n if (parse !== undefined) explicit.push([flag, parse]);\n }\n const values = resolveFlagValues(spec, explicit, env, cwd);\n return requestId === undefined ? { values } : { values, requestId };\n}\n","import { contractError } from '../contract/contract.lib.ts';\nimport type { ContractError } from '../contract/contract.types.ts';\nimport { redactSecretText } from '../kernel/redact.lib.ts';\nimport type { CliOutput } from './mcp.schema.ts';\nimport type { CommandFailure, CommandOutcome } from './mcp.types.ts';\n\n// Ошибка вызова команды и конверт её результата. Это минимальные копии того, что в onreel живёт в CLI-инфраструктуре\n// (src/cli/errors.lib.ts и src/cli/output.lib.ts @ b73407be076a5df73931d1340f70910ca13c908d): библиотека не имеет\n// права их импортировать, а серверу MCP они нужны, чтобы отдавать клиенту ровно тот же конверт `--json`, что и CLI.\n// Отличие от onreel: отказ исполнителя распознаётся структурно (isCommandFailure), а не через instanceof —\n// исполнитель принадлежит потребителю и бросает свой класс ошибки, и её код должен дойти до клиента неизменным.\n\n/** Ошибка вызова команды: контрактная ошибка, происхождение и requestId уже отправленного запроса. */\nexport class CommandError extends Error implements CommandFailure {\n readonly error: ContractError;\n readonly origin: 'local' | 'host';\n readonly requestId: string | null;\n\n constructor(error: ContractError, origin: 'local' | 'host', requestId: string | null = null, options?: ErrorOptions) {\n super(error.message, options);\n this.name = 'CommandError';\n this.error = error;\n this.origin = origin;\n this.requestId = requestId;\n }\n}\n\n/** Ошибка вызова: команда, флаг или значение; запрос не отправлен. */\nexport function usageError(message: string, nextSteps: [string, ...string[]], data?: Record<string, unknown>): CommandError {\n return new CommandError(contractError('invalid_request', message, nextSteps, data), 'local');\n}\n\n/** Причина отказа, которую принёс исполнитель команды. */\nfunction failureOf(cause: unknown): CommandFailure | undefined {\n if (cause instanceof CommandError) return cause;\n if (typeof cause !== 'object' || cause === null) return undefined;\n const candidate = cause as { error?: unknown; origin?: unknown; requestId?: unknown };\n if (!isContractError(candidate.error)) return undefined;\n return {\n error: candidate.error,\n origin: candidate.origin === 'host' ? 'host' : 'local',\n requestId: typeof candidate.requestId === 'string' ? candidate.requestId : null,\n };\n}\n\n/** Форма контрактной ошибки (D-053): код — строка, сообщение непустое, nextSteps — массив строк. */\nfunction isContractError(value: unknown): value is ContractError {\n if (typeof value !== 'object' || value === null) return false;\n const error = value as { code?: unknown; message?: unknown; nextSteps?: unknown };\n return typeof error.code === 'string' && typeof error.message === 'string' && Array.isArray(error.nextSteps) && error.nextSteps.length > 0;\n}\n\n/** Неожиданный сбой сервера; известная ошибка исполнителя проходит без изменений. */\nexport function internalError(cause: unknown): CommandError {\n const known = failureOf(cause);\n if (known !== undefined) return new CommandError(known.error, known.origin ?? 'local', known.requestId ?? null, { cause });\n const raw = cause instanceof Error ? cause.message : String(cause);\n const detail = redactSecretText(raw);\n const error = contractError(\n 'internal',\n `Внутренняя ошибка onreel: ${detail === '' ? 'без описания' : detail}`,\n ['Повторите команду; если ошибка повторяется — сообщите о ней с полным выводом команды.'],\n );\n return new CommandError(error, 'local', null, { cause });\n}\n\n/** Прерывание SIGINT или отмена вызова во время ожидания; requestId — уже отправленного запроса, если он был. */\nexport function interruptedError(cause: unknown, requestId: string | null = null): CommandError {\n const sent = requestId ?? failureOf(cause)?.requestId ?? null;\n const error = contractError('internal', 'Команда прервана (SIGINT).', [\n sent === null\n ? 'Повторите команду.'\n : `Запрос уже отправлен: повторите команду с --request-id ${sent}, мутацию безопасно повторить с тем же requestId (D-068).`,\n ]);\n return new CommandError(error, 'local', sent, { cause });\n}\n\n/** Признак повтора в результате глагола: дубликат сообщает исполнитель, а не сервер. */\nfunction isDuplicate(outcome: CommandOutcome): boolean {\n const result = outcome.result;\n const fromResult = typeof result === 'object' && result !== null && (result as { duplicate?: unknown }).duplicate === true;\n return outcome.duplicate === true || fromResult;\n}\n\n/** Конверт успеха `--json`: {ok: true, requestId, duplicate, result}. */\nexport function successEnvelope(outcome: CommandOutcome): CliOutput {\n const duplicate = isDuplicate(outcome);\n return {\n ok: true,\n ...(outcome.requestId === undefined ? {} : { requestId: outcome.requestId }),\n ...(outcome.requestId === undefined && !duplicate ? {} : { duplicate }),\n result: outcome.result,\n };\n}\n\n/** Конверт отказа `--json`: {ok: false, requestId, error}. */\nexport function failureEnvelope(error: CommandFailure): CliOutput {\n return { ok: false, requestId: error.requestId ?? null, error: error.error };\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n ENV_DISPATCH_ID,\n ENV_HOST_URL,\n ENV_RUN_ID,\n ENV_TASK_ID,\n ENV_TOKEN,\n HOST_DISCOVERY_FILE,\n} from '../contract/contract.const.ts';\nimport { contractError } from '../contract/contract.lib.ts';\nimport { CommandError } from './envelope.lib.ts';\nimport type { DiscoveryProvider, GlobalOptions, McpPrincipal } from './mcp.types.ts';\n\n// От чьего имени работает сервер (D-289, D-290). Клиенты MCP часто запускают сервер с урезанным окружением, и воркер,\n// которого запустил host, теряет ONREEL_HOST_URL и ONREEL_TOKEN. Тогда выбор цели (D-258) молча ушёл бы к владельцу\n// по host.json. Поэтому без env агента сервер смотрит на предков: если среди них процесс агента onreel, неявный\n// переход к владельцу запрещён. Явный --data-dir — выбор владельца, как в CLI.\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d, src/cli/mcp/principal.lib.ts. Отличия:\n// isAgentInvocation built in-library из констант контракта (в onreel — экспорт client.lib), а каталог данных даёт\n// вызывающий через DiscoveryProvider: библиотека не знает ни имени переменной окружения, ни домашнего каталога CLI.\n//\n// Linux-специфика: поиск предков читает /proc/<pid>/status и /proc/<pid>/environ — их нет на macOS и Windows.\n// Деградация спокойная и по умолчанию, без броска: нечитаемый или отсутствующий процесс просто пропускается, цепочка\n// обрывается, и findAgentAncestor возвращает undefined. Следствие: вне Linux сервер не узнает, что запущен внутри\n// процесса агента, и при урезанном env выберет владельца вместо отказа. Потребителю, которому это важно, надо\n// передать agentAncestor самому или задать principal явно.\n\n/** Сколько предков проверять: цепочка клиент → обёртки → агент короче; ограничение — от циклов в чужом /proc. */\nconst MAX_ANCESTORS = 64;\n\n/** Переменные окружения агента, которые клиент MCP должен передать серверу (D-226). */\nconst AGENT_ENV_NAMES = [ENV_HOST_URL, ENV_TOKEN, ENV_RUN_ID, ENV_TASK_ID, ENV_DISPATCH_ID] as const;\n\nfunction nonEmpty(value: string | undefined): string | undefined {\n return value === undefined || value === '' ? undefined : value;\n}\n\nfunction readProc(procRoot: string, pid: number, file: string): string | undefined {\n try {\n return readFileSync(join(procRoot, String(pid), file), 'utf8');\n } catch {\n return undefined;\n }\n}\n\n/** Окружение процесса из /proc/<pid>/environ — агент onreel: ONREEL_HOST_URL и ONREEL_TOKEN не пусты. */\nfunction hasAgentEnv(environ: string): boolean {\n const names = new Set<string>();\n for (const entry of environ.split('\\0')) {\n const separator = entry.indexOf('=');\n if (separator > 0 && separator < entry.length - 1) names.add(entry.slice(0, separator));\n }\n return names.has(ENV_HOST_URL) && names.has(ENV_TOKEN);\n}\n\n/**\n * Ближайший предок (начиная с pid), в окружении которого есть адрес и токен агента onreel, — его pid; иначе\n * undefined. Окружение процесса — то, с которым его запустили (/proc/<pid>/environ), поэтому агент виден, даже\n * если клиент MCP урезал env сервера. Без /proc (не Linux) и для нечитаемых процессов предок не находится.\n */\nexport function findAgentAncestor(pid: number = process.ppid, procRoot = '/proc'): number | undefined {\n const seen = new Set<number>();\n let current = pid;\n while (current > 0 && !seen.has(current) && seen.size < MAX_ANCESTORS) {\n seen.add(current);\n const environ = readProc(procRoot, current, 'environ');\n if (environ !== undefined && hasAgentEnv(environ)) return current;\n const parent = /^PPid:\\s*(\\d+)\\s*$/m.exec(readProc(procRoot, current, 'status') ?? '')?.[1];\n if (parent === undefined) return undefined;\n current = Number(parent);\n }\n return undefined;\n}\n\n/** Адрес и токен агента из env, если вызов идёт от агента: нет `--data-dir`, ONREEL_HOST_URL и ONREEL_TOKEN не пусты. */\nexport function isAgentInvocation(globals: GlobalOptions, env: NodeJS.ProcessEnv): boolean {\n return globals.dataDir === undefined && nonEmpty(env[ENV_HOST_URL]) !== undefined && nonEmpty(env[ENV_TOKEN]) !== undefined;\n}\n\n/**\n * Принципал сервера по флагам запуска и env (как resolveTarget, D-258): env агента — агент; явный --data-dir —\n * владелец; иначе владелец по host.json, если только сервер не запущен из процесса агента (agentAncestor).\n * Каталог данных для последней ветки даёт discovery — без него владелец называется без пути.\n */\nexport function mcpPrincipal(\n globals: GlobalOptions,\n env: NodeJS.ProcessEnv,\n agentAncestor: number | undefined,\n discovery?: DiscoveryProvider,\n): McpPrincipal {\n if (isAgentInvocation(globals, env)) {\n const dispatchId = env[ENV_DISPATCH_ID];\n return dispatchId === undefined || dispatchId === '' ? { kind: 'agent' } : { kind: 'agent', dispatchId };\n }\n if (globals.dataDir === undefined && agentAncestor !== undefined) return { kind: 'refused', agentPid: agentAncestor };\n const dataDir = globals.dataDir ?? discovery?.(globals, env);\n return dataDir === undefined ? { kind: 'owner' } : { kind: 'owner', dataDir };\n}\n\n/** Одна фраза о принципале: для instructions ответа initialize и строки stderr при запуске (D-290). */\nexport function principalText(principal: McpPrincipal): string {\n switch (principal.kind) {\n case 'agent':\n return `Сервер работает от агента onreel: токен из ${ENV_TOKEN}${principal.dispatchId === undefined ? '' : `, попытка ${principal.dispatchId}`}.`;\n case 'owner':\n return `Сервер работает от владельца: токен из ${HOST_DISCOVERY_FILE}${principal.dataDir === undefined ? '' : ` в ${principal.dataDir}`}.`;\n case 'refused':\n return (\n `Сервер запущен из процесса агента onreel (pid ${String(principal.agentPid)}), но без ${ENV_HOST_URL} и ${ENV_TOKEN}: ` +\n `от владельца по ${HOST_DISCOVERY_FILE} он не работает, каждый вызов вернёт unauthorized.`\n );\n }\n}\n\n/** Отказ вызова у сервера без env агента внутри процесса агента: unauthorized, запрос к host не отправляется. */\nexport function principalRefusal(principal: Extract<McpPrincipal, { kind: 'refused' }>): CommandError {\n return new CommandError(\n contractError(\n 'unauthorized',\n `onreel orch mcp запущен из процесса агента onreel (pid ${String(principal.agentPid)}) без ${ENV_HOST_URL} и ${ENV_TOKEN}: ` +\n `клиент MCP не передал серверу окружение агента, а работать от владельца по ${HOST_DISCOVERY_FILE} внутри агента сервер отказывается.`,\n [\n `Передайте серверу переменные ${AGENT_ENV_NAMES.join(', ')} в конфигурации клиента MCP (Codex — env_vars, Claude Code — env, opencode — environment).`,\n 'До тех пор вызывайте те же команды в оболочке: onreel orch … получает окружение агента.',\n ],\n { agentPid: principal.agentPid },\n ),\n 'local',\n );\n}\n","import { z } from 'zod';\nimport { requestIdSchema } from '../contract/contract.schema.ts';\nimport { requiredFlagNames } from './args.lib.ts';\nimport { DURATION_PATTERN, MCP_REQUEST_ID_ARGUMENT } from './mcp.const.ts';\nimport type { CliOutput } from './mcp.schema.ts';\nimport type { CommandSpec, FlagSpec, JsonSchema, McpInputSchema, McpTool, McpToolResult } from './mcp.types.ts';\n\n// Инструменты MCP строятся из таблицы команд вызывающего: имя — путь через `_`, свойства входной схемы — флаги без\n// `--` и request-id. Обязательны флаги, которые нечем заполнить в окружении сервера (env, default): правило берётся\n// из разбора аргументов (requiredFlagNames), шаблоны длительности и requestId — из их источников.\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d, src/cli/mcp/tools.lib.ts. Отличия: таблица\n// команд обязательна (в onreel значение по умолчанию — orchCommandSpecs из orch.const.ts, файла CLI в библиотеке нет);\n// признак мутации смотрится в spec.mutation (в onreel — hostCommands[spec.verb].mutation, реестра глаголов здесь нет);\n// DURATION_PATTERN и имя аргумента идемпотентности — свои константы из mcp.const.ts вместо args.const.ts.\n\nlet requestIdPattern: { value: string | undefined } | undefined;\n\n/** Шаблон requestId из схемы контракта, а не переписанный руками; считается при первом списке инструментов. */\nfunction requestIdPatternOf(): string | undefined {\n requestIdPattern ??= { value: (z.toJSONSchema(requestIdSchema) as { pattern?: string }).pattern };\n return requestIdPattern.value;\n}\n\n/** Имя инструмента: путь команды через `_` (orch_task_create). */\nexport function toolName(spec: CommandSpec): string {\n return spec.path.join('_');\n}\n\n/** Команды-инструменты: переданная таблица без самой команды сервера (`orch mcp`). */\nexport function mcpToolSpecs(specs: readonly CommandSpec[]): CommandSpec[] {\n return specs.filter((spec) => spec.handler !== 'mcp');\n}\n\nfunction typeOf(flag: FlagSpec): JsonSchema {\n switch (flag.parse) {\n case 'int':\n return { type: 'integer' };\n case 'boolean':\n return { type: 'boolean' };\n case 'csv':\n return { type: 'array', items: { type: 'string' } };\n case 'json':\n return { type: 'object' };\n case 'duration':\n return { type: 'string', pattern: DURATION_PATTERN.source };\n default:\n return flag.multiple === true ? { type: 'array', items: { type: 'string' } } : { type: 'string' };\n }\n}\n\nfunction descriptionOf(flag: FlagSpec): string {\n const notes: string[] = [];\n if (flag.env !== undefined && !flag.help.includes(flag.env)) notes.push(`по умолчанию из ${flag.env}`);\n if (flag.default !== undefined) notes.push(`по умолчанию ${JSON.stringify(flag.default)}`);\n if (flag.parse === 'duration') notes.push('длительность: 30s, 5m, 1h или число миллисекунд');\n if (flag.parse === 'path') notes.push('относительный путь — от рабочего каталога сервера');\n return notes.length === 0 ? flag.help : `${flag.help} (${notes.join('; ')})`;\n}\n\n/** Входная схема инструмента; обязательность — по env сервера, как проверка обязательных флагов CLI. */\nexport function inputSchemaOf(spec: CommandSpec, env: NodeJS.ProcessEnv): McpInputSchema {\n const properties: Record<string, JsonSchema> = {};\n for (const flag of spec.flags) {\n properties[flag.name] = {\n ...typeOf(flag),\n description: descriptionOf(flag),\n ...(flag.default === undefined ? {} : { default: flag.default }),\n };\n }\n const pattern = requestIdPatternOf();\n properties[MCP_REQUEST_ID_ARGUMENT] = {\n type: 'string',\n ...(pattern === undefined ? {} : { pattern }),\n description: 'requestId запроса (флаг --request-id): повтор с тем же значением вернёт результат первого выполнения',\n };\n return { type: 'object', properties, required: requiredFlagNames(spec, env), additionalProperties: false };\n}\n\n/**\n * Инструмент MCP строки таблицы; readOnlyHint — по флагу мутации глагола контракта, локальная команда — только чтение.\n * Префикс `onreel` в title и description — текст скопированный из onreel дословно: таблица команд у вызывающего своя,\n * и сервер MCP отвечает на протокол от имени этого CLI.\n */\nexport function toolOf(spec: CommandSpec, env: NodeJS.ProcessEnv): McpTool {\n const command = spec.path.join(' ');\n const summary = spec.summary.replace(/\\.$/, '');\n const description =\n `${summary}. То же, что onreel ${command}.` +\n (spec.rule === undefined ? '' : ` Правило: ${spec.rule}`) +\n (spec.verb === undefined ? '' : ` Глагол контракта: ${spec.verb}.`);\n return {\n name: toolName(spec),\n title: `onreel ${command}`,\n description,\n inputSchema: inputSchemaOf(spec, env),\n annotations: { readOnlyHint: spec.verb === undefined ? true : spec.mutation !== true, openWorldHint: false },\n };\n}\n\n/** Результат вызова инструмента: конверт `--json` текстом и, если версия протокола позволяет, объектом. */\nexport function toolResult(output: CliOutput, structured: boolean): McpToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify(output) }],\n ...(structured ? { structuredContent: output } : {}),\n ...(output.ok ? {} : { isError: true as const }),\n };\n}\n","import { HOST_CONTRACT_VERSION } from '../contract/contract.const.ts';\nimport { formatVersion } from '../contract/contract.lib.ts';\nimport { redactSecretText } from '../kernel/redact.lib.ts';\nimport { resolveJsonArguments } from './args.lib.ts';\nimport { failureEnvelope, internalError, interruptedError, successEnvelope } from './envelope.lib.ts';\nimport {\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_INVALID_REQUEST,\n JSONRPC_METHOD_NOT_FOUND,\n JSONRPC_PARSE_ERROR,\n MCP_EOF_GRACE_MS,\n MCP_INSTRUCTIONS,\n MCP_MAX_LINE_BYTES,\n MCP_PROGRESS_INTERVAL_MS,\n MCP_PROTOCOL_VERSIONS,\n MCP_SERVER_NAME,\n MCP_SERVER_TITLE,\n MCP_STRUCTURED_SINCE,\n} from './mcp.const.ts';\nimport type { CliOutput } from './mcp.schema.ts';\nimport { cancelledParamsSchema, initializeParamsSchema, jsonRpcMessageSchema, toolsCallParamsSchema } from './mcp.schema.ts';\nimport type { JsonRpcId, ToolsCallParams } from './mcp.schema.ts';\nimport type { CliIo, CommandSpec, GlobalOptions, McpServerOptions } from './mcp.types.ts';\nimport { mcpPrincipal, principalRefusal, principalText } from './principal.lib.ts';\nimport { mcpToolSpecs, toolName, toolOf, toolResult } from './tools.lib.ts';\n\n// Сервер MCP (D-279…D-290): JSON-RPC 2.0 построчно на stdio, только инструменты. Каждый вызов\n// инструмента — как отдельный вызов onreel: аргументы разбирает тот же разбор флагов, команду выполняет executeCommand\n// CLI (переданный параметром), цель и токен находятся заново на каждом вызове. stdout — только сообщения протокола.\n// Принципал сервера (агент, владелец или отказ) определяется при запуске и называется в instructions (D-289, D-290).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d, src/cli/mcp/server.lib.ts. Отличия: разбор\n// аргументов, ошибки и конверт — свои файлы библиотеки (args.lib.ts, envelope.lib.ts, mcp.schema.ts), маскирование\n// секретов — redactSecretText из ядра; обработчик 'mcp' runMcp не копирован — он привязан к CLI onreel,\n// библиотека отдаёт serveMcp и сборщики.\n\n/** Ошибка протокола: ответ JSON-RPC с error вместо result. */\nclass RpcError extends Error {\n readonly code: number;\n\n constructor(code: number, message: string) {\n super(message);\n this.name = 'RpcError';\n this.code = code;\n }\n}\n\n/** Ключ вызова в таблице отмены: 1 и \"1\" — разные id JSON-RPC. */\nfunction keyOf(id: JsonRpcId): string {\n return `${typeof id}:${String(id)}`;\n}\n\n/** id сообщения, если его можно прочитать, — для ответа на неверный запрос. */\nfunction readableId(message: unknown): JsonRpcId | null {\n if (typeof message !== 'object' || message === null) return null;\n const id = (message as { id?: unknown }).id;\n return typeof id === 'string' || (typeof id === 'number' && Number.isInteger(id)) ? id : null;\n}\n\n/** Причина конца чтения: конец stdin или остановка сервера (SIGINT). */\ntype ReadEnd = 'eof' | 'stop';\n\n/**\n * Строки input по `\\n` (CR в конце снимается). Строка длиннее maxBytes байт не собирается: onOverflow, и всё до\n * следующего `\\n` отбрасывается (D-288). Последняя строка без перевода строки отдаётся в конце ввода. Возвращает\n * остановку чтения.\n */\nfunction readLines(\n input: NodeJS.ReadableStream,\n maxBytes: number,\n onLine: (line: string) => void,\n onOverflow: () => void,\n onEnd: (reason: ReadEnd) => void,\n): () => void {\n let chunks: Buffer[] = [];\n let size = 0;\n let skipping = false;\n let closed = false;\n const emit = (tail: Buffer): void => {\n const line = Buffer.concat([...chunks, tail]).toString('utf8');\n chunks = [];\n size = 0;\n onLine(line.endsWith('\\r') ? line.slice(0, -1) : line);\n };\n const onData = (data: Buffer | string): void => {\n let chunk = typeof data === 'string' ? Buffer.from(data, 'utf8') : data;\n while (!closed) {\n const newline = chunk.indexOf(0x0a);\n const piece = newline === -1 ? chunk : chunk.subarray(0, newline);\n if (!skipping) {\n if (size + piece.length > maxBytes) {\n chunks = [];\n size = 0;\n skipping = true;\n onOverflow();\n } else if (newline === -1) {\n chunks.push(piece);\n size += piece.length;\n } else {\n emit(piece);\n }\n }\n if (newline === -1) return;\n skipping = false;\n chunk = chunk.subarray(newline + 1);\n }\n };\n const finish = (reason: ReadEnd): void => {\n if (closed) return;\n closed = true;\n input.off('data', onData);\n input.off('end', onInputEnd);\n input.off('close', onInputEnd);\n input.pause();\n onEnd(reason);\n };\n const onInputEnd = (): void => {\n if (closed) return;\n if (!skipping && size > 0) emit(Buffer.alloc(0));\n finish('eof');\n };\n // Ошибка чтения stdin — тот же конец ввода: за ней приходит close.\n input.on('error', () => {});\n input.on('data', onData);\n input.once('end', onInputEnd);\n input.once('close', onInputEnd);\n return () => {\n finish('stop');\n };\n}\n\nfunction negotiate(requested: string): string {\n return (MCP_PROTOCOL_VERSIONS as readonly string[]).includes(requested) ? requested : MCP_PROTOCOL_VERSIONS[0];\n}\n\n/** Цикл MCP на stdio: читает строки input, отвечает в io.stdout; конец input — дождаться начатых вызовов и выйти. */\nexport function serveMcp(options: McpServerOptions): Promise<void> {\n const { execute, io } = options;\n const specs = mcpToolSpecs(options.specs);\n const byName = new Map(specs.map((spec) => [toolName(spec), spec]));\n const progressIntervalMs = options.progressIntervalMs ?? MCP_PROGRESS_INTERVAL_MS;\n const principal = options.principal ?? mcpPrincipal(options.globals, io.env, undefined, options.discovery);\n const instructions = `${MCP_INSTRUCTIONS} ${principalText(principal)} Рабочий каталог сервера: ${io.cwd}; относительные пути аргументов — от него.`;\n // До initialize — последняя версия: structuredContent есть.\n let protocolVersion: string = MCP_PROTOCOL_VERSIONS[0];\n const calls = new Map<string, AbortController>();\n const running = new Set<Promise<void>>();\n\n const send = (message: Record<string, unknown>): void => {\n io.stdout(`${JSON.stringify({ jsonrpc: '2.0', ...message })}\\n`);\n };\n const sendError = (id: JsonRpcId | null, code: number, message: string): void => {\n send({ id, error: { code, message } });\n };\n\n /** Вызов инструмента: идёт параллельно с чтением следующих строк; отменённый вызов ответа не получает. */\n const callTool = async (id: JsonRpcId, spec: CommandSpec, params: ToolsCallParams): Promise<void> => {\n const controller = new AbortController();\n const key = keyOf(id);\n calls.set(key, controller);\n const signal = io.signal === undefined ? controller.signal : AbortSignal.any([io.signal, controller.signal]);\n const progressToken = params._meta?.progressToken;\n let progress = 0;\n const timer =\n progressToken === undefined\n ? undefined\n : setInterval(() => {\n progress += 1;\n send({ method: 'notifications/progress', params: { progressToken, progress, message: 'Ожидание…' } });\n }, progressIntervalMs);\n timer?.unref();\n // Отменённый вызов больше не шлёт progress, даже если обработчик ещё не вернулся.\n signal.addEventListener('abort', () => clearInterval(timer), { once: true });\n let output: CliOutput;\n try {\n if (principal.kind === 'refused') throw principalRefusal(principal);\n const { values, requestId } = resolveJsonArguments(spec, params.arguments, io.env, io.cwd);\n const globals: GlobalOptions = {\n json: true,\n help: false,\n ...(options.globals.dataDir === undefined ? {} : { dataDir: options.globals.dataDir }),\n ...(requestId === undefined ? {} : { requestId }),\n };\n // Обработчик не пишет в канал протокола: его stdout — в никуда.\n const callIo: CliIo = { ...io, stdout: () => {}, signal };\n output = successEnvelope(await execute(spec, values, globals, callIo));\n } catch (cause) {\n output = failureEnvelope(signal.aborted ? interruptedError(cause) : internalError(cause));\n } finally {\n clearInterval(timer);\n if (calls.get(key) === controller) calls.delete(key);\n }\n if (signal.aborted) return;\n send({ id, result: toolResult(output, protocolVersion >= MCP_STRUCTURED_SINCE) });\n };\n\n /** Запрос с id: ответ result, ошибка протокола — RpcError; tools/call отвечает сам, когда вызов закончится. */\n const handleRequest = (id: JsonRpcId, method: string, params: unknown): void => {\n switch (method) {\n case 'initialize': {\n const parsed = initializeParamsSchema.safeParse(params);\n if (!parsed.success) throw new RpcError(JSONRPC_INVALID_PARAMS, 'Неверные параметры initialize: нужен protocolVersion.');\n protocolVersion = negotiate(parsed.data.protocolVersion);\n send({\n id,\n result: {\n protocolVersion,\n capabilities: { tools: { listChanged: false } },\n serverInfo: { name: MCP_SERVER_NAME, title: MCP_SERVER_TITLE, version: formatVersion(HOST_CONTRACT_VERSION) },\n instructions,\n },\n });\n return;\n }\n case 'ping':\n send({ id, result: {} });\n return;\n case 'tools/list':\n send({ id, result: { tools: specs.map((spec) => toolOf(spec, io.env)) } });\n return;\n case 'tools/call': {\n const parsed = toolsCallParamsSchema.safeParse(params);\n if (!parsed.success) throw new RpcError(JSONRPC_INVALID_PARAMS, 'Неверные параметры tools/call: нужно имя инструмента name.');\n const spec = byName.get(parsed.data.name);\n if (spec === undefined) throw new RpcError(JSONRPC_INVALID_PARAMS, `Неизвестный инструмент ${parsed.data.name}.`);\n const call = callTool(id, spec, parsed.data).catch((cause: unknown) => {\n reportInternal(id, cause);\n });\n running.add(call);\n void call.finally(() => running.delete(call));\n return;\n }\n default:\n throw new RpcError(JSONRPC_METHOD_NOT_FOUND, `Метод не поддерживается: ${method}.`);\n }\n };\n\n /** Уведомление без id: ответа нет никогда; незнакомые уведомления пропускаются. Отмена — как SIGINT (D-285). */\n const handleNotification = (method: string, params: unknown): void => {\n if (method !== 'notifications/cancelled') return;\n const parsed = cancelledParamsSchema.safeParse(params);\n if (parsed.success) calls.get(keyOf(parsed.data.requestId))?.abort();\n };\n\n const reportInternal = (id: JsonRpcId | null, cause: unknown): void => {\n const detail = redactSecretText(cause instanceof Error ? cause.message : String(cause));\n io.stderr(`onreel orch mcp: внутренняя ошибка: ${detail}\\n`);\n sendError(id, JSONRPC_INTERNAL_ERROR, `Внутренняя ошибка сервера MCP onreel: ${detail}`);\n };\n\n const handleLine = (line: string): void => {\n if (line.trim() === '') return;\n let message: unknown;\n try {\n message = JSON.parse(line) as unknown;\n } catch {\n sendError(null, JSONRPC_PARSE_ERROR, 'Строка не JSON: сообщение JSON-RPC — один объект JSON в строке.');\n return;\n }\n if (Array.isArray(message)) {\n sendError(null, JSONRPC_INVALID_REQUEST, 'Пакеты JSON-RPC не поддерживаются: отправляйте сообщения по одному.');\n return;\n }\n const parsed = jsonRpcMessageSchema.safeParse(message);\n if (!parsed.success) {\n sendError(readableId(message), JSONRPC_INVALID_REQUEST, 'Неверное сообщение JSON-RPC 2.0.');\n return;\n }\n const { id, method, params } = parsed.data;\n if (method === undefined) {\n // Ответы клиента на запросы сервера: сервер запросов не шлёт. Без method, result и error — не сообщение JSON-RPC.\n const reply = message as Record<string, unknown>;\n if (!('result' in reply) && !('error' in reply)) {\n sendError(id ?? null, JSONRPC_INVALID_REQUEST, 'Неверное сообщение JSON-RPC 2.0: нет ни method, ни result, ни error.');\n }\n return;\n }\n if (id === undefined) {\n handleNotification(method, params);\n return;\n }\n if (id === null) {\n sendError(null, JSONRPC_INVALID_REQUEST, 'id запроса JSON-RPC — строка или целое число.');\n return;\n }\n try {\n handleRequest(id, method, params);\n } catch (cause) {\n if (cause instanceof RpcError) sendError(id, cause.code, cause.message);\n else reportInternal(id, cause);\n }\n };\n\n const maxLineBytes = options.maxLineBytes ?? MCP_MAX_LINE_BYTES;\n const eofGraceMs = options.eofGraceMs ?? MCP_EOF_GRACE_MS;\n const overflow = (): void => {\n sendError(null, JSONRPC_INVALID_REQUEST, `Строка длиннее ${String(maxLineBytes)} байт: сообщение отброшено.`);\n };\n\n return new Promise<void>((resolve) => {\n let stop = (): void => {};\n const onEnd = (reason: ReadEnd): void => {\n io.signal?.removeEventListener('abort', stop);\n // SIGINT: начатые вызовы прерываются через io.signal. Конец stdin: вызовы получают eofGraceMs, чтобы дописать\n // ответ, затем прерываются как отменённые (D-287). Прерванный вызов ответа не получает.\n const abortAll = (): void => {\n for (const controller of calls.values()) controller.abort();\n };\n const grace = reason === 'eof' && running.size > 0 ? setTimeout(abortAll, eofGraceMs) : undefined;\n void Promise.allSettled(running).then(() => {\n clearTimeout(grace);\n resolve();\n });\n };\n stop = readLines(options.input, maxLineBytes, handleLine, overflow, onEnd);\n io.signal?.addEventListener('abort', stop, { once: true });\n if (io.signal?.aborted === true) stop();\n });\n}\n"],"mappings":"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","names":["z","z","resolve"]}
1
+ {"version":3,"sources":["../../src/mcp/mcp.const.ts","../../src/mcp/mcp.schema.ts","../../src/mcp/args.lib.ts","../../src/mcp/envelope.lib.ts","../../src/mcp/principal.lib.ts","../../src/mcp/tools.lib.ts","../../src/mcp/server.lib.ts"],"sourcesContent":["// Константы сервера MCP: версии протокола, имя сервера, коды ошибок JSON-RPC 2.0 и инструкция\n// для модели. Протокол — подмножество MCP на stdio: initialize, ping, tools/list, tools/call.\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d, src/cli/mcp/mcp.const.ts; дословная копия,\n// кроме импорта CLI-инфраструктуры onreel: имя аргумента идемпотности (REQUEST_ID_FLAG из args.const.ts) и шаблон\n// длительности (DURATION_PATTERN оттуда же) объявлены здесь своими константами — в библиотеку args.const.ts не входит.\n\n/** Поддерживаемые версии протокола MCP (D-286); первая — последняя: ею отвечаем на незнакомую версию клиента. */\nexport const MCP_PROTOCOL_VERSIONS = ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'] as const;\n\n/** С этой версии результат инструмента несёт structuredContent. */\nexport const MCP_STRUCTURED_SINCE = '2025-06-18';\n\nexport const MCP_SERVER_NAME = 'onreel';\nexport const MCP_SERVER_TITLE = 'onreel orch';\n\n/** Пауза между notifications/progress долгого вызова с progressToken (D-284). */\nexport const MCP_PROGRESS_INTERVAL_MS = 15_000;\n\n/** Предел длины строки JSON-RPC (D-288): длиннее — ошибка -32600, строка отбрасывается до перевода строки. */\nexport const MCP_MAX_LINE_BYTES = 8 * 1024 * 1024;\n\n/** Сколько начатые вызовы могут дописывать ответ после конца stdin, прежде чем их прервут (D-287). */\nexport const MCP_EOF_GRACE_MS = 5_000;\n\n/** Аргумент инструмента с ключом идемпотентности — флаг --request-id CLI. */\nexport const MCP_REQUEST_ID_ARGUMENT = 'request-id';\n\n/** Длительность `<n>ms|s|m|h`, голое число — миллисекунды; значение флага parse: 'duration'. */\nexport const DURATION_PATTERN = /^\\s*(\\d+)(ms|s|m|h)?\\s*$/;\n\nexport const JSONRPC_PARSE_ERROR = -32700;\nexport const JSONRPC_INVALID_REQUEST = -32600;\nexport const JSONRPC_METHOD_NOT_FOUND = -32601;\nexport const JSONRPC_INVALID_PARAMS = -32602;\nexport const JSONRPC_INTERNAL_ERROR = -32603;\n\n/** Инструкция сервера модели (ответ initialize). */\nexport const MCP_INSTRUCTIONS =\n 'Инструменты onreel — те же команды, что `onreel orch …`, с теми же правами. Имя инструмента — путь команды через `_` ' +\n '(orch_task_create — это onreel orch task create), аргументы — флаги команды без `--`; request-id — ключ идемпотентности: ' +\n 'повтор с тем же значением вернёт результат первого выполнения. Результат — конверт как у `--json`: ' +\n '{ok: true, requestId, duplicate, result} или {ok: false, requestId, error: {code, message, nextSteps}}; ' +\n 'флаг `--x` в nextSteps — это аргумент x. Истёкшее ожидание orch_check и orch_ask — не ошибка (timedOut, answered: false): ' +\n 'повторите вызов; держите timeout короче таймаута вызова у клиента (например, 5m). Права — у токена, с которым запущен ' +\n 'сервер: владелец из host.json или агент из переменных ONREEL_*.';\n","import { z } from 'zod';\nimport { contractErrorSchema, requestIdSchema } from '../contract/contract.schema.ts';\n\n// Сообщения JSON-RPC 2.0 и параметры методов MCP, которые читает сервер. Параметры не строгие: поля новых версий\n// протокола не ломают разбор. Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d,\n// src/cli/mcp/mcp.schema.ts (дословно) + src/cli/output.schema.ts: конверт результата вызова добавлен сюда,\n// потому что output.schema.ts — CLI-инфраструктура onreel, а форма результата входит в контракт сервера MCP.\n\nexport const jsonRpcIdSchema = z.union([z.string(), z.number().int()]);\n\n/** Любое сообщение JSON-RPC: запрос (id и method), уведомление (только method) или ответ (result или error). */\nexport const jsonRpcMessageSchema = z.object({\n jsonrpc: z.literal('2.0'),\n id: jsonRpcIdSchema.nullable().optional(),\n method: z.string().optional(),\n params: z.unknown().optional(),\n result: z.unknown().optional(),\n error: z.unknown().optional(),\n});\n\nexport const initializeParamsSchema = z\n .object({ protocolVersion: z.string(), capabilities: z.unknown().optional(), clientInfo: z.unknown().optional() })\n .loose();\n\nexport const toolsCallParamsSchema = z\n .object({\n name: z.string().min(1),\n arguments: z.unknown().optional(),\n _meta: z.object({ progressToken: z.union([z.string(), z.number()]).optional() }).loose().optional(),\n })\n .loose();\n\nexport const cancelledParamsSchema = z.object({ requestId: jsonRpcIdSchema, reason: z.string().optional() }).loose();\n\n// Конверт результата команды (D-052): одна строка JSON в content, и им же structuredContent на новых версиях\n// протокола. requestId нет у локальных команд, и он равен null у локальных ошибок.\n\nexport const cliSuccessSchema = z.object({\n ok: z.literal(true),\n requestId: requestIdSchema.optional(),\n duplicate: z.boolean().optional(),\n result: z.unknown(),\n});\n\nexport const cliFailureSchema = z.object({\n ok: z.literal(false),\n requestId: requestIdSchema.nullable(),\n error: contractErrorSchema,\n});\n\nexport const cliOutputSchema = z.discriminatedUnion('ok', [cliSuccessSchema, cliFailureSchema]);\n\nexport type JsonRpcId = z.infer<typeof jsonRpcIdSchema>;\nexport type JsonRpcMessage = z.infer<typeof jsonRpcMessageSchema>;\nexport type InitializeParams = z.infer<typeof initializeParamsSchema>;\nexport type ToolsCallParams = z.infer<typeof toolsCallParamsSchema>;\nexport type CancelledParams = z.infer<typeof cancelledParamsSchema>;\nexport type CliOutput = z.infer<typeof cliOutputSchema>;\n","import { resolve } from 'node:path';\nimport { requestIdSchema } from '../contract/contract.schema.ts';\nimport { DURATION_PATTERN, MCP_REQUEST_ID_ARGUMENT } from './mcp.const.ts';\nimport { usageError } from './envelope.lib.ts';\nimport type { CommandSpec, FlagSpec } from './mcp.types.ts';\n\n// Разбор аргументов вызова инструмента: объект JSON `{\"флаг\": значение}` → значения флагов команды. Минимальная\n// копия той части src/cli/args.lib.ts onreel (@ b73407be076a5df73931d1340f70910ca13c908d), которая нужна серверу MCP:\n// хвост разбора (явные значения, env, default, конфликт полей тела, проверка обязательных) и разбор значений по\n// типу флага. Разбор argv (parseInvocation, ведущие позиционные, глобальные флаги) остаётся в CLI потребителя —\n// в библиотеке его нет, поэтому и ошибка всегда invalid_request с шагами как у CLI.\n\nconst durationUnits: Record<string, number> = { ms: 1, s: 1000, m: 60_000, h: 3_600_000 };\n\n/** Длительность `<n>ms|s|m|h`, голое число — миллисекунды; неверная запись — undefined. */\nexport function parseDuration(text: string): number | undefined {\n const match = DURATION_PATTERN.exec(text);\n if (match === null) return undefined;\n const value = Number(match[1]) * (durationUnits[match[2] ?? 'ms'] ?? 1);\n return Number.isSafeInteger(value) ? value : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction helpStep(path: readonly string[]): string {\n return `Справка: onreel ${[...path, '--help'].join(' ')}`;\n}\n\nfunction applyTemplate(template: string | undefined, value: unknown): unknown {\n return template === undefined || typeof value !== 'string' ? value : template.replaceAll('{value}', value);\n}\n\nfunction valueError(flag: FlagSpec, what: string, path: readonly string[]): Error {\n return usageError(`Неверное значение --${flag.name}: ${what}.`, [`Значение --${flag.name}: ${flag.help}`, helpStep(path)], {\n flag: flag.name,\n });\n}\n\n/** Значение одной строки флага по его типу разбора. */\nfunction parseOne(flag: FlagSpec, text: string, cwd: string, path: readonly string[]): unknown {\n const fail = (what: string): never => {\n throw valueError(flag, what, path);\n };\n switch (flag.parse) {\n case 'string':\n return text;\n case 'boolean':\n return text === 'true' || text === '1';\n case 'int': {\n const value = /^-?\\d+$/.test(text.trim()) ? Number(text) : Number.NaN;\n return Number.isSafeInteger(value) ? value : fail(`ожидается целое число, получено «${text}»`);\n }\n case 'csv':\n return text\n .split(',')\n .map((part) => part.trim())\n .filter((part) => part !== '');\n case 'json':\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return fail('ожидается JSON');\n }\n case 'duration':\n return parseDuration(text) ?? fail(`ожидается длительность вида 30s, 5m, 1h или число миллисекунд, получено «${text}»`);\n case 'path':\n return text === '' ? fail('пустой путь') : resolve(cwd, text);\n }\n}\n\n/** Что ожидается в JSON-значении флага: текст ошибки неверного типа. */\nfunction expectedOf(flag: FlagSpec): string {\n switch (flag.parse) {\n case 'int':\n return 'ожидается целое число';\n case 'boolean':\n return 'ожидается true или false';\n case 'csv':\n return 'ожидается массив строк или строка через запятую';\n case 'duration':\n return 'ожидается длительность строкой (30s, 5m, 1h) или неотрицательное целое число миллисекунд';\n case 'json':\n return 'ожидается JSON';\n default:\n return 'ожидается строка';\n }\n}\n\nfunction typeError(flag: FlagSpec, path: readonly string[]): never {\n throw valueError(flag, expectedOf(flag), path);\n}\n\n/**\n * Одно JSON-значение флага (элемент массива у повторяемого флага): строки разбирает тот же parseOne, что argv,\n * числа и логические значения принимаются по типу флага. Шаблон флага применяется как в CLI.\n */\nfunction jsonScalar(flag: FlagSpec, value: unknown, cwd: string, path: readonly string[]): unknown {\n let parsed: unknown;\n if (typeof value === 'string' && flag.parse !== 'boolean') parsed = parseOne(flag, value, cwd, path);\n else if (flag.parse === 'boolean' && value === true) parsed = true;\n else if (flag.parse === 'int' && Number.isSafeInteger(value)) parsed = value;\n else if (flag.parse === 'duration' && Number.isSafeInteger(value) && (value as number) >= 0) parsed = value;\n else if (flag.parse === 'json' && typeof value !== 'string') parsed = value;\n else if (flag.parse === 'csv' && Array.isArray(value)) {\n // Элементы массива — как значения через запятую в argv: каждый разбирается тем же csv.\n parsed = value.map((item) => (typeof item === 'string' ? parseOne(flag, item, cwd, path) : typeError(flag, path))).flat();\n } else return typeError(flag, path);\n return applyTemplate(flag.template, parsed);\n}\n\n/** Значение флага из аргументов MCP; undefined — флага нет (null и false у переключателя — как отсутствие флага в argv). */\nfunction jsonFlagValue(flag: FlagSpec, value: unknown, cwd: string, path: readonly string[]): (() => unknown) | undefined {\n if (value === undefined || value === null || (flag.parse === 'boolean' && value === false)) return undefined;\n if (flag.multiple !== true || flag.parse === 'csv') return () => jsonScalar(flag, value, cwd, path);\n const items = Array.isArray(value) ? value : [value];\n if (items.length === 0) return undefined;\n return () => items.map((item) => jsonScalar(flag, item, cwd, path));\n}\n\n/** Ключ поля тела, в которое пишет флаг; флаг без field читает обработчик — ключ по имени флага. */\nfunction targetOf(flag: FlagSpec): string {\n return flag.field === undefined ? `flag:${flag.name}` : `field:${flag.field}`;\n}\n\n/** Флаг заполняется без явного значения: непустая переменная env или default. */\nfunction implicitlyFilled(flag: FlagSpec, env: NodeJS.ProcessEnv): boolean {\n const fromEnv = flag.env === undefined ? undefined : env[flag.env];\n return (fromEnv !== undefined && fromEnv !== '') || flag.default !== undefined;\n}\n\n/**\n * Флаги, без которых вызов не пройдёт проверку обязательных: required, и поле флага не заполнит ни env, ни default\n * (его или другого флага того же поля), ни другой флаг того же поля, заданный явно. Это обязательные свойства\n * входной схемы инструмента MCP.\n */\nexport function requiredFlagNames(spec: CommandSpec, env: NodeJS.ProcessEnv): string[] {\n return spec.flags\n .filter((flag) => {\n if (flag.required !== true) return false;\n const target = targetOf(flag);\n return !spec.flags.some((other) => targetOf(other) === target && (other !== flag || implicitlyFilled(other, env)));\n })\n .map((flag) => flag.name);\n}\n\n/** Явный флаг вызова и разбор его значения; разбор ленивый — ошибки идут в том же порядке, что флаги таблицы. */\ntype ExplicitFlag = readonly [FlagSpec, () => unknown];\n\n/**\n * Общий хвост разбора: явные значения (два флага с одним полем тела — ошибка), затем env и default,\n * затем проверка обязательных флагов.\n */\nfunction resolveFlagValues(spec: CommandSpec, explicit: readonly ExplicitFlag[], env: NodeJS.ProcessEnv, cwd: string): Record<string, unknown> {\n // Явные флаги: два флага с одним полем тела — ошибка.\n const values: Record<string, unknown> = {};\n const writers = new Map<string, string>();\n for (const [flag, parse] of explicit) {\n values[flag.name] = parse();\n const target = targetOf(flag);\n const other = writers.get(target);\n if (other !== undefined) {\n const what = flag.field === undefined ? 'одно и то же значение' : `одно и то же поле ${flag.field}`;\n throw usageError(`Флаги --${other} и --${flag.name} задают ${what}.`, [`Оставьте один из флагов: --${other} или --${flag.name}.`]);\n }\n writers.set(target, flag.name);\n }\n\n // env и default заполняют только поля, которые не задал явный флаг.\n for (const flag of spec.flags) {\n if (values[flag.name] !== undefined || writers.has(targetOf(flag))) continue;\n const fromEnv = flag.env === undefined ? undefined : env[flag.env];\n let value: unknown;\n if (fromEnv !== undefined && fromEnv !== '') value = applyTemplate(flag.envTemplate, parseOne(flag, fromEnv, cwd, spec.path));\n else if (flag.default !== undefined) value = flag.default;\n if (value === undefined) continue;\n values[flag.name] = value;\n writers.set(targetOf(flag), flag.name);\n }\n\n for (const flag of spec.flags) {\n if (flag.required !== true || writers.has(targetOf(flag))) continue;\n const steps: [string, ...string[]] = [`Добавьте --${flag.name} ${flag.placeholder ?? '<значение>'}: ${flag.help}`];\n if (flag.env !== undefined) steps.push(`Или задайте переменную ${flag.env}.`);\n steps.push(helpStep(spec.path));\n throw usageError(`Не задан обязательный флаг --${flag.name} команды onreel ${spec.path.join(' ')}.`, steps, { flag: flag.name });\n }\n return values;\n}\n\n/** Ошибка неверного request-id: тот же текст, что у флага --request-id в CLI. */\nfunction requestIdError(value: string): Error {\n return usageError(`Неверный --request-id: ${value}.`, [\n 'requestId — до 128 символов: латиница, цифры и . _ : -, первый символ — буква или цифра.',\n ]);\n}\n\n/**\n * Аргументы вызова инструмента MCP (объект JSON) → значения флагов команды: тот же разбор, шаблоны, env,\n * default, конфликт полей и проверка обязательных, что у argv. Ошибка — invalid_request (origin local).\n */\nexport function resolveJsonArguments(\n spec: CommandSpec,\n input: unknown,\n env: NodeJS.ProcessEnv,\n cwd: string,\n): { values: Readonly<Record<string, unknown>>; requestId?: string } {\n const command = `onreel ${spec.path.join(' ')}`;\n const args = input === undefined || input === null ? {} : input;\n if (!isRecord(args)) {\n throw usageError(`Неверные аргументы ${command}: ожидается объект JSON {\"флаг\": значение}.`, [helpStep(spec.path)]);\n }\n const byName = new Map(spec.flags.map((flag) => [flag.name, flag]));\n let requestId: string | undefined;\n for (const [key, value] of Object.entries(args)) {\n if (key === MCP_REQUEST_ID_ARGUMENT) {\n if (value === undefined || value === null) continue;\n if (typeof value !== 'string' || !requestIdSchema.safeParse(value).success) {\n throw requestIdError(typeof value === 'string' ? value : JSON.stringify(value));\n }\n requestId = value;\n } else if (!byName.has(key)) {\n const known = [...byName.keys(), MCP_REQUEST_ID_ARGUMENT].join(', ');\n const steps: [string, ...string[]] =\n key === 'data-dir'\n ? ['Каталог данных host задаётся при запуске сервера: onreel orch mcp --data-dir <каталог>.']\n : [`Аргументы ${command}: ${known}.`, helpStep(spec.path)];\n throw usageError(`Неизвестный аргумент ${key} команды ${command}.`, steps, { argument: key });\n }\n }\n\n // Явные значения — в порядке флагов таблицы, как у argv.\n const explicit: ExplicitFlag[] = [];\n for (const flag of spec.flags) {\n const parse = jsonFlagValue(flag, args[flag.name], cwd, spec.path);\n if (parse !== undefined) explicit.push([flag, parse]);\n }\n const values = resolveFlagValues(spec, explicit, env, cwd);\n return requestId === undefined ? { values } : { values, requestId };\n}\n","import { contractError } from '../contract/contract.lib.ts';\nimport type { ContractError } from '../contract/contract.types.ts';\nimport { redactSecretText } from '../kernel/redact.lib.ts';\nimport type { CliOutput } from './mcp.schema.ts';\nimport type { CommandFailure, CommandOutcome } from './mcp.types.ts';\n\n// Ошибка вызова команды и конверт её результата. Это минимальные копии того, что в onreel живёт в CLI-инфраструктуре\n// (src/cli/errors.lib.ts и src/cli/output.lib.ts @ b73407be076a5df73931d1340f70910ca13c908d): библиотека не имеет\n// права их импортировать, а серверу MCP они нужны, чтобы отдавать клиенту ровно тот же конверт `--json`, что и CLI.\n// Отличие от onreel: отказ исполнителя распознаётся структурно (isCommandFailure), а не через instanceof —\n// исполнитель принадлежит потребителю и бросает свой класс ошибки, и её код должен дойти до клиента неизменным.\n\n/** Ошибка вызова команды: контрактная ошибка, происхождение и requestId уже отправленного запроса. */\nexport class CommandError extends Error implements CommandFailure {\n readonly error: ContractError;\n readonly origin: 'local' | 'host';\n readonly requestId: string | null;\n\n constructor(error: ContractError, origin: 'local' | 'host', requestId: string | null = null, options?: ErrorOptions) {\n super(error.message, options);\n this.name = 'CommandError';\n this.error = error;\n this.origin = origin;\n this.requestId = requestId;\n }\n}\n\n/** Ошибка вызова: команда, флаг или значение; запрос не отправлен. */\nexport function usageError(message: string, nextSteps: [string, ...string[]], data?: Record<string, unknown>): CommandError {\n return new CommandError(contractError('invalid_request', message, nextSteps, data), 'local');\n}\n\n/** Причина отказа, которую принёс исполнитель команды. */\nfunction failureOf(cause: unknown): CommandFailure | undefined {\n if (cause instanceof CommandError) return cause;\n if (typeof cause !== 'object' || cause === null) return undefined;\n const candidate = cause as { error?: unknown; origin?: unknown; requestId?: unknown };\n if (!isContractError(candidate.error)) return undefined;\n return {\n error: candidate.error,\n origin: candidate.origin === 'host' ? 'host' : 'local',\n requestId: typeof candidate.requestId === 'string' ? candidate.requestId : null,\n };\n}\n\n/** Форма контрактной ошибки (D-053): код — строка, сообщение непустое, nextSteps — массив строк. */\nfunction isContractError(value: unknown): value is ContractError {\n if (typeof value !== 'object' || value === null) return false;\n const error = value as { code?: unknown; message?: unknown; nextSteps?: unknown };\n return typeof error.code === 'string' && typeof error.message === 'string' && Array.isArray(error.nextSteps) && error.nextSteps.length > 0;\n}\n\n/** Неожиданный сбой сервера; известная ошибка исполнителя проходит без изменений. */\nexport function internalError(cause: unknown): CommandError {\n const known = failureOf(cause);\n if (known !== undefined) return new CommandError(known.error, known.origin ?? 'local', known.requestId ?? null, { cause });\n const raw = cause instanceof Error ? cause.message : String(cause);\n const detail = redactSecretText(raw);\n const error = contractError(\n 'internal',\n `Внутренняя ошибка onreel: ${detail === '' ? 'без описания' : detail}`,\n ['Повторите команду; если ошибка повторяется — сообщите о ней с полным выводом команды.'],\n );\n return new CommandError(error, 'local', null, { cause });\n}\n\n/** Прерывание SIGINT или отмена вызова во время ожидания; requestId — уже отправленного запроса, если он был. */\nexport function interruptedError(cause: unknown, requestId: string | null = null): CommandError {\n const sent = requestId ?? failureOf(cause)?.requestId ?? null;\n const error = contractError('internal', 'Команда прервана (SIGINT).', [\n sent === null\n ? 'Повторите команду.'\n : `Запрос уже отправлен: повторите команду с --request-id ${sent}, мутацию безопасно повторить с тем же requestId (D-068).`,\n ]);\n return new CommandError(error, 'local', sent, { cause });\n}\n\n/** Признак повтора в результате глагола: дубликат сообщает исполнитель, а не сервер. */\nfunction isDuplicate(outcome: CommandOutcome): boolean {\n const result = outcome.result;\n const fromResult = typeof result === 'object' && result !== null && (result as { duplicate?: unknown }).duplicate === true;\n return outcome.duplicate === true || fromResult;\n}\n\n/** Конверт успеха `--json`: {ok: true, requestId, duplicate, result}. */\nexport function successEnvelope(outcome: CommandOutcome): CliOutput {\n const duplicate = isDuplicate(outcome);\n return {\n ok: true,\n ...(outcome.requestId === undefined ? {} : { requestId: outcome.requestId }),\n ...(outcome.requestId === undefined && !duplicate ? {} : { duplicate }),\n result: outcome.result,\n };\n}\n\n/** Конверт отказа `--json`: {ok: false, requestId, error}. */\nexport function failureEnvelope(error: CommandFailure): CliOutput {\n return { ok: false, requestId: error.requestId ?? null, error: error.error };\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n ENV_DISPATCH_ID,\n ENV_HOST_URL,\n ENV_RUN_ID,\n ENV_TASK_ID,\n ENV_TOKEN,\n HOST_DISCOVERY_FILE,\n} from '../contract/contract.const.ts';\nimport { contractError } from '../contract/contract.lib.ts';\nimport { CommandError } from './envelope.lib.ts';\nimport type { DiscoveryProvider, GlobalOptions, McpPrincipal } from './mcp.types.ts';\n\n// От чьего имени работает сервер (D-289, D-290). Клиенты MCP часто запускают сервер с урезанным окружением, и воркер,\n// которого запустил host, теряет ONREEL_HOST_URL и ONREEL_TOKEN. Тогда выбор цели (D-258) молча ушёл бы к владельцу\n// по host.json. Поэтому без env агента сервер смотрит на предков: если среди них процесс агента onreel, неявный\n// переход к владельцу запрещён. Явный --data-dir — выбор владельца, как в CLI.\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d, src/cli/mcp/principal.lib.ts. Отличия:\n// isAgentInvocation built in-library из констант контракта (в onreel — экспорт client.lib), а каталог данных даёт\n// вызывающий через DiscoveryProvider: библиотека не знает ни имени переменной окружения, ни домашнего каталога CLI.\n//\n// Linux-специфика: поиск предков читает /proc/<pid>/status и /proc/<pid>/environ — их нет на macOS и Windows.\n// Деградация спокойная и по умолчанию, без броска: нечитаемый или отсутствующий процесс просто пропускается, цепочка\n// обрывается, и findAgentAncestor возвращает undefined. Следствие: вне Linux сервер не узнает, что запущен внутри\n// процесса агента, и при урезанном env выберет владельца вместо отказа. Потребителю, которому это важно, надо\n// передать agentAncestor самому или задать principal явно.\n\n/** Сколько предков проверять: цепочка клиент → обёртки → агент короче; ограничение — от циклов в чужом /proc. */\nconst MAX_ANCESTORS = 64;\n\n/** Переменные окружения агента, которые клиент MCP должен передать серверу (D-226). */\nconst AGENT_ENV_NAMES = [ENV_HOST_URL, ENV_TOKEN, ENV_RUN_ID, ENV_TASK_ID, ENV_DISPATCH_ID] as const;\n\nfunction nonEmpty(value: string | undefined): string | undefined {\n return value === undefined || value === '' ? undefined : value;\n}\n\nfunction readProc(procRoot: string, pid: number, file: string): string | undefined {\n try {\n return readFileSync(join(procRoot, String(pid), file), 'utf8');\n } catch {\n return undefined;\n }\n}\n\n/** Окружение процесса из /proc/<pid>/environ — агент onreel: ONREEL_HOST_URL и ONREEL_TOKEN не пусты. */\nfunction hasAgentEnv(environ: string): boolean {\n const names = new Set<string>();\n for (const entry of environ.split('\\0')) {\n const separator = entry.indexOf('=');\n if (separator > 0 && separator < entry.length - 1) names.add(entry.slice(0, separator));\n }\n return names.has(ENV_HOST_URL) && names.has(ENV_TOKEN);\n}\n\n/**\n * Ближайший предок (начиная с pid), в окружении которого есть адрес и токен агента onreel, — его pid; иначе\n * undefined. Окружение процесса — то, с которым его запустили (/proc/<pid>/environ), поэтому агент виден, даже\n * если клиент MCP урезал env сервера. Без /proc (не Linux) и для нечитаемых процессов предок не находится.\n */\nexport function findAgentAncestor(pid: number = process.ppid, procRoot = '/proc'): number | undefined {\n const seen = new Set<number>();\n let current = pid;\n while (current > 0 && !seen.has(current) && seen.size < MAX_ANCESTORS) {\n seen.add(current);\n const environ = readProc(procRoot, current, 'environ');\n if (environ !== undefined && hasAgentEnv(environ)) return current;\n const parent = /^PPid:\\s*(\\d+)\\s*$/m.exec(readProc(procRoot, current, 'status') ?? '')?.[1];\n if (parent === undefined) return undefined;\n current = Number(parent);\n }\n return undefined;\n}\n\n/** Адрес и токен агента из env, если вызов идёт от агента: нет `--data-dir`, ONREEL_HOST_URL и ONREEL_TOKEN не пусты. */\nexport function isAgentInvocation(globals: GlobalOptions, env: NodeJS.ProcessEnv): boolean {\n return globals.dataDir === undefined && nonEmpty(env[ENV_HOST_URL]) !== undefined && nonEmpty(env[ENV_TOKEN]) !== undefined;\n}\n\n/**\n * Принципал сервера по флагам запуска и env (как resolveTarget, D-258): env агента — агент; явный --data-dir —\n * владелец; иначе владелец по host.json, если только сервер не запущен из процесса агента (agentAncestor).\n * Каталог данных для последней ветки даёт discovery — без него владелец называется без пути.\n */\nexport function mcpPrincipal(\n globals: GlobalOptions,\n env: NodeJS.ProcessEnv,\n agentAncestor: number | undefined,\n discovery?: DiscoveryProvider,\n): McpPrincipal {\n if (isAgentInvocation(globals, env)) {\n const dispatchId = env[ENV_DISPATCH_ID];\n return dispatchId === undefined || dispatchId === '' ? { kind: 'agent' } : { kind: 'agent', dispatchId };\n }\n if (globals.dataDir === undefined && agentAncestor !== undefined) return { kind: 'refused', agentPid: agentAncestor };\n const dataDir = globals.dataDir ?? discovery?.(globals, env);\n return dataDir === undefined ? { kind: 'owner' } : { kind: 'owner', dataDir };\n}\n\n/** Одна фраза о принципале: для instructions ответа initialize и строки stderr при запуске (D-290). */\nexport function principalText(principal: McpPrincipal): string {\n switch (principal.kind) {\n case 'agent':\n return `Сервер работает от агента onreel: токен из ${ENV_TOKEN}${principal.dispatchId === undefined ? '' : `, попытка ${principal.dispatchId}`}.`;\n case 'owner':\n return `Сервер работает от владельца: токен из ${HOST_DISCOVERY_FILE}${principal.dataDir === undefined ? '' : ` в ${principal.dataDir}`}.`;\n case 'refused':\n return (\n `Сервер запущен из процесса агента onreel (pid ${String(principal.agentPid)}), но без ${ENV_HOST_URL} и ${ENV_TOKEN}: ` +\n `от владельца по ${HOST_DISCOVERY_FILE} он не работает, каждый вызов вернёт unauthorized.`\n );\n }\n}\n\n/** Отказ вызова у сервера без env агента внутри процесса агента: unauthorized, запрос к host не отправляется. */\nexport function principalRefusal(principal: Extract<McpPrincipal, { kind: 'refused' }>): CommandError {\n return new CommandError(\n contractError(\n 'unauthorized',\n `onreel orch mcp запущен из процесса агента onreel (pid ${String(principal.agentPid)}) без ${ENV_HOST_URL} и ${ENV_TOKEN}: ` +\n `клиент MCP не передал серверу окружение агента, а работать от владельца по ${HOST_DISCOVERY_FILE} внутри агента сервер отказывается.`,\n [\n `Передайте серверу переменные ${AGENT_ENV_NAMES.join(', ')} в конфигурации клиента MCP (Codex — env_vars, Claude Code — env, opencode — environment).`,\n 'До тех пор вызывайте те же команды в оболочке: onreel orch … получает окружение агента.',\n ],\n { agentPid: principal.agentPid },\n ),\n 'local',\n );\n}\n","import { z } from 'zod';\nimport { requestIdSchema } from '../contract/contract.schema.ts';\nimport { requiredFlagNames } from './args.lib.ts';\nimport { DURATION_PATTERN, MCP_REQUEST_ID_ARGUMENT } from './mcp.const.ts';\nimport type { CliOutput } from './mcp.schema.ts';\nimport type { CommandSpec, FlagSpec, JsonSchema, McpInputSchema, McpTool, McpToolResult } from './mcp.types.ts';\n\n// Инструменты MCP строятся из таблицы команд вызывающего: имя — путь через `_`, свойства входной схемы — флаги без\n// `--` и request-id. Обязательны флаги, которые нечем заполнить в окружении сервера (env, default): правило берётся\n// из разбора аргументов (requiredFlagNames), шаблоны длительности и requestId — из их источников.\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d, src/cli/mcp/tools.lib.ts. Отличия: таблица\n// команд обязательна (в onreel значение по умолчанию — orchCommandSpecs из orch.const.ts, файла CLI в библиотеке нет);\n// признак мутации смотрится в spec.mutation, а если он живёт в реестре глаголов потребителя (в onreel —\n// hostCommands[spec.verb].mutation) — его подставляет хук readOnly (#21); DURATION_PATTERN и имя аргумента\n// идемпотентности — свои константы из mcp.const.ts вместо args.const.ts.\n\nlet requestIdPattern: { value: string | undefined } | undefined;\n\n/** Шаблон requestId из схемы контракта, а не переписанный руками; считается при первом списке инструментов. */\nfunction requestIdPatternOf(): string | undefined {\n requestIdPattern ??= { value: (z.toJSONSchema(requestIdSchema) as { pattern?: string }).pattern };\n return requestIdPattern.value;\n}\n\n/** Имя инструмента: путь команды через `_` (orch_task_create). */\nexport function toolName(spec: CommandSpec): string {\n return spec.path.join('_');\n}\n\n/** Команды-инструменты: переданная таблица без самой команды сервера (`orch mcp`); тип строки таблицы сохраняется. */\nexport function mcpToolSpecs<S extends CommandSpec>(specs: readonly S[]): S[] {\n return specs.filter((spec) => spec.handler !== 'mcp');\n}\n\n/**\n * Подсказка «только чтение» без хука вызывающего: команда без глагола контракта — локальная, она только читает;\n * у глагола признак мутации лежит в строке таблицы (в onreel — в реестре глаголов, оттуда его переносит потребитель\n * или заменяет хуком readOnly).\n */\nfunction readOnlyOf(spec: CommandSpec): boolean {\n return spec.verb === undefined ? true : spec.mutation !== true;\n}\n\nfunction typeOf(flag: FlagSpec): JsonSchema {\n switch (flag.parse) {\n case 'int':\n return { type: 'integer' };\n case 'boolean':\n return { type: 'boolean' };\n case 'csv':\n return { type: 'array', items: { type: 'string' } };\n case 'json':\n return { type: 'object' };\n case 'duration':\n return { type: 'string', pattern: DURATION_PATTERN.source };\n default:\n return flag.multiple === true ? { type: 'array', items: { type: 'string' } } : { type: 'string' };\n }\n}\n\nfunction descriptionOf(flag: FlagSpec): string {\n const notes: string[] = [];\n if (flag.env !== undefined && !flag.help.includes(flag.env)) notes.push(`по умолчанию из ${flag.env}`);\n if (flag.default !== undefined) notes.push(`по умолчанию ${JSON.stringify(flag.default)}`);\n if (flag.parse === 'duration') notes.push('длительность: 30s, 5m, 1h или число миллисекунд');\n if (flag.parse === 'path') notes.push('относительный путь — от рабочего каталога сервера');\n return notes.length === 0 ? flag.help : `${flag.help} (${notes.join('; ')})`;\n}\n\n/** Входная схема инструмента; обязательность — по env сервера, как проверка обязательных флагов CLI. */\nexport function inputSchemaOf(spec: CommandSpec, env: NodeJS.ProcessEnv): McpInputSchema {\n const properties: Record<string, JsonSchema> = {};\n for (const flag of spec.flags) {\n properties[flag.name] = {\n ...typeOf(flag),\n description: descriptionOf(flag),\n ...(flag.default === undefined ? {} : { default: flag.default }),\n };\n }\n const pattern = requestIdPatternOf();\n properties[MCP_REQUEST_ID_ARGUMENT] = {\n type: 'string',\n ...(pattern === undefined ? {} : { pattern }),\n description: 'requestId запроса (флаг --request-id): повтор с тем же значением вернёт результат первого выполнения',\n };\n return { type: 'object', properties, required: requiredFlagNames(spec, env), additionalProperties: false };\n}\n\n/**\n * Инструмент MCP строки таблицы; readOnlyHint — из хука `readOnly` вызывающего, а без него по флагу мутации глагола\n * контракта (локальная команда — только чтение). Префикс `onreel` в title и description — текст скопированный из\n * onreel дословно: таблица команд у вызывающего своя, и сервер MCP отвечает на протокол от имени этого CLI.\n */\nexport function toolOf<S extends CommandSpec>(spec: S, env: NodeJS.ProcessEnv, readOnly?: (spec: S) => boolean): McpTool {\n const command = spec.path.join(' ');\n const summary = spec.summary.replace(/\\.$/, '');\n const description =\n `${summary}. То же, что onreel ${command}.` +\n (spec.rule === undefined ? '' : ` Правило: ${spec.rule}`) +\n (spec.verb === undefined ? '' : ` Глагол контракта: ${spec.verb}.`);\n return {\n name: toolName(spec),\n title: `onreel ${command}`,\n description,\n inputSchema: inputSchemaOf(spec, env),\n annotations: { readOnlyHint: readOnly === undefined ? readOnlyOf(spec) : readOnly(spec), openWorldHint: false },\n };\n}\n\n/** Результат вызова инструмента: конверт `--json` текстом и, если версия протокола позволяет, объектом. */\nexport function toolResult(output: CliOutput, structured: boolean): McpToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify(output) }],\n ...(structured ? { structuredContent: output } : {}),\n ...(output.ok ? {} : { isError: true as const }),\n };\n}\n","import { HOST_CONTRACT_VERSION } from '../contract/contract.const.ts';\nimport { formatVersion } from '../contract/contract.lib.ts';\nimport { redactSecretText } from '../kernel/redact.lib.ts';\nimport { resolveJsonArguments } from './args.lib.ts';\nimport { failureEnvelope, internalError, interruptedError, successEnvelope } from './envelope.lib.ts';\nimport {\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_INVALID_REQUEST,\n JSONRPC_METHOD_NOT_FOUND,\n JSONRPC_PARSE_ERROR,\n MCP_EOF_GRACE_MS,\n MCP_INSTRUCTIONS,\n MCP_MAX_LINE_BYTES,\n MCP_PROGRESS_INTERVAL_MS,\n MCP_PROTOCOL_VERSIONS,\n MCP_SERVER_NAME,\n MCP_SERVER_TITLE,\n MCP_STRUCTURED_SINCE,\n} from './mcp.const.ts';\nimport type { CliOutput } from './mcp.schema.ts';\nimport { cancelledParamsSchema, initializeParamsSchema, jsonRpcMessageSchema, toolsCallParamsSchema } from './mcp.schema.ts';\nimport type { JsonRpcId, ToolsCallParams } from './mcp.schema.ts';\nimport type { CliIo, CommandSpec, GlobalOptions, McpServerOptions } from './mcp.types.ts';\nimport { mcpPrincipal, principalRefusal, principalText } from './principal.lib.ts';\nimport { mcpToolSpecs, toolName, toolOf, toolResult } from './tools.lib.ts';\n\n// Сервер MCP (D-279…D-290): JSON-RPC 2.0 построчно на stdio, только инструменты. Каждый вызов\n// инструмента — как отдельный вызов onreel: аргументы разбирает тот же разбор флагов, команду выполняет executeCommand\n// CLI (переданный параметром), цель и токен находятся заново на каждом вызове. stdout — только сообщения протокола.\n// Принципал сервера (агент, владелец или отказ) определяется при запуске и называется в instructions (D-289, D-290).\n// Происхождение — onreel @ b73407be076a5df73931d1340f70910ca13c908d, src/cli/mcp/server.lib.ts. Отличия: разбор\n// аргументов, ошибки и конверт — свои файлы библиотеки (args.lib.ts, envelope.lib.ts, mcp.schema.ts), маскирование\n// секретов — redactSecretText из ядра; обработчик 'mcp' runMcp не копирован — он привязан к CLI onreel,\n// библиотека отдаёт serveMcp и сборщики.\n\n/** Ошибка протокола: ответ JSON-RPC с error вместо result. */\nclass RpcError extends Error {\n readonly code: number;\n\n constructor(code: number, message: string) {\n super(message);\n this.name = 'RpcError';\n this.code = code;\n }\n}\n\n/** Ключ вызова в таблице отмены: 1 и \"1\" — разные id JSON-RPC. */\nfunction keyOf(id: JsonRpcId): string {\n return `${typeof id}:${String(id)}`;\n}\n\n/** id сообщения, если его можно прочитать, — для ответа на неверный запрос. */\nfunction readableId(message: unknown): JsonRpcId | null {\n if (typeof message !== 'object' || message === null) return null;\n const id = (message as { id?: unknown }).id;\n return typeof id === 'string' || (typeof id === 'number' && Number.isInteger(id)) ? id : null;\n}\n\n/** Причина конца чтения: конец stdin или остановка сервера (SIGINT). */\ntype ReadEnd = 'eof' | 'stop';\n\n/**\n * Строки input по `\\n` (CR в конце снимается). Строка длиннее maxBytes байт не собирается: onOverflow, и всё до\n * следующего `\\n` отбрасывается (D-288). Последняя строка без перевода строки отдаётся в конце ввода. Возвращает\n * остановку чтения.\n */\nfunction readLines(\n input: NodeJS.ReadableStream,\n maxBytes: number,\n onLine: (line: string) => void,\n onOverflow: () => void,\n onEnd: (reason: ReadEnd) => void,\n): () => void {\n let chunks: Buffer[] = [];\n let size = 0;\n let skipping = false;\n let closed = false;\n const emit = (tail: Buffer): void => {\n const line = Buffer.concat([...chunks, tail]).toString('utf8');\n chunks = [];\n size = 0;\n onLine(line.endsWith('\\r') ? line.slice(0, -1) : line);\n };\n const onData = (data: Buffer | string): void => {\n let chunk = typeof data === 'string' ? Buffer.from(data, 'utf8') : data;\n while (!closed) {\n const newline = chunk.indexOf(0x0a);\n const piece = newline === -1 ? chunk : chunk.subarray(0, newline);\n if (!skipping) {\n if (size + piece.length > maxBytes) {\n chunks = [];\n size = 0;\n skipping = true;\n onOverflow();\n } else if (newline === -1) {\n chunks.push(piece);\n size += piece.length;\n } else {\n emit(piece);\n }\n }\n if (newline === -1) return;\n skipping = false;\n chunk = chunk.subarray(newline + 1);\n }\n };\n const finish = (reason: ReadEnd): void => {\n if (closed) return;\n closed = true;\n input.off('data', onData);\n input.off('end', onInputEnd);\n input.off('close', onInputEnd);\n input.pause();\n onEnd(reason);\n };\n const onInputEnd = (): void => {\n if (closed) return;\n if (!skipping && size > 0) emit(Buffer.alloc(0));\n finish('eof');\n };\n // Ошибка чтения stdin — тот же конец ввода: за ней приходит close.\n input.on('error', () => {});\n input.on('data', onData);\n input.once('end', onInputEnd);\n input.once('close', onInputEnd);\n return () => {\n finish('stop');\n };\n}\n\nfunction negotiate(requested: string): string {\n return (MCP_PROTOCOL_VERSIONS as readonly string[]).includes(requested) ? requested : MCP_PROTOCOL_VERSIONS[0];\n}\n\n/** Цикл MCP на stdio: читает строки input, отвечает в io.stdout; конец input — дождаться начатых вызовов и выйти. */\nexport function serveMcp<S extends CommandSpec = CommandSpec>(options: McpServerOptions<S>): Promise<void> {\n const { execute, io, readOnly } = options;\n const specs = mcpToolSpecs(options.specs);\n const byName = new Map(specs.map((spec) => [toolName(spec), spec]));\n const progressIntervalMs = options.progressIntervalMs ?? MCP_PROGRESS_INTERVAL_MS;\n const principal = options.principal ?? mcpPrincipal(options.globals, io.env, undefined, options.discovery);\n const instructions = `${MCP_INSTRUCTIONS} ${principalText(principal)} Рабочий каталог сервера: ${io.cwd}; относительные пути аргументов — от него.`;\n // До initialize — последняя версия: structuredContent есть.\n let protocolVersion: string = MCP_PROTOCOL_VERSIONS[0];\n const calls = new Map<string, AbortController>();\n const running = new Set<Promise<void>>();\n\n const send = (message: Record<string, unknown>): void => {\n io.stdout(`${JSON.stringify({ jsonrpc: '2.0', ...message })}\\n`);\n };\n const sendError = (id: JsonRpcId | null, code: number, message: string): void => {\n send({ id, error: { code, message } });\n };\n\n /** Вызов инструмента: идёт параллельно с чтением следующих строк; отменённый вызов ответа не получает. */\n const callTool = async (id: JsonRpcId, spec: S, params: ToolsCallParams): Promise<void> => {\n const controller = new AbortController();\n const key = keyOf(id);\n calls.set(key, controller);\n const signal = io.signal === undefined ? controller.signal : AbortSignal.any([io.signal, controller.signal]);\n const progressToken = params._meta?.progressToken;\n let progress = 0;\n const timer =\n progressToken === undefined\n ? undefined\n : setInterval(() => {\n progress += 1;\n send({ method: 'notifications/progress', params: { progressToken, progress, message: 'Ожидание…' } });\n }, progressIntervalMs);\n timer?.unref();\n // Отменённый вызов больше не шлёт progress, даже если обработчик ещё не вернулся.\n signal.addEventListener('abort', () => clearInterval(timer), { once: true });\n let output: CliOutput;\n try {\n if (principal.kind === 'refused') throw principalRefusal(principal);\n const { values, requestId } = resolveJsonArguments(spec, params.arguments, io.env, io.cwd);\n const globals: GlobalOptions = {\n json: true,\n help: false,\n ...(options.globals.dataDir === undefined ? {} : { dataDir: options.globals.dataDir }),\n ...(requestId === undefined ? {} : { requestId }),\n };\n // Обработчик не пишет в канал протокола: его stdout — в никуда.\n const callIo: CliIo = { ...io, stdout: () => {}, signal };\n output = successEnvelope(await execute(spec, values, globals, callIo));\n } catch (cause) {\n output = failureEnvelope(signal.aborted ? interruptedError(cause) : internalError(cause));\n } finally {\n clearInterval(timer);\n if (calls.get(key) === controller) calls.delete(key);\n }\n if (signal.aborted) return;\n send({ id, result: toolResult(output, protocolVersion >= MCP_STRUCTURED_SINCE) });\n };\n\n /** Запрос с id: ответ result, ошибка протокола — RpcError; tools/call отвечает сам, когда вызов закончится. */\n const handleRequest = (id: JsonRpcId, method: string, params: unknown): void => {\n switch (method) {\n case 'initialize': {\n const parsed = initializeParamsSchema.safeParse(params);\n if (!parsed.success) throw new RpcError(JSONRPC_INVALID_PARAMS, 'Неверные параметры initialize: нужен protocolVersion.');\n protocolVersion = negotiate(parsed.data.protocolVersion);\n send({\n id,\n result: {\n protocolVersion,\n capabilities: { tools: { listChanged: false } },\n serverInfo: {\n name: MCP_SERVER_NAME,\n title: MCP_SERVER_TITLE,\n version: options.serverVersion ?? formatVersion(HOST_CONTRACT_VERSION),\n },\n instructions,\n },\n });\n return;\n }\n case 'ping':\n send({ id, result: {} });\n return;\n case 'tools/list':\n send({ id, result: { tools: specs.map((spec) => toolOf(spec, io.env, readOnly)) } });\n return;\n case 'tools/call': {\n const parsed = toolsCallParamsSchema.safeParse(params);\n if (!parsed.success) throw new RpcError(JSONRPC_INVALID_PARAMS, 'Неверные параметры tools/call: нужно имя инструмента name.');\n const spec = byName.get(parsed.data.name);\n if (spec === undefined) throw new RpcError(JSONRPC_INVALID_PARAMS, `Неизвестный инструмент ${parsed.data.name}.`);\n const call = callTool(id, spec, parsed.data).catch((cause: unknown) => {\n reportInternal(id, cause);\n });\n running.add(call);\n void call.finally(() => running.delete(call));\n return;\n }\n default:\n throw new RpcError(JSONRPC_METHOD_NOT_FOUND, `Метод не поддерживается: ${method}.`);\n }\n };\n\n /** Уведомление без id: ответа нет никогда; незнакомые уведомления пропускаются. Отмена — как SIGINT (D-285). */\n const handleNotification = (method: string, params: unknown): void => {\n if (method !== 'notifications/cancelled') return;\n const parsed = cancelledParamsSchema.safeParse(params);\n if (parsed.success) calls.get(keyOf(parsed.data.requestId))?.abort();\n };\n\n const reportInternal = (id: JsonRpcId | null, cause: unknown): void => {\n const detail = redactSecretText(cause instanceof Error ? cause.message : String(cause));\n io.stderr(`onreel orch mcp: внутренняя ошибка: ${detail}\\n`);\n sendError(id, JSONRPC_INTERNAL_ERROR, `Внутренняя ошибка сервера MCP onreel: ${detail}`);\n };\n\n const handleLine = (line: string): void => {\n if (line.trim() === '') return;\n let message: unknown;\n try {\n message = JSON.parse(line) as unknown;\n } catch {\n sendError(null, JSONRPC_PARSE_ERROR, 'Строка не JSON: сообщение JSON-RPC — один объект JSON в строке.');\n return;\n }\n if (Array.isArray(message)) {\n sendError(null, JSONRPC_INVALID_REQUEST, 'Пакеты JSON-RPC не поддерживаются: отправляйте сообщения по одному.');\n return;\n }\n const parsed = jsonRpcMessageSchema.safeParse(message);\n if (!parsed.success) {\n sendError(readableId(message), JSONRPC_INVALID_REQUEST, 'Неверное сообщение JSON-RPC 2.0.');\n return;\n }\n const { id, method, params } = parsed.data;\n if (method === undefined) {\n // Ответы клиента на запросы сервера: сервер запросов не шлёт. Без method, result и error — не сообщение JSON-RPC.\n const reply = message as Record<string, unknown>;\n if (!('result' in reply) && !('error' in reply)) {\n sendError(id ?? null, JSONRPC_INVALID_REQUEST, 'Неверное сообщение JSON-RPC 2.0: нет ни method, ни result, ни error.');\n }\n return;\n }\n if (id === undefined) {\n handleNotification(method, params);\n return;\n }\n if (id === null) {\n sendError(null, JSONRPC_INVALID_REQUEST, 'id запроса JSON-RPC — строка или целое число.');\n return;\n }\n try {\n handleRequest(id, method, params);\n } catch (cause) {\n if (cause instanceof RpcError) sendError(id, cause.code, cause.message);\n else reportInternal(id, cause);\n }\n };\n\n const maxLineBytes = options.maxLineBytes ?? MCP_MAX_LINE_BYTES;\n const eofGraceMs = options.eofGraceMs ?? MCP_EOF_GRACE_MS;\n const overflow = (): void => {\n sendError(null, JSONRPC_INVALID_REQUEST, `Строка длиннее ${String(maxLineBytes)} байт: сообщение отброшено.`);\n };\n\n return new Promise<void>((resolve) => {\n let stop = (): void => {};\n const onEnd = (reason: ReadEnd): void => {\n io.signal?.removeEventListener('abort', stop);\n // SIGINT: начатые вызовы прерываются через io.signal. Конец stdin: вызовы получают eofGraceMs, чтобы дописать\n // ответ, затем прерываются как отменённые (D-287). Прерванный вызов ответа не получает.\n const abortAll = (): void => {\n for (const controller of calls.values()) controller.abort();\n };\n const grace = reason === 'eof' && running.size > 0 ? setTimeout(abortAll, eofGraceMs) : undefined;\n void Promise.allSettled(running).then(() => {\n clearTimeout(grace);\n resolve();\n });\n };\n stop = readLines(options.input, maxLineBytes, handleLine, overflow, onEnd);\n io.signal?.addEventListener('abort', stop, { once: true });\n if (io.signal?.aborted === true) stop();\n });\n}\n"],"mappings":"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","names":["z","z","resolve"]}
@@ -52,8 +52,13 @@ export type CommandOutcome = {
52
52
  duplicate?: boolean;
53
53
  human?: string;
54
54
  };
55
- /** Исполнитель команды таблицы — executeCommand из CLI потребителя, передаётся параметром. */
56
- export type CommandExecutor = (spec: CommandSpec, values: Readonly<Record<string, unknown>>, globals: GlobalOptions, io: CliIo) => Promise<CommandOutcome>;
55
+ /**
56
+ * Исполнитель команды таблицы — executeCommand из CLI потребителя, передаётся параметром. Обобщён по типу строки
57
+ * таблицы `S`: исполнитель получает ту же строку, которую вызывающий положил в `specs`, а не библиотечный
58
+ * `CommandSpec` — иначе параметр контравариантен и исполнитель потребителя со своей более широкой строкой
59
+ * не передаётся без адаптера.
60
+ */
61
+ export type CommandExecutor<S extends CommandSpec = CommandSpec> = (spec: S, values: Readonly<Record<string, unknown>>, globals: GlobalOptions, io: CliIo) => Promise<CommandOutcome>;
57
62
  export type JsonSchema = {
58
63
  type?: 'string' | 'integer' | 'boolean' | 'array' | 'object';
59
64
  description?: string;
@@ -90,12 +95,18 @@ export type McpToolResult = {
90
95
  * путь даёт вызывающий. undefined — каталог не определён, владелец называется без пути.
91
96
  */
92
97
  export type DiscoveryProvider = (globals: GlobalOptions, env: NodeJS.ProcessEnv) => string | undefined;
93
- export type McpServerOptions = {
94
- specs: readonly CommandSpec[];
95
- execute: CommandExecutor;
98
+ /**
99
+ * Параметры сервера MCP, обобщённые по типу строки таблицы команд `S`: потребитель передаёт свою таблицу и своего
100
+ * исполнителя без адаптера — без обогащения строк полем `mutation` и без поиска своей строки по пути.
101
+ */
102
+ export type McpServerOptions<S extends CommandSpec = CommandSpec> = {
103
+ specs: readonly S[];
104
+ execute: CommandExecutor<S>;
105
+ readOnly?: (spec: S) => boolean;
96
106
  globals: GlobalOptions;
97
107
  io: CliIo;
98
108
  input: NodeJS.ReadableStream;
109
+ serverVersion?: string;
99
110
  progressIntervalMs?: number;
100
111
  maxLineBytes?: number;
101
112
  eofGraceMs?: number;
@@ -1,3 +1,3 @@
1
- import type { McpServerOptions } from './mcp.types.ts';
1
+ import type { CommandSpec, McpServerOptions } from './mcp.types.ts';
2
2
  /** Цикл MCP на stdio: читает строки input, отвечает в io.stdout; конец input — дождаться начатых вызовов и выйти. */
3
- export declare function serveMcp(options: McpServerOptions): Promise<void>;
3
+ export declare function serveMcp<S extends CommandSpec = CommandSpec>(options: McpServerOptions<S>): Promise<void>;
@@ -2,15 +2,15 @@ import type { CliOutput } from './mcp.schema.ts';
2
2
  import type { CommandSpec, McpInputSchema, McpTool, McpToolResult } from './mcp.types.ts';
3
3
  /** Имя инструмента: путь команды через `_` (orch_task_create). */
4
4
  export declare function toolName(spec: CommandSpec): string;
5
- /** Команды-инструменты: переданная таблица без самой команды сервера (`orch mcp`). */
6
- export declare function mcpToolSpecs(specs: readonly CommandSpec[]): CommandSpec[];
5
+ /** Команды-инструменты: переданная таблица без самой команды сервера (`orch mcp`); тип строки таблицы сохраняется. */
6
+ export declare function mcpToolSpecs<S extends CommandSpec>(specs: readonly S[]): S[];
7
7
  /** Входная схема инструмента; обязательность — по env сервера, как проверка обязательных флагов CLI. */
8
8
  export declare function inputSchemaOf(spec: CommandSpec, env: NodeJS.ProcessEnv): McpInputSchema;
9
9
  /**
10
- * Инструмент MCP строки таблицы; readOnlyHint — по флагу мутации глагола контракта, локальная команда — только чтение.
11
- * Префикс `onreel` в title и description — текст скопированный из onreel дословно: таблица команд у вызывающего своя,
12
- * и сервер MCP отвечает на протокол от имени этого CLI.
10
+ * Инструмент MCP строки таблицы; readOnlyHint — из хука `readOnly` вызывающего, а без него по флагу мутации глагола
11
+ * контракта (локальная команда — только чтение). Префикс `onreel` в title и description — текст скопированный из
12
+ * onreel дословно: таблица команд у вызывающего своя, и сервер MCP отвечает на протокол от имени этого CLI.
13
13
  */
14
- export declare function toolOf(spec: CommandSpec, env: NodeJS.ProcessEnv): McpTool;
14
+ export declare function toolOf<S extends CommandSpec>(spec: S, env: NodeJS.ProcessEnv, readOnly?: (spec: S) => boolean): McpTool;
15
15
  /** Результат вызова инструмента: конверт `--json` текстом и, если версия протокола позволяет, объектом. */
16
16
  export declare function toolResult(output: CliOutput, structured: boolean): McpToolResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smwb/onreel-git-mcp",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Библиотека модулей, выделенных из onreel: git-операции и безопасные пути, список файлов worktree, жизненный цикл worktree против порта WorktreeStore, адаптеры трекеров GitHub/GitLab/Jira/SourceCraft/локального и MCP-сервер на stdio",
5
5
  "keywords": [
6
6
  "git",