@zeroroot-ai/gibson-mcp 0.1.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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +160 -0
  3. package/dist/ambient.d.ts +7 -0
  4. package/dist/ambient.js +18 -0
  5. package/dist/ask.d.ts +70 -0
  6. package/dist/ask.js +111 -0
  7. package/dist/build.d.ts +83 -0
  8. package/dist/build.js +209 -0
  9. package/dist/cli.d.ts +88 -0
  10. package/dist/cli.js +186 -0
  11. package/dist/config.d.ts +45 -0
  12. package/dist/config.js +54 -0
  13. package/dist/discovery.d.ts +57 -0
  14. package/dist/discovery.js +132 -0
  15. package/dist/flags.d.ts +32 -0
  16. package/dist/flags.js +85 -0
  17. package/dist/generated/tools.d.ts +15 -0
  18. package/dist/generated/tools.js +276 -0
  19. package/dist/helpers/componentize.d.ts +19 -0
  20. package/dist/helpers/componentize.js +106 -0
  21. package/dist/helpers/context.d.ts +19 -0
  22. package/dist/helpers/context.js +19 -0
  23. package/dist/helpers/coverage.d.ts +23 -0
  24. package/dist/helpers/coverage.js +119 -0
  25. package/dist/helpers/delegate.d.ts +4 -0
  26. package/dist/helpers/delegate.js +182 -0
  27. package/dist/helpers/findings.d.ts +24 -0
  28. package/dist/helpers/findings.js +118 -0
  29. package/dist/helpers/index.d.ts +17 -0
  30. package/dist/helpers/index.js +24 -0
  31. package/dist/helpers/knowledge.d.ts +16 -0
  32. package/dist/helpers/knowledge.js +161 -0
  33. package/dist/helpers/tools.d.ts +113 -0
  34. package/dist/helpers/tools.js +80 -0
  35. package/dist/http.d.ts +57 -0
  36. package/dist/http.js +137 -0
  37. package/dist/inbox.d.ts +88 -0
  38. package/dist/inbox.js +176 -0
  39. package/dist/index.d.ts +23 -0
  40. package/dist/index.js +25 -0
  41. package/dist/log.d.ts +4 -0
  42. package/dist/log.js +5 -0
  43. package/dist/main.d.ts +2 -0
  44. package/dist/main.js +61 -0
  45. package/dist/mode.d.ts +32 -0
  46. package/dist/mode.js +21 -0
  47. package/dist/registry.d.ts +83 -0
  48. package/dist/registry.js +133 -0
  49. package/dist/resources.d.ts +63 -0
  50. package/dist/resources.js +98 -0
  51. package/dist/rpc.d.ts +80 -0
  52. package/dist/rpc.js +184 -0
  53. package/dist/schema.d.ts +31 -0
  54. package/dist/schema.js +143 -0
  55. package/dist/server.d.ts +22 -0
  56. package/dist/server.js +70 -0
  57. package/dist/session.d.ts +41 -0
  58. package/dist/session.js +170 -0
  59. package/dist/source.d.ts +30 -0
  60. package/dist/source.js +23 -0
  61. package/dist/state.d.ts +29 -0
  62. package/dist/state.js +37 -0
  63. package/dist/tls.d.ts +1 -0
  64. package/dist/tls.js +19 -0
  65. package/dist/tool.d.ts +17 -0
  66. package/dist/tool.js +22 -0
  67. package/dist/tools/connect.d.ts +24 -0
  68. package/dist/tools/connect.js +115 -0
  69. package/dist/tools/result.d.ts +7 -0
  70. package/dist/tools/result.js +16 -0
  71. package/dist/tools/status.d.ts +5 -0
  72. package/dist/tools/status.js +36 -0
  73. package/dist/turn.d.ts +75 -0
  74. package/dist/turn.js +95 -0
  75. package/package.json +58 -0
@@ -0,0 +1,36 @@
1
+ import { defineTool } from "../tool.js";
2
+ import { text } from "./result.js";
3
+ /** One tool that says how this session is connected to Gibson and why. */
4
+ export function statusTool(current) {
5
+ return defineTool({
6
+ name: "gibson_status",
7
+ description: "Show how this session is connected to Gibson: the check-in source (dispatched grant, bootstrap token, " +
8
+ "enrolled host key, or none), the posture (standalone, component, live, task), the platform, tenant, " +
9
+ "target, mission and run ids, and what is missing if anything.",
10
+ input: {},
11
+ annotations: { readOnlyHint: true },
12
+ handler: async () => text("", describeGibson(current())),
13
+ });
14
+ }
15
+ export function describeGibson(g) {
16
+ const lines = [`source: ${g.source}`, `posture: ${g.mode}`, `agent: ${g.agentName}`];
17
+ if (g.settings.platformURL)
18
+ lines.push(`platform: ${g.settings.platformURL}`);
19
+ if (g.settings.tenant)
20
+ lines.push(`tenant: ${g.settings.tenant}`);
21
+ if (g.settings.targetId)
22
+ lines.push(`target: ${g.settings.targetId}`);
23
+ if (g.session)
24
+ lines.push(`component_scope: ${g.session.componentScope}`, `instance: ${g.session.instance.current()}`);
25
+ if (g.live) {
26
+ lines.push(`mission: ${g.live.missionId}`);
27
+ if (g.runId)
28
+ lines.push(`run: ${g.runId}`);
29
+ lines.push(`work: ${g.live.workId}`);
30
+ const exp = g.live.harness.expiresAt();
31
+ lines.push(`grant expires: ${exp && Number.isFinite(exp) ? new Date(exp).toISOString() : "unknown"}`);
32
+ }
33
+ if (g.reason)
34
+ lines.push(`note: ${g.reason}`);
35
+ return lines.join("\n");
36
+ }
package/dist/turn.d.ts ADDED
@@ -0,0 +1,75 @@
1
+ import type { Transport } from "@connectrpc/connect";
2
+ import { type TaskHarness } from "@zeroroot-ai/sdk";
3
+ import { type Log } from "./log.js";
4
+ /**
5
+ * Per-turn grants (gibson#1706, decision 14).
6
+ *
7
+ * A member sandbox is long-lived: one Claude Code process serves many
8
+ * dispatches over its life, and each input message carries the task grant of
9
+ * its own dispatch. Every tool call made while working that message must run
10
+ * under that grant, not under the grant the sandbox started with. A stdio
11
+ * server the host spawns cannot do this, which is why the sandbox runs the
12
+ * HTTP transport.
13
+ *
14
+ * Two credentials, and they never mix:
15
+ *
16
+ * - the **base grant**, from the launch. It is the member's own identity
17
+ * and it is used for the lifetime RPCs only: the inbox subscription,
18
+ * reading repository credentials, and the checkpoint writes.
19
+ * - the **turn grant**, set by the driver before it feeds Claude a message.
20
+ * Every tool call in that turn uses it.
21
+ *
22
+ * The turn is set two ways. `POST /turn` sets it for everything that
23
+ * follows, which is what the driver does between turns. A single request may
24
+ * also carry `x-gibson-turn-grant`, which applies to that request alone;
25
+ * that is how a driver runs two turns at once without one turn's grant
26
+ * leaking into the other. The per-request header wins.
27
+ *
28
+ * Between turns there is no turn grant, and a tool call falls back to the
29
+ * base grant. That is deliberate: the alternative is holding the last turn's
30
+ * grant after its dispatch is over, which would attribute work to a job that
31
+ * has already been answered.
32
+ */
33
+ export declare const TURN_GRANT_HEADER = "x-gibson-turn-grant";
34
+ export interface Turn {
35
+ jobId: string;
36
+ grant: string;
37
+ /** The callback endpoint this turn's grant is good for. */
38
+ endpoint: string;
39
+ /** Dial the endpoint without TLS. Local daemons only. */
40
+ insecure: boolean;
41
+ }
42
+ export interface TurnControllerOptions {
43
+ /** The harness the launch opened. Its grant and endpoint are the base. */
44
+ base: TaskHarness;
45
+ insecure?: boolean;
46
+ log?: Log;
47
+ /** Test seam: build a transport for an endpoint and a grant source. */
48
+ makeTransport?: (baseUrl: string, token: () => string) => Transport;
49
+ }
50
+ export interface TurnController {
51
+ /** The turn in force right now, if any. */
52
+ current(): Turn | undefined;
53
+ /** Set the turn every later call runs under, until it is cleared. */
54
+ set(turn: Turn): void;
55
+ /** Drop the turn. Later calls fall back to the base grant. */
56
+ clear(): void;
57
+ /** Run `fn` under one grant, for this request only. */
58
+ withGrant<T>(grant: string | undefined, fn: () => T): T;
59
+ /** The grant a call made right here would carry. */
60
+ activeGrant(): string;
61
+ /**
62
+ * The transport for tool calls. One object for the life of the process:
63
+ * the clients are built once, and the swap happens inside.
64
+ */
65
+ transport(): Transport;
66
+ /** The base transport, for the lifetime RPCs. Never swapped. */
67
+ lifetimeTransport(): Transport;
68
+ close(): void;
69
+ }
70
+ /**
71
+ * A transport that resolves its target at call time, so a client built once
72
+ * keeps working across a grant swap and an endpoint change.
73
+ */
74
+ export declare function dynamicTransport(pick: () => Transport): Transport;
75
+ export declare function createTurnController(opts: TurnControllerOptions): TurnController;
package/dist/turn.js ADDED
@@ -0,0 +1,95 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { createGrpcTransport } from "@connectrpc/connect-node";
3
+ import { callbackBaseUrl, grantInterceptor } from "@zeroroot-ai/sdk";
4
+ import { TAG } from "./log.js";
5
+ /**
6
+ * Per-turn grants (gibson#1706, decision 14).
7
+ *
8
+ * A member sandbox is long-lived: one Claude Code process serves many
9
+ * dispatches over its life, and each input message carries the task grant of
10
+ * its own dispatch. Every tool call made while working that message must run
11
+ * under that grant, not under the grant the sandbox started with. A stdio
12
+ * server the host spawns cannot do this, which is why the sandbox runs the
13
+ * HTTP transport.
14
+ *
15
+ * Two credentials, and they never mix:
16
+ *
17
+ * - the **base grant**, from the launch. It is the member's own identity
18
+ * and it is used for the lifetime RPCs only: the inbox subscription,
19
+ * reading repository credentials, and the checkpoint writes.
20
+ * - the **turn grant**, set by the driver before it feeds Claude a message.
21
+ * Every tool call in that turn uses it.
22
+ *
23
+ * The turn is set two ways. `POST /turn` sets it for everything that
24
+ * follows, which is what the driver does between turns. A single request may
25
+ * also carry `x-gibson-turn-grant`, which applies to that request alone;
26
+ * that is how a driver runs two turns at once without one turn's grant
27
+ * leaking into the other. The per-request header wins.
28
+ *
29
+ * Between turns there is no turn grant, and a tool call falls back to the
30
+ * base grant. That is deliberate: the alternative is holding the last turn's
31
+ * grant after its dispatch is over, which would attribute work to a job that
32
+ * has already been answered.
33
+ */
34
+ export const TURN_GRANT_HEADER = "x-gibson-turn-grant";
35
+ /**
36
+ * A transport that resolves its target at call time, so a client built once
37
+ * keeps working across a grant swap and an endpoint change.
38
+ */
39
+ export function dynamicTransport(pick) {
40
+ return {
41
+ unary: (method, signal, timeoutMs, header, input, contextValues) => pick().unary(method, signal, timeoutMs, header, input, contextValues),
42
+ stream: (method, signal, timeoutMs, header, input, contextValues) => pick().stream(method, signal, timeoutMs, header, input, contextValues),
43
+ };
44
+ }
45
+ export function createTurnController(opts) {
46
+ const { base } = opts;
47
+ const insecure = opts.insecure ?? false;
48
+ const perRequest = new AsyncLocalStorage();
49
+ const make = opts.makeTransport ?? ((baseUrl, token) => createGrpcTransport({ baseUrl, interceptors: [grantInterceptor(token)] }));
50
+ let turn;
51
+ // One transport per endpoint. A turn usually reuses the member's own
52
+ // callback endpoint, so this is one entry in practice; a driver that
53
+ // points a turn somewhere else gets a second rather than a rebuild per
54
+ // turn.
55
+ const byEndpoint = new Map();
56
+ const activeGrant = () => perRequest.getStore() ?? turn?.grant ?? base.token();
57
+ const transportFor = (endpoint, endpointInsecure) => {
58
+ const baseUrl = callbackBaseUrl(endpoint, endpointInsecure);
59
+ const existing = byEndpoint.get(baseUrl);
60
+ if (existing)
61
+ return existing;
62
+ const built = make(baseUrl, activeGrant);
63
+ byEndpoint.set(baseUrl, built);
64
+ return built;
65
+ };
66
+ const pick = () => {
67
+ const t = turn;
68
+ // The base harness already carries the base grant, so between turns the
69
+ // call goes over the transport the launch opened.
70
+ if (!t && !perRequest.getStore())
71
+ return base.transport;
72
+ return transportFor(t?.endpoint || base.endpoint, t ? t.insecure : insecure);
73
+ };
74
+ const tools = dynamicTransport(pick);
75
+ return {
76
+ current: () => turn,
77
+ set: (next) => {
78
+ turn = next;
79
+ opts.log?.(`${TAG} turn ${next.jobId}: tool calls now run under that dispatch's grant`);
80
+ },
81
+ clear: () => {
82
+ if (turn)
83
+ opts.log?.(`${TAG} turn ${turn.jobId} ended; tool calls fall back to the base grant`);
84
+ turn = undefined;
85
+ },
86
+ withGrant: (grant, fn) => (grant ? perRequest.run(grant, fn) : fn()),
87
+ activeGrant,
88
+ transport: () => tools,
89
+ lifetimeTransport: () => base.transport,
90
+ close: () => {
91
+ turn = undefined;
92
+ byEndpoint.clear();
93
+ },
94
+ };
95
+ }
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@zeroroot-ai/gibson-mcp",
3
+ "version": "0.1.0",
4
+ "description": "The Gibson MCP server: one tool surface for every coding agent host. Every RPC of every SDK service, every SDK helper and every checked-in platform tool, over stdio or streamable HTTP on localhost.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/zeroroot-ai/sdk-ts.git",
9
+ "directory": "packages/gibson-mcp"
10
+ },
11
+ "homepage": "https://github.com/zeroroot-ai/sdk-ts",
12
+ "bugs": "https://github.com/zeroroot-ai/sdk-ts/issues",
13
+ "type": "module",
14
+ "main": "dist/index.js",
15
+ "types": "dist/index.d.ts",
16
+ "bin": {
17
+ "gibson-mcp": "dist/main.js"
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "scripts": {
23
+ "generate": "node scripts/generate-tools.ts",
24
+ "build": "tsc -p tsconfig.json",
25
+ "typecheck": "tsc -p tsconfig.json --noEmit",
26
+ "test": "sh -c 'tsc -p tsconfig.test.json && node --test \"dist-test/**/*.test.js\"' swallow-forwarded-vitest-args"
27
+ },
28
+ "dependencies": {
29
+ "@bufbuild/protobuf": "^2.2.0",
30
+ "@connectrpc/connect": "^2.0.0",
31
+ "@connectrpc/connect-node": "^2.0.0",
32
+ "@modelcontextprotocol/sdk": "^1.30.0",
33
+ "@zeroroot-ai/sdk": "workspace:^",
34
+ "zod": "^4.4.3"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.0.0",
38
+ "typescript": "^5.6.0"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "exports": {
44
+ ".": {
45
+ "types": "./dist/index.d.ts",
46
+ "import": "./dist/index.js"
47
+ }
48
+ },
49
+ "keywords": [
50
+ "gibson",
51
+ "mcp",
52
+ "model-context-protocol",
53
+ "claude-code",
54
+ "opencode",
55
+ "security",
56
+ "knowledge-graph"
57
+ ]
58
+ }