@cogenta/mcp 0.1.3 → 0.3.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.
Files changed (40) hide show
  1. package/README.md +123 -0
  2. package/dist/client/sandbox.d.ts +17 -0
  3. package/dist/client/sandbox.d.ts.map +1 -0
  4. package/dist/client/sandbox.js +24 -0
  5. package/dist/client/sandbox.js.map +1 -0
  6. package/dist/client/stdio-client.d.ts +59 -2
  7. package/dist/client/stdio-client.d.ts.map +1 -1
  8. package/dist/client/stdio-client.js +201 -25
  9. package/dist/client/stdio-client.js.map +1 -1
  10. package/dist/client/types.d.ts +21 -4
  11. package/dist/client/types.d.ts.map +1 -1
  12. package/dist/client/watchdog.d.ts +41 -0
  13. package/dist/client/watchdog.d.ts.map +1 -0
  14. package/dist/client/watchdog.js +67 -0
  15. package/dist/client/watchdog.js.map +1 -0
  16. package/dist/client/wrap-tool.d.ts +20 -0
  17. package/dist/client/wrap-tool.d.ts.map +1 -1
  18. package/dist/client/wrap-tool.js +9 -2
  19. package/dist/client/wrap-tool.js.map +1 -1
  20. package/dist/index.d.ts +13 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +6 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/registry/discovery.d.ts +37 -0
  25. package/dist/registry/discovery.d.ts.map +1 -0
  26. package/dist/registry/discovery.js +68 -0
  27. package/dist/registry/discovery.js.map +1 -0
  28. package/dist/registry/store.d.ts +137 -0
  29. package/dist/registry/store.d.ts.map +1 -0
  30. package/dist/registry/store.js +272 -0
  31. package/dist/registry/store.js.map +1 -0
  32. package/dist/registry/tables.d.ts +24 -0
  33. package/dist/registry/tables.d.ts.map +1 -0
  34. package/dist/registry/tables.js +65 -0
  35. package/dist/registry/tables.js.map +1 -0
  36. package/dist/registry/tool-definitions.d.ts +53 -0
  37. package/dist/registry/tool-definitions.d.ts.map +1 -0
  38. package/dist/registry/tool-definitions.js +98 -0
  39. package/dist/registry/tool-definitions.js.map +1 -0
  40. package/package.json +3 -3
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Fiche 58 task 1bis: "Watchdog mémoire/CPU par poll du PID (pas de
3
+ * dépendance native)". A `child_process` spawned to run a third-party
4
+ * binary has no `resourceLimits` the way a `worker_threads` worker does
5
+ * (`@cogenta/plugins`'s isolation model does not apply here — see the
6
+ * fiche's "pièges connus"), and R9/R10 forbid pulling in a native addon
7
+ * (`pidusage` and friends) just to read one process's RSS/CPU. This polls
8
+ * the OS's own process inspector instead — `ps` on POSIX, PowerShell's
9
+ * `Get-Process` on Windows — both already present on every real deployment
10
+ * target, zero new dependency.
11
+ *
12
+ * This is explicitly a best-effort floor, not a guarantee: the real limit
13
+ * is host-level (a cgroup, a Windows Job Object), which this code cannot
14
+ * set up and does not pretend to (fiche's own words: "à documenter comme
15
+ * prérequis, pas une garantie du code"). `readUsage` is injectable so tests
16
+ * never depend on the real `ps`/PowerShell being present or behaving a
17
+ * particular way.
18
+ */
19
+ export interface PidUsage {
20
+ readonly rssBytes: number;
21
+ /** 0-based fraction of one core recently, e.g. 1.5 == 150% of one core. `0` when unknown (Windows falls back to memory-only). */
22
+ readonly cpuPercent: number;
23
+ }
24
+ export type ReadPidUsage = (pid: number) => Promise<PidUsage | null>;
25
+ export interface PidWatchdogOptions {
26
+ readonly pid: number;
27
+ readonly pollMs?: number;
28
+ /** `undefined` disables the memory ceiling. */
29
+ readonly maxRssBytes?: number;
30
+ /** `undefined` disables the CPU ceiling. */
31
+ readonly maxCpuPercent?: number;
32
+ readonly onExceeded: (usage: PidUsage, reason: 'memory' | 'cpu') => void;
33
+ /** Injectable for tests — defaults to the real `ps`/PowerShell probe. */
34
+ readonly readUsage?: ReadPidUsage;
35
+ }
36
+ export interface PidWatchdog {
37
+ stop(): void;
38
+ }
39
+ /** Polls one PID on an interval; fires `onExceeded` at most once (the caller is expected to kill the process and tear the watchdog down in response — this module never kills anything itself, it only observes). A process that has already exited, or a platform where the probe fails, is silently treated as "no signal" rather than a crash — this is a best-effort floor, never a hard dependency for the connection to function. */
40
+ export declare function startPidWatchdog(options: PidWatchdogOptions): PidWatchdog;
41
+ //# sourceMappingURL=watchdog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchdog.d.ts","sourceRoot":"","sources":["../../src/client/watchdog.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,iIAAiI;IACjI,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;AAwCpE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,4CAA4C;IAC5C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAA;IACxE,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,YAAY,CAAA;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,IAAI,IAAI,CAAA;CACb;AAID,2aAA2a;AAC3a,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CA6BzE"}
@@ -0,0 +1,67 @@
1
+ import { execFile } from 'node:child_process';
2
+ import process from 'node:process';
3
+ function parsePosixPs(stdout) {
4
+ const line = stdout.trim().split('\n').at(-1) ?? '';
5
+ const [rssKb, cpu] = line.trim().split(/\s+/u);
6
+ const rssBytes = Number.parseInt(rssKb ?? '', 10) * 1024;
7
+ if (!Number.isFinite(rssBytes) || rssBytes < 0)
8
+ return null;
9
+ const cpuPercent = Number.parseFloat(cpu ?? '');
10
+ return { rssBytes, cpuPercent: Number.isFinite(cpuPercent) ? cpuPercent : 0 };
11
+ }
12
+ async function readUsageViaCli(pid) {
13
+ return new Promise((resolve) => {
14
+ if (process.platform === 'win32') {
15
+ execFile('powershell', [
16
+ '-NoProfile',
17
+ '-NonInteractive',
18
+ '-Command',
19
+ `(Get-Process -Id ${pid} -ErrorAction Stop).WorkingSet64`,
20
+ ], { timeout: 5000 }, (error, stdout) => {
21
+ if (error) {
22
+ resolve(null);
23
+ return;
24
+ }
25
+ const rssBytes = Number.parseInt(stdout.trim(), 10);
26
+ resolve(Number.isFinite(rssBytes) && rssBytes >= 0 ? { rssBytes, cpuPercent: 0 } : null);
27
+ });
28
+ return;
29
+ }
30
+ execFile('ps', ['-o', 'rss=,%cpu=', '-p', String(pid)], { timeout: 5000 }, (error, stdout) => {
31
+ resolve(error ? null : parsePosixPs(stdout));
32
+ });
33
+ });
34
+ }
35
+ const DEFAULT_POLL_MS = 5000;
36
+ /** Polls one PID on an interval; fires `onExceeded` at most once (the caller is expected to kill the process and tear the watchdog down in response — this module never kills anything itself, it only observes). A process that has already exited, or a platform where the probe fails, is silently treated as "no signal" rather than a crash — this is a best-effort floor, never a hard dependency for the connection to function. */
37
+ export function startPidWatchdog(options) {
38
+ const pollMs = options.pollMs ?? DEFAULT_POLL_MS;
39
+ const readUsage = options.readUsage ?? readUsageViaCli;
40
+ let stopped = false;
41
+ let fired = false;
42
+ const timer = setInterval(() => {
43
+ if (stopped || fired)
44
+ return;
45
+ void readUsage(options.pid).then((usage) => {
46
+ if (stopped || fired || usage === null)
47
+ return;
48
+ if (options.maxRssBytes !== undefined && usage.rssBytes > options.maxRssBytes) {
49
+ fired = true;
50
+ options.onExceeded(usage, 'memory');
51
+ return;
52
+ }
53
+ if (options.maxCpuPercent !== undefined && usage.cpuPercent > options.maxCpuPercent) {
54
+ fired = true;
55
+ options.onExceeded(usage, 'cpu');
56
+ }
57
+ });
58
+ }, pollMs);
59
+ timer.unref?.();
60
+ return {
61
+ stop() {
62
+ stopped = true;
63
+ clearInterval(timer);
64
+ },
65
+ };
66
+ }
67
+ //# sourceMappingURL=watchdog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchdog.js","sourceRoot":"","sources":["../../src/client/watchdog.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,19 @@ export interface WrapMcpToolOptions<Input, Output> {
18
18
  * les outils internes": these five fields are the integrator's own
19
19
  * declaration, checked by the same runtime (registry, manifest, audit,
20
20
  * autonomy) as every other `defineTool` built in-repo.
21
+ *
22
+ * Fiche 58 task 6 settles the taxonomy: an MCP client integrator (the
23
+ * registry wiring in `../registry/`) always passes exactly one string
24
+ * here, `mcp.external:<connectionId>.<remoteName>` — one permission per
25
+ * checked remote tool, never `mcp.external.<connexion>` (rejected by the
26
+ * security review: that would grant every tool on a connection
27
+ * indifferently of its own risk, and R4 requires an outcome to declare
28
+ * its own permission, not inherit its connection's). This module itself
29
+ * does not enforce that convention — it accepts whatever `permissions`
30
+ * its caller declares, exactly like every other `defineTool` call — the
31
+ * enforcement is structural: nothing in this repository constructs a
32
+ * wrapped MCP tool except `../registry/`'s own builder, which always
33
+ * follows it.
21
34
  */
22
35
  readonly permissions: readonly string[];
23
36
  readonly sideEffects: boolean;
@@ -30,6 +43,13 @@ export interface WrapMcpToolOptions<Input, Output> {
30
43
  * tool implemented in this repository. `execute` calls the remote tool and
31
44
  * maps its MCP result back to the declared Zod `output`; a remote failure
32
45
  * (`isError: true`) becomes a thrown error, same as a local tool's.
46
+ *
47
+ * Fiche 58 task 1bis: `execute` takes `(input, ctx)` — contract C's own
48
+ * shape — and forwards `ctx.signal` to the client's per-call `callTool`, so
49
+ * the run's own cancellation (budget exceeded, kill switch, the agent loop
50
+ * itself being aborted) reaches the remote process the same way a hung
51
+ * server's own timeout does: the connection's underlying `child_process` is
52
+ * killed, not merely "stopped waiting on our end while it keeps running".
33
53
  */
34
54
  export declare function wrapMcpTool<Input, Output>(options: WrapMcpToolOptions<Input, Output>): ToolDefinition<Input, Output>;
35
55
  //# sourceMappingURL=wrap-tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-tool.d.ts","sourceRoot":"","sources":["../../src/client/wrap-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhF,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C,MAAM,WAAW,kBAAkB,CAAC,KAAK,EAAE,MAAM;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAClC;;;;;;;;OAQG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EACvC,OAAO,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,GACzC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CA+B/B"}
1
+ {"version":3,"file":"wrap-tool.d.ts","sourceRoot":"","sources":["../../src/client/wrap-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhF,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C,MAAM,WAAW,kBAAkB,CAAC,KAAK,EAAE,MAAM;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAClC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EACvC,OAAO,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,GACzC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAgC/B"}
@@ -6,6 +6,13 @@ import { CogentaError } from '@cogenta/core';
6
6
  * tool implemented in this repository. `execute` calls the remote tool and
7
7
  * maps its MCP result back to the declared Zod `output`; a remote failure
8
8
  * (`isError: true`) becomes a thrown error, same as a local tool's.
9
+ *
10
+ * Fiche 58 task 1bis: `execute` takes `(input, ctx)` — contract C's own
11
+ * shape — and forwards `ctx.signal` to the client's per-call `callTool`, so
12
+ * the run's own cancellation (budget exceeded, kill switch, the agent loop
13
+ * itself being aborted) reaches the remote process the same way a hung
14
+ * server's own timeout does: the connection's underlying `child_process` is
15
+ * killed, not merely "stopped waiting on our end while it keeps running".
9
16
  */
10
17
  export function wrapMcpTool(options) {
11
18
  return defineTool({
@@ -18,8 +25,8 @@ export function wrapMcpTool(options) {
18
25
  sideEffects: options.sideEffects,
19
26
  reversible: options.reversible,
20
27
  cost: options.cost,
21
- async execute(input) {
22
- const result = await options.client.callTool(options.remoteName, input);
28
+ async execute(input, ctx) {
29
+ const result = await options.client.callTool(options.remoteName, input, { signal: ctx.signal });
23
30
  const text = result.content.map((block) => block.text).join('\n');
24
31
  if (result.isError) {
25
32
  throw new CogentaError({
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-tool.js","sourceRoot":"","sources":["../../src/client/wrap-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsC,MAAM,iBAAiB,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AA4B5C;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,OAA0C;IAE1C,OAAO,UAAU,CAAC;QAChB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,CAAC,OAAO,CAAC,KAAK;YACjB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAC1C,OAAO,CAAC,UAAU,EAClB,KAA0C,CAC3C,CAAA;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACjE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,IAAI,YAAY,CAAC;oBACrB,IAAI,EAAE,wBAAwB;oBAC9B,OAAO,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,UAAU,oCAAoC,CAAC,CAAC,CAAC,IAAI;oBACxF,IAAI,EAAE,0EAA0E;iBACjF,CAAC,CAAA;YACJ,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAW,CAAA;YACnC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAyB,CAAA;YAClC,CAAC;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"wrap-tool.js","sourceRoot":"","sources":["../../src/client/wrap-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsC,MAAM,iBAAiB,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAyC5C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CACzB,OAA0C;IAE1C,OAAO,UAAU,CAAC;QAChB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG;YACtB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CAC1C,OAAO,CAAC,UAAU,EAClB,KAA0C,EAC1C,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CACvB,CAAA;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACjE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,IAAI,YAAY,CAAC;oBACrB,IAAI,EAAE,wBAAwB;oBAC9B,OAAO,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,UAAU,oCAAoC,CAAC,CAAC,CAAC,IAAI;oBACxF,IAAI,EAAE,0EAA0E;iBACjF,CAAC,CAAA;YACJ,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAW,CAAA;YACnC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAyB,CAAA;YAClC,CAAC;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,21 @@
1
- export type { McpStdioClientOptions } from './client/stdio-client.js';
1
+ export type { SandboxWorkDir } from './client/sandbox.js';
2
+ export { createSandboxWorkDir } from './client/sandbox.js';
3
+ export type { McpStdioClientOptions, SpawnOptionsForClient } from './client/stdio-client.js';
2
4
  export { createMcpStdioClient } from './client/stdio-client.js';
3
- export type { ChildProcessLike, McpClient, McpContentBlock, McpServerInfo, McpToolCallResult, McpToolSpec, } from './client/types.js';
5
+ export type { ChildProcessLike, McpCallOptions, McpClient, McpContentBlock, McpServerInfo, McpToolCallResult, McpToolSpec, } from './client/types.js';
6
+ export type { PidUsage, PidWatchdog, PidWatchdogOptions, ReadPidUsage } from './client/watchdog.js';
7
+ export { startPidWatchdog } from './client/watchdog.js';
4
8
  export type { WrapMcpToolOptions } from './client/wrap-tool.js';
5
9
  export { wrapMcpTool } from './client/wrap-tool.js';
6
10
  export type { JsonRpcError, JsonRpcErrorPayload, JsonRpcRequest, JsonRpcResponse, JsonRpcSuccess, } from './jsonrpc.js';
7
11
  export { JsonRpcErrorCode, jsonRpcError, jsonRpcSuccess } from './jsonrpc.js';
12
+ export type { DiscoverMcpConnectionOptions, DiscoverMcpConnectionResult, } from './registry/discovery.js';
13
+ export { discoverMcpConnection } from './registry/discovery.js';
14
+ export type { FileMcpConnectionStoreOptions, McpAuthKind, McpConnectionCreateInput, McpConnectionStatus, McpConnectionStore, McpConnectionSummary, McpConnectionUpdateInput, McpDiscoveredTool, McpDiscoveryFailure, McpDiscoveryResult, McpExposedTool, McpTransport, } from './registry/store.js';
15
+ export { createMcpConnectionStore } from './registry/store.js';
16
+ export { ensureMcpConnectionTables, MCP_CONNECTION_TABLE } from './registry/tables.js';
17
+ export type { BuildMcpToolDefinitionsOptions, McpToolDefinitionsAssembly, } from './registry/tool-definitions.js';
18
+ export { buildMcpToolDefinitions } from './registry/tool-definitions.js';
8
19
  export type { McpServer, McpServerOptions } from './server.js';
9
20
  export { createMcpServer } from './server.js';
10
21
  export type { StdioTransport, StdioTransportOptions } from './stdio-transport.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAC/D,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,WAAW,GACZ,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7E,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,YAAY,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAC/D,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,SAAS,EACT,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,WAAW,GACZ,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnG,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7E,YAAY,EACV,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,YAAY,EACV,6BAA6B,EAC7B,WAAW,EACX,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,YAAY,GACb,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AACtF,YAAY,EACV,8BAA8B,EAC9B,0BAA0B,GAC3B,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAA;AACxE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA"}
package/dist/index.js CHANGED
@@ -1,6 +1,12 @@
1
+ export { createSandboxWorkDir } from './client/sandbox.js';
1
2
  export { createMcpStdioClient } from './client/stdio-client.js';
3
+ export { startPidWatchdog } from './client/watchdog.js';
2
4
  export { wrapMcpTool } from './client/wrap-tool.js';
3
5
  export { JsonRpcErrorCode, jsonRpcError, jsonRpcSuccess } from './jsonrpc.js';
6
+ export { discoverMcpConnection } from './registry/discovery.js';
7
+ export { createMcpConnectionStore } from './registry/store.js';
8
+ export { ensureMcpConnectionTables, MCP_CONNECTION_TABLE } from './registry/tables.js';
9
+ export { buildMcpToolDefinitions } from './registry/tool-definitions.js';
4
10
  export { createMcpServer } from './server.js';
5
11
  export { serveMcpOverStdio } from './stdio-transport.js';
6
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAU/D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAQnD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAW/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAQnD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAK7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAe/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAKtF,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAA;AAExE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,37 @@
1
+ import type { Logger } from '@cogenta/core';
2
+ import { type McpStdioClientOptions } from '../client/stdio-client.js';
3
+ import type { McpConnectionSummary, McpDiscoveredTool } from './store.js';
4
+ export interface DiscoverMcpConnectionOptions {
5
+ readonly connection: McpConnectionSummary;
6
+ /** The decrypted secret for this connection, when `connection.authKind !== 'none'` — resolved by the caller (`McpConnectionStore.decryptSecret`), never by this module. */
7
+ readonly secret?: string;
8
+ readonly logger?: Logger;
9
+ readonly callTimeoutMs?: number;
10
+ /** Injectable for tests — defaults to a real spawned process (see `McpStdioClientOptions.spawnFn`). */
11
+ readonly spawnFn?: McpStdioClientOptions['spawnFn'];
12
+ }
13
+ export type DiscoverMcpConnectionResult = {
14
+ readonly status: 'ok';
15
+ readonly tools: readonly McpDiscoveredTool[];
16
+ } | {
17
+ readonly status: 'error';
18
+ readonly error: string;
19
+ };
20
+ /**
21
+ * Fiche 58 task 3's "test (`initialize` + `tools/list`)" — the one real
22
+ * network/process boundary the "MCP Clients" admin screen's "test
23
+ * connection" action crosses. Goes through the exact same sandboxed
24
+ * `createMcpStdioClient` an actual agent run later uses
25
+ * (`./tool-definitions.js`) — never a lighter, unsandboxed path just
26
+ * because this call is "only a test": a malicious `stdio` server has no
27
+ * way to tell a probe from a real call.
28
+ *
29
+ * `http` connections are stored (fiche 58 task 2's schema names both
30
+ * transports) but this module honestly refuses them — no HTTP MCP client
31
+ * exists in this repository yet (see `../index.js`'s own module comment).
32
+ * Storing the shape without silently pretending to support it is the
33
+ * documented, deliberate gap; claiming to test an HTTP connection that
34
+ * cannot actually connect would be worse than refusing outright.
35
+ */
36
+ export declare function discoverMcpConnection(options: DiscoverMcpConnectionOptions): Promise<DiscoverMcpConnectionResult>;
37
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/registry/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAE3C,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AAE5F,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEzE,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAA;IACzC,2KAA2K;IAC3K,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,uGAAuG;IACvG,QAAQ,CAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAA;CACpD;AAED,MAAM,MAAM,2BAA2B,GACnC;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAaxD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,2BAA2B,CAAC,CAyCtC"}
@@ -0,0 +1,68 @@
1
+ import { createSandboxWorkDir } from '../client/sandbox.js';
2
+ import { createMcpStdioClient } from '../client/stdio-client.js';
3
+ function envFor(connection, secret) {
4
+ const env = { ...connection.env };
5
+ if (connection.secretEnvVar !== undefined && secret !== undefined) {
6
+ env[connection.secretEnvVar] = secret;
7
+ }
8
+ return env;
9
+ }
10
+ /**
11
+ * Fiche 58 task 3's "test (`initialize` + `tools/list`)" — the one real
12
+ * network/process boundary the "MCP Clients" admin screen's "test
13
+ * connection" action crosses. Goes through the exact same sandboxed
14
+ * `createMcpStdioClient` an actual agent run later uses
15
+ * (`./tool-definitions.js`) — never a lighter, unsandboxed path just
16
+ * because this call is "only a test": a malicious `stdio` server has no
17
+ * way to tell a probe from a real call.
18
+ *
19
+ * `http` connections are stored (fiche 58 task 2's schema names both
20
+ * transports) but this module honestly refuses them — no HTTP MCP client
21
+ * exists in this repository yet (see `../index.js`'s own module comment).
22
+ * Storing the shape without silently pretending to support it is the
23
+ * documented, deliberate gap; claiming to test an HTTP connection that
24
+ * cannot actually connect would be worse than refusing outright.
25
+ */
26
+ export async function discoverMcpConnection(options) {
27
+ const { connection } = options;
28
+ if (connection.transport !== 'stdio') {
29
+ return {
30
+ status: 'error',
31
+ error: 'HTTP MCP connections are stored but not implemented yet — only "stdio" connections can be tested or used today.',
32
+ };
33
+ }
34
+ if (connection.command === undefined) {
35
+ return { status: 'error', error: 'This connection has no command configured.' };
36
+ }
37
+ const sandbox = await createSandboxWorkDir();
38
+ let client;
39
+ try {
40
+ client = createMcpStdioClient({
41
+ command: connection.command,
42
+ args: connection.args,
43
+ env: envFor(connection, options.secret),
44
+ cwd: sandbox.path,
45
+ ...(options.logger === undefined ? {} : { logger: options.logger }),
46
+ ...(options.callTimeoutMs === undefined ? {} : { callTimeoutMs: options.callTimeoutMs }),
47
+ ...(options.spawnFn === undefined ? {} : { spawnFn: options.spawnFn }),
48
+ });
49
+ await client.initialize();
50
+ const tools = await client.listTools();
51
+ return {
52
+ status: 'ok',
53
+ tools: tools.map((tool) => ({
54
+ name: tool.name,
55
+ description: tool.description,
56
+ inputSchema: tool.inputSchema,
57
+ })),
58
+ };
59
+ }
60
+ catch (error) {
61
+ return { status: 'error', error: error instanceof Error ? error.message : String(error) };
62
+ }
63
+ finally {
64
+ client?.close();
65
+ await sandbox.cleanup();
66
+ }
67
+ }
68
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/registry/discovery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,EAAE,oBAAoB,EAA8B,MAAM,2BAA2B,CAAA;AAkB5F,SAAS,MAAM,CACb,UAAgC,EAChC,MAA0B;IAE1B,MAAM,GAAG,GAA2B,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAA;IACzD,IAAI,UAAU,CAAC,YAAY,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAClE,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,MAAM,CAAA;IACvC,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAqC;IAErC,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAA;IAC9B,IAAI,UAAU,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;QACrC,OAAO;YACL,MAAM,EAAE,OAAO;YACf,KAAK,EACH,iHAAiH;SACpH,CAAA;IACH,CAAC;IACD,IAAI,UAAU,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,4CAA4C,EAAE,CAAA;IACjF,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,oBAAoB,EAAE,CAAA;IAC5C,IAAI,MAA6B,CAAA;IACjC,IAAI,CAAC;QACH,MAAM,GAAG,oBAAoB,CAAC;YAC5B,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC;YACvC,GAAG,EAAE,OAAO,CAAC,IAAI;YACjB,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YACnE,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;YACxF,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;SACvE,CAAC,CAAA;QACF,MAAM,MAAM,CAAC,UAAU,EAAE,CAAA;QACzB,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAA;QACtC,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC1B,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;IAC3F,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,KAAK,EAAE,CAAA;QACf,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;IACzB,CAAC;AACH,CAAC"}
@@ -0,0 +1,137 @@
1
+ import { type DatabaseHandle } from '@cogenta/core';
2
+ /**
3
+ * Fiche 58 task 2/3. The registry of external MCP connections this site's
4
+ * agent runtime may consume — never confused with `cogenta mcp` (the
5
+ * *server* this site exposes outward, `packages/cli/src/commands/mcp.ts`,
6
+ * unrelated code path). See `../client/stdio-client.js` for what actually
7
+ * runs when a `stdio` connection is used, and `wrap-tool.js` for how one
8
+ * exposed tool becomes a Contract C `ToolDefinition`.
9
+ */
10
+ export type McpTransport = 'stdio' | 'http';
11
+ export type McpAuthKind = 'none' | 'api_key' | 'oauth';
12
+ export type McpConnectionStatus = 'unverified' | 'ok' | 'error';
13
+ export interface McpDiscoveredTool {
14
+ readonly name: string;
15
+ readonly description: string;
16
+ readonly inputSchema: Readonly<Record<string, unknown>>;
17
+ }
18
+ /** One remote tool the admin has explicitly checked as exposable — "absent, pas refusée": a tool discovered but never listed here is never wrapped, never offered to a single agent. */
19
+ export interface McpExposedTool {
20
+ /** The tool's name on the remote server — must be present in this connection's last discovered tool list. */
21
+ readonly remoteName: string;
22
+ /** This connection's own name for it in Cogenta's tool registry — defaults to `remoteName` when not given. */
23
+ readonly localName: string;
24
+ readonly description: string;
25
+ /** Declared by the admin at exposure time, per fiche 58 task 6 — never read from the remote server, which has no way to be trusted to declare its own blast radius. */
26
+ readonly sideEffects: boolean;
27
+ readonly reversible: boolean;
28
+ readonly cost: 'low' | 'medium' | 'high';
29
+ }
30
+ export interface McpConnectionSummary {
31
+ readonly id: string;
32
+ readonly name: string;
33
+ readonly transport: McpTransport;
34
+ readonly command?: string;
35
+ readonly args: readonly string[];
36
+ readonly url?: string;
37
+ /** Explicit, non-secret environment for a `stdio` connection — see `../client/stdio-client.js`: this is exactly, and only, what the spawned process receives, never `process.env`. */
38
+ readonly env: Readonly<Record<string, string>>;
39
+ readonly authKind: McpAuthKind;
40
+ /** `true` once a secret has been saved — the secret itself is never returned here (same posture as `ProviderConfigStore.decryptKey`, R7). */
41
+ readonly hasSecret: boolean;
42
+ /** For `authKind !== 'none'` on a `stdio` connection: which environment variable receives the decrypted secret at connect time. Irrelevant otherwise. */
43
+ readonly secretEnvVar?: string;
44
+ /**
45
+ * Fiche 58 task 1bis's mandatory, honest confirmation for a `stdio`
46
+ * connection: whoever created it explicitly acknowledged that this
47
+ * binary runs with the Cogenta process's own full OS privileges,
48
+ * unsandboxed beyond `../client/stdio-client.js`'s own floor. Always
49
+ * `true` for an `http` connection (nothing is spawned).
50
+ */
51
+ readonly confirmedUnsandboxed: boolean;
52
+ readonly enabled: boolean;
53
+ readonly status: McpConnectionStatus;
54
+ readonly lastError?: string;
55
+ readonly discoveredTools: readonly McpDiscoveredTool[];
56
+ readonly lastDiscoveredAt?: string;
57
+ readonly exposedTools: readonly McpExposedTool[];
58
+ readonly createdAt: string;
59
+ readonly updatedAt: string;
60
+ }
61
+ export interface McpConnectionCreateInput {
62
+ readonly name: string;
63
+ readonly transport: McpTransport;
64
+ readonly command?: string;
65
+ readonly args?: readonly string[];
66
+ readonly url?: string;
67
+ readonly env?: Readonly<Record<string, string>>;
68
+ readonly authKind?: McpAuthKind;
69
+ readonly secret?: string;
70
+ readonly secretEnvVar?: string;
71
+ /**
72
+ * Required `true` for a `stdio` connection. This is the structural half
73
+ * of fiche 58 task 1bis's confirmation requirement — a UI can and must
74
+ * show the warning (`packages/admin/src/routes/mcp-clients.tsx`), but the
75
+ * refusal itself lives here, not only in a checkbox that markup could
76
+ * omit: `create()` throws `MCP_CONNECTION_CONFIRMATION_REQUIRED` for every
77
+ * `stdio` connection created without this being exactly `true`.
78
+ */
79
+ readonly confirmUnsandboxed?: boolean;
80
+ }
81
+ /**
82
+ * Fiche feedback: a saved connection had no way to change its own
83
+ * command/args/env/auth/secret without deleting and recreating it (losing
84
+ * its already-validated `exposedTools`) — same trap as
85
+ * `ProviderConfigStore.updateSettings` fixed for Providers. Every field is
86
+ * optional and means "leave exactly as saved" when absent; `transport` is
87
+ * deliberately not here (changing it is a different connection, not an
88
+ * edit — delete and recreate, same as a provider's id).
89
+ */
90
+ export interface McpConnectionUpdateInput {
91
+ readonly name?: string;
92
+ readonly command?: string;
93
+ readonly args?: readonly string[];
94
+ readonly url?: string;
95
+ readonly env?: Readonly<Record<string, string>>;
96
+ readonly authKind?: McpAuthKind;
97
+ /** Re-encrypts and replaces the saved secret. Ignored (never touches the saved secret) unless given — there is no way to read it back to resend unchanged. */
98
+ readonly secret?: string;
99
+ readonly secretEnvVar?: string;
100
+ }
101
+ export interface McpDiscoveryResult {
102
+ readonly status: 'ok';
103
+ readonly tools: readonly McpDiscoveredTool[];
104
+ }
105
+ export interface McpDiscoveryFailure {
106
+ readonly status: 'error';
107
+ readonly error: string;
108
+ }
109
+ export interface McpConnectionStore {
110
+ list(): Promise<readonly McpConnectionSummary[]>;
111
+ get(id: string): Promise<McpConnectionSummary | undefined>;
112
+ create(input: McpConnectionCreateInput): Promise<McpConnectionSummary>;
113
+ remove(id: string): Promise<void>;
114
+ setEnabled(id: string, enabled: boolean): Promise<McpConnectionSummary>;
115
+ /** Tri-state patch (fields absent from `patch` are left exactly as saved) for everything but `transport` and `enabled` — see `McpConnectionUpdateInput`. */
116
+ update(id: string, patch: McpConnectionUpdateInput): Promise<McpConnectionSummary>;
117
+ /** Persists the result of a real `initialize()`+`tools/list()` probe (`../discovery.js`) — never invented here. A failed discovery does not clear previously exposed tools; a connection that briefly can't be reached does not silently lose its admin's prior decisions. */
118
+ recordDiscovery(id: string, result: McpDiscoveryResult | McpDiscoveryFailure): Promise<McpConnectionSummary>;
119
+ /**
120
+ * The admin's checkbox decision (task 3) — replaces the full exposed-tool
121
+ * set for this connection. Every `remoteName` must be present in the
122
+ * connection's last discovered tool list: this is what makes "jamais un
123
+ * octroi implicite du catalogue distant entier" true structurally rather
124
+ * than by UI convention — a caller cannot expose a tool that was never
125
+ * actually seen on the wire.
126
+ */
127
+ setExposedTools(id: string, tools: readonly McpExposedTool[]): Promise<McpConnectionSummary>;
128
+ /** The one place the real secret is ever decrypted — never exposed on `McpConnectionSummary`. Throws `MCP_CONNECTION_NOT_FOUND`/`MCP_CONNECTION_AUTH_INVALID` as appropriate. */
129
+ decryptSecret(id: string): Promise<string>;
130
+ }
131
+ export interface FileMcpConnectionStoreOptions {
132
+ /** `COGENTA_AUTH_SIGNING_KEY` — the encryption key is derived from it, never stored itself (same posture as `ProviderConfigStore`, R7). */
133
+ readonly signingKey: string;
134
+ readonly now?: () => number;
135
+ }
136
+ export declare function createMcpConnectionStore(db: DatabaseHandle, options: FileMcpConnectionStoreOptions): McpConnectionStore;
137
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/registry/store.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,cAAc,EAA0B,MAAM,eAAe,CAAA;AAGzF;;;;;;;GAOG;AAEH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAA;AAC3C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;AACtD,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,IAAI,GAAG,OAAO,CAAA;AAE/D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACxD;AAED,wLAAwL;AACxL,MAAM,WAAW,cAAc;IAC7B,6GAA6G;IAC7G,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,8GAA8G;IAC9G,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,uKAAuK;IACvK,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;CACzC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,sLAAsL;IACtL,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC9C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAA;IAC9B,6IAA6I;IAC7I,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,yJAAyJ;IACzJ,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAA;IACtC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAA;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,eAAe,EAAE,SAAS,iBAAiB,EAAE,CAAA;IACtD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,cAAc,EAAE,CAAA;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CACtC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAA;IAC/B,8JAA8J;IAC9J,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAC7C;AACD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,IAAI,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC,CAAA;IAChD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAAA;IAC1D,MAAM,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACtE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACvE,4JAA4J;IAC5J,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAClF,8QAA8Q;IAC9Q,eAAe,CACb,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,kBAAkB,GAAG,mBAAmB,GAC/C,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAChC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;IAC5F,iLAAiL;IACjL,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CAC3C;AAsFD,MAAM,WAAW,6BAA6B;IAC5C,2IAA2I;IAC3I,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B;AAED,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,cAAc,EAClB,OAAO,EAAE,6BAA6B,GACrC,kBAAkB,CAyOpB"}