edgegate-mcp 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/bin/edgegate-mcp +2 -0
  4. package/bin/edgegate-mcp-install +2 -0
  5. package/dist/client.d.ts +54 -0
  6. package/dist/client.js +103 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/install.d.ts +1 -0
  9. package/dist/install.js +118 -0
  10. package/dist/install.js.map +1 -0
  11. package/dist/server.d.ts +1 -0
  12. package/dist/server.js +113 -0
  13. package/dist/server.js.map +1 -0
  14. package/dist/tools/check_status.d.ts +15 -0
  15. package/dist/tools/check_status.js +48 -0
  16. package/dist/tools/check_status.js.map +1 -0
  17. package/dist/tools/create_pipeline.d.ts +68 -0
  18. package/dist/tools/create_pipeline.js +74 -0
  19. package/dist/tools/create_pipeline.js.map +1 -0
  20. package/dist/tools/get_audit_report.d.ts +15 -0
  21. package/dist/tools/get_audit_report.js +46 -0
  22. package/dist/tools/get_audit_report.js.map +1 -0
  23. package/dist/tools/get_report.d.ts +15 -0
  24. package/dist/tools/get_report.js +53 -0
  25. package/dist/tools/get_report.js.map +1 -0
  26. package/dist/tools/run_gate.d.ts +18 -0
  27. package/dist/tools/run_gate.js +48 -0
  28. package/dist/tools/run_gate.js.map +1 -0
  29. package/dist/tools/setup_github_action.d.ts +18 -0
  30. package/dist/tools/setup_github_action.js +69 -0
  31. package/dist/tools/setup_github_action.js.map +1 -0
  32. package/dist/tools/setup_workspace.d.ts +18 -0
  33. package/dist/tools/setup_workspace.js +73 -0
  34. package/dist/tools/setup_workspace.js.map +1 -0
  35. package/dist/types.d.ts +64 -0
  36. package/dist/types.js +2 -0
  37. package/dist/types.js.map +1 -0
  38. package/dist/version.d.ts +2 -0
  39. package/dist/version.js +3 -0
  40. package/dist/version.js.map +1 -0
  41. package/package.json +49 -0
  42. package/plugin.json +26 -0
  43. package/skills/edgegate-audit.md +17 -0
  44. package/skills/edgegate-gate.md +15 -0
  45. package/skills/edgegate-init.md +35 -0
  46. package/skills/edgegate-status.md +14 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 EdgeGate
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # edgegate-mcp
2
+
3
+ MCP server for [EdgeGate](https://edgegate.frozo.ai) — set up edge-AI regression gates on Snapdragon devices directly from Claude Code, Cursor, or Claude Desktop.
4
+
5
+ ## What does it do?
6
+
7
+ EdgeGate runs AI model regression tests on real Snapdragon hardware via Qualcomm AI Hub, then produces signed evidence bundles you can attach to CI gates. This npm package exposes EdgeGate's REST API as 7 MCP tools, plus 4 bundled skills, so you can drive the whole flow from a prompt:
8
+
9
+ ```
10
+ > Use the edgegate MCP to set up a CI gate for my MobileNet ONNX model.
11
+ > Gates: inference_time_ms ≤ 10, peak_memory_mb ≤ 150.
12
+ > Devices: Galaxy S24, Galaxy S23.
13
+ ```
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ # 1. Generate an API key in the EdgeGate dashboard
19
+ # https://edgegate.frozo.ai/workspace/<id>/settings#api-keys
20
+
21
+ # 2. Run the installer (writes config for Claude Code / Cursor / Desktop)
22
+ npx edgegate-mcp-install
23
+ ```
24
+
25
+ Restart your MCP client. Done.
26
+
27
+ ## Manual config
28
+
29
+ If you'd rather edit config files yourself, the server is a standard stdio MCP. Add this to your client's config:
30
+
31
+ ### Claude Code (`~/.claude.json`)
32
+
33
+ ```json
34
+ {
35
+ "mcpServers": {
36
+ "edgegate": {
37
+ "type": "stdio",
38
+ "command": "npx",
39
+ "args": ["-y", "edgegate-mcp"],
40
+ "env": {
41
+ "EDGEGATE_API_KEY": "egk_live_...",
42
+ "EDGEGATE_API_URL": "https://edgegateapi.frozo.ai"
43
+ }
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ ### Cursor (`~/.cursor/mcp.json`)
50
+
51
+ Same shape as Claude Code without the `type` field.
52
+
53
+ ### Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS)
54
+
55
+ Same shape as Cursor.
56
+
57
+ ## Tools
58
+
59
+ See [docs/tools.md](./docs/tools.md) for the full tool reference. Quick list:
60
+
61
+ | Tool | Purpose |
62
+ |---|---|
63
+ | `edgegate_setup_workspace` | Pick / confirm the active workspace |
64
+ | `edgegate_create_pipeline` | Define a new regression pipeline |
65
+ | `edgegate_run_gate` | Trigger a run |
66
+ | `edgegate_check_status` | Poll a run for status + metrics |
67
+ | `edgegate_get_report` | List recent runs |
68
+ | `edgegate_get_audit_report` | Fetch the signed audit PDF |
69
+ | `edgegate_setup_github_action` | Generate the GitHub Actions workflow + secret commands |
70
+
71
+ ## Skills
72
+
73
+ Slash commands you can invoke directly:
74
+
75
+ - `/edgegate-init` — full onboarding flow (zero → CI gate)
76
+ - `/edgegate-gate` — trigger a run on an existing pipeline
77
+ - `/edgegate-status` — check a run's status + metrics
78
+ - `/edgegate-audit` — fetch the audit PDF for a run
79
+
80
+ ## License
81
+
82
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import("../dist/server.js");
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import("../dist/install.js");
@@ -0,0 +1,54 @@
1
+ import type { APIKeyCreateResponse, AuditReport, Pipeline, RunDetail, RunSummary, Workspace, WorkflowTemplate } from "./types.js";
2
+ export interface EdgeGateClientOptions {
3
+ apiUrl: string;
4
+ apiKey: string;
5
+ retryDelayMs?: number;
6
+ maxRetries?: number;
7
+ timeoutMs?: number;
8
+ }
9
+ export declare class EdgeGateError extends Error {
10
+ readonly status: number;
11
+ readonly detail: string;
12
+ readonly url: string;
13
+ constructor(status: number, detail: string, url: string);
14
+ }
15
+ export declare class EdgeGateClient {
16
+ private readonly apiUrl;
17
+ private readonly apiKey;
18
+ private readonly retryDelayMs;
19
+ private readonly maxRetries;
20
+ private readonly timeoutMs;
21
+ constructor(opts: EdgeGateClientOptions);
22
+ getWorkspace(workspaceId: string): Promise<Workspace>;
23
+ listWorkspaces(): Promise<Workspace[]>;
24
+ createAPIKey(workspaceId: string, body: {
25
+ name: string;
26
+ expires_at?: string;
27
+ }): Promise<APIKeyCreateResponse>;
28
+ createPipeline(workspaceId: string, body: {
29
+ name: string;
30
+ description?: string;
31
+ models: Array<{
32
+ name: string;
33
+ artifact_id: string;
34
+ }>;
35
+ devices: string[];
36
+ gates: Array<{
37
+ metric: string;
38
+ operator: string;
39
+ threshold: number;
40
+ }>;
41
+ promptpack_id?: string;
42
+ repeats?: number;
43
+ }): Promise<Pipeline>;
44
+ listPipelines(workspaceId: string): Promise<Pipeline[]>;
45
+ triggerRun(workspaceId: string, pipelineId: string, body?: {
46
+ trigger?: string;
47
+ model_artifact_id?: string;
48
+ }): Promise<RunSummary>;
49
+ getRun(workspaceId: string, runId: string): Promise<RunDetail>;
50
+ listRuns(workspaceId: string, limit?: number): Promise<RunSummary[]>;
51
+ getAuditReport(workspaceId: string, runId: string): Promise<AuditReport>;
52
+ getWorkflowTemplate(workspaceId: string): Promise<WorkflowTemplate>;
53
+ private request;
54
+ }
package/dist/client.js ADDED
@@ -0,0 +1,103 @@
1
+ import { USER_AGENT } from "./version.js";
2
+ export class EdgeGateError extends Error {
3
+ status;
4
+ detail;
5
+ url;
6
+ constructor(status, detail, url) {
7
+ super(`EdgeGate ${status} at ${url}: ${detail}`);
8
+ this.status = status;
9
+ this.detail = detail;
10
+ this.url = url;
11
+ this.name = "EdgeGateError";
12
+ }
13
+ }
14
+ export class EdgeGateClient {
15
+ apiUrl;
16
+ apiKey;
17
+ retryDelayMs;
18
+ maxRetries;
19
+ timeoutMs;
20
+ constructor(opts) {
21
+ this.apiUrl = opts.apiUrl.replace(/\/$/, "");
22
+ this.apiKey = opts.apiKey;
23
+ this.retryDelayMs = opts.retryDelayMs ?? 500;
24
+ this.maxRetries = opts.maxRetries ?? 2;
25
+ this.timeoutMs = opts.timeoutMs ?? 30_000;
26
+ }
27
+ async getWorkspace(workspaceId) {
28
+ return this.request("GET", `/v1/workspaces/${workspaceId}`);
29
+ }
30
+ async listWorkspaces() {
31
+ return this.request("GET", `/v1/workspaces`);
32
+ }
33
+ async createAPIKey(workspaceId, body) {
34
+ return this.request("POST", `/v1/workspaces/${workspaceId}/api-keys`, body);
35
+ }
36
+ async createPipeline(workspaceId, body) {
37
+ return this.request("POST", `/v1/workspaces/${workspaceId}/pipelines`, body);
38
+ }
39
+ async listPipelines(workspaceId) {
40
+ return this.request("GET", `/v1/workspaces/${workspaceId}/pipelines`);
41
+ }
42
+ async triggerRun(workspaceId, pipelineId, body = {}) {
43
+ return this.request("POST", `/v1/workspaces/${workspaceId}/pipelines/${pipelineId}/runs`, body);
44
+ }
45
+ async getRun(workspaceId, runId) {
46
+ return this.request("GET", `/v1/workspaces/${workspaceId}/runs/${runId}`);
47
+ }
48
+ async listRuns(workspaceId, limit = 20) {
49
+ return this.request("GET", `/v1/workspaces/${workspaceId}/runs?limit=${limit}`);
50
+ }
51
+ async getAuditReport(workspaceId, runId) {
52
+ return this.request("GET", `/v1/workspaces/${workspaceId}/runs/${runId}/audit-report`);
53
+ }
54
+ async getWorkflowTemplate(workspaceId) {
55
+ return this.request("GET", `/v1/workspaces/${workspaceId}/github-action/template`);
56
+ }
57
+ async request(method, path, body) {
58
+ const url = `${this.apiUrl}${path}`;
59
+ const isIdempotent = method === "GET";
60
+ const attempts = isIdempotent ? this.maxRetries + 1 : 1;
61
+ for (let attempt = 1; attempt <= attempts; attempt++) {
62
+ const headers = {
63
+ Authorization: `Bearer ${this.apiKey}`,
64
+ "User-Agent": USER_AGENT,
65
+ };
66
+ if (body !== undefined) {
67
+ headers["Content-Type"] = "application/json";
68
+ }
69
+ const resp = await fetch(url, {
70
+ method,
71
+ headers,
72
+ body: body !== undefined ? JSON.stringify(body) : undefined,
73
+ signal: AbortSignal.timeout(this.timeoutMs),
74
+ });
75
+ const text = await resp.text();
76
+ const json = text ? safeJson(text) : null;
77
+ if (resp.ok) {
78
+ return json;
79
+ }
80
+ const detail = json && typeof json === "object" && "detail" in json
81
+ ? String(json.detail)
82
+ : text || "Unknown error";
83
+ if (resp.status >= 500 && isIdempotent && attempt < attempts) {
84
+ await sleep(this.retryDelayMs);
85
+ continue;
86
+ }
87
+ throw new EdgeGateError(resp.status, detail, url);
88
+ }
89
+ throw new Error("retry loop exited unexpectedly");
90
+ }
91
+ }
92
+ function safeJson(text) {
93
+ try {
94
+ return JSON.parse(text);
95
+ }
96
+ catch {
97
+ return null;
98
+ }
99
+ }
100
+ function sleep(ms) {
101
+ return new Promise((r) => setTimeout(r, ms));
102
+ }
103
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,118 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import { homedir, platform } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+ import { createInterface } from "node:readline/promises";
6
+ import { stdin, stdout } from "node:process";
7
+ async function mergeIntoMcpServers(configPath, block) {
8
+ await mkdir(dirname(configPath), { recursive: true });
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ let existing = {};
11
+ if (existsSync(configPath)) {
12
+ try {
13
+ existing = JSON.parse(await readFile(configPath, "utf-8"));
14
+ }
15
+ catch {
16
+ existing = {};
17
+ }
18
+ }
19
+ existing.mcpServers = existing.mcpServers ?? {};
20
+ existing.mcpServers["edgegate"] = block;
21
+ await writeFile(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
22
+ }
23
+ const CLAUDE_CODE = {
24
+ name: "Claude Code",
25
+ configPath: () => join(homedir(), ".claude.json"),
26
+ detect: () => existsSync(join(homedir(), ".claude.json")),
27
+ serverBlock: (apiKey, apiUrl) => ({
28
+ type: "stdio",
29
+ command: "npx",
30
+ args: ["-y", "edgegate-mcp"],
31
+ env: { EDGEGATE_API_KEY: apiKey, EDGEGATE_API_URL: apiUrl },
32
+ }),
33
+ writeConfig: mergeIntoMcpServers,
34
+ };
35
+ const CURSOR = {
36
+ name: "Cursor",
37
+ configPath: () => join(homedir(), ".cursor", "mcp.json"),
38
+ detect: () => existsSync(join(homedir(), ".cursor")),
39
+ serverBlock: (apiKey, apiUrl) => ({
40
+ command: "npx",
41
+ args: ["-y", "edgegate-mcp"],
42
+ env: { EDGEGATE_API_KEY: apiKey, EDGEGATE_API_URL: apiUrl },
43
+ }),
44
+ writeConfig: mergeIntoMcpServers,
45
+ };
46
+ const CLAUDE_DESKTOP = {
47
+ name: "Claude Desktop",
48
+ configPath: () => {
49
+ if (platform() === "darwin") {
50
+ return join(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
51
+ }
52
+ if (platform() === "win32") {
53
+ return join(process.env.APPDATA ?? homedir(), "Claude", "claude_desktop_config.json");
54
+ }
55
+ return join(homedir(), ".config", "Claude", "claude_desktop_config.json");
56
+ },
57
+ detect: () => existsSync(CLAUDE_DESKTOP.configPath()),
58
+ serverBlock: (apiKey, apiUrl) => ({
59
+ command: "npx",
60
+ args: ["-y", "edgegate-mcp"],
61
+ env: { EDGEGATE_API_KEY: apiKey, EDGEGATE_API_URL: apiUrl },
62
+ }),
63
+ writeConfig: mergeIntoMcpServers,
64
+ };
65
+ const ALL_CLIENTS = [CLAUDE_CODE, CURSOR, CLAUDE_DESKTOP];
66
+ async function main() {
67
+ const rl = createInterface({ input: stdin, output: stdout });
68
+ console.log("EdgeGate MCP installer\n");
69
+ const detected = ALL_CLIENTS.filter((c) => c.detect());
70
+ if (detected.length === 0) {
71
+ console.log("No supported MCP clients detected. Supported: Claude Code, Cursor, Claude Desktop.\n" +
72
+ "If one IS installed, write the config manually — see " +
73
+ "https://github.com/frozo-ai/edgegate-mcp#manual-config.");
74
+ rl.close();
75
+ process.exit(1);
76
+ }
77
+ console.log("Detected MCP clients:");
78
+ for (let i = 0; i < detected.length; i++) {
79
+ console.log(` ${i + 1}. ${detected[i].name} (${detected[i].configPath()})`);
80
+ }
81
+ const pick = (await rl.question("\nWhich one(s)? (e.g. 1,2 or 'all'): ")).trim();
82
+ const chosen = pick.toLowerCase() === "all"
83
+ ? detected
84
+ : pick
85
+ .split(",")
86
+ .map((s) => Number(s.trim()) - 1)
87
+ .filter((i) => i >= 0 && i < detected.length)
88
+ .map((i) => detected[i]);
89
+ if (chosen.length === 0) {
90
+ console.log("No valid selection.");
91
+ rl.close();
92
+ process.exit(1);
93
+ }
94
+ const apiKey = (await rl.question("\nPaste your EdgeGate API key (egk_live_* or egk_test_*) — get one at\n" +
95
+ " https://edgegate.frozo.ai/workspace/<id>/settings#api-keys\n > ")).trim();
96
+ if (!apiKey.startsWith("egk_")) {
97
+ console.log("That does not look like a valid EdgeGate API key (must start with `egk_`).");
98
+ rl.close();
99
+ process.exit(1);
100
+ }
101
+ const apiUrl = (await rl.question("EdgeGate API URL [default https://edgegateapi.frozo.ai]: ")).trim() ||
102
+ "https://edgegateapi.frozo.ai";
103
+ for (const c of chosen) {
104
+ const block = c.serverBlock(apiKey, apiUrl);
105
+ await c.writeConfig(c.configPath(), block);
106
+ console.log(`✓ Wrote ${c.configPath()}`);
107
+ }
108
+ console.log("\nDone. Restart your MCP client so it picks up the new server.\n" +
109
+ "Then try a prompt like:\n" +
110
+ " > Use the edgegate MCP to list my workspaces.");
111
+ rl.close();
112
+ }
113
+ main().catch((err) => {
114
+ // eslint-disable-next-line no-console
115
+ console.error("Fatal:", err);
116
+ process.exit(1);
117
+ });
118
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
package/dist/server.js ADDED
@@ -0,0 +1,113 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
4
+ import { zodToJsonSchema } from "zod-to-json-schema";
5
+ import { EdgeGateClient } from "./client.js";
6
+ import { VERSION } from "./version.js";
7
+ import { setupWorkspaceHandler, setupWorkspaceInputSchema } from "./tools/setup_workspace.js";
8
+ import { createPipelineHandler, createPipelineInputSchema } from "./tools/create_pipeline.js";
9
+ import { runGateHandler, runGateInputSchema } from "./tools/run_gate.js";
10
+ import { checkStatusHandler, checkStatusInputSchema } from "./tools/check_status.js";
11
+ import { getReportHandler, getReportInputSchema } from "./tools/get_report.js";
12
+ import { getAuditReportHandler, getAuditReportInputSchema } from "./tools/get_audit_report.js";
13
+ import { setupGithubActionHandler, setupGithubActionInputSchema, } from "./tools/setup_github_action.js";
14
+ const TOOLS = [
15
+ {
16
+ name: "edgegate_setup_workspace",
17
+ description: "Confirm or list EdgeGate workspaces visible to the API key. Run this first " +
18
+ "in a fresh conversation to lock in which workspace_id the other tools should use.",
19
+ schema: setupWorkspaceInputSchema,
20
+ handler: setupWorkspaceHandler,
21
+ },
22
+ {
23
+ name: "edgegate_create_pipeline",
24
+ description: "Create a new EdgeGate regression pipeline. Define which model(s), which device(s), " +
25
+ "and which gates (e.g. inference_time_ms ≤ 10) the pipeline will enforce.",
26
+ schema: createPipelineInputSchema,
27
+ handler: createPipelineHandler,
28
+ },
29
+ {
30
+ name: "edgegate_run_gate",
31
+ description: "Trigger an EdgeGate run against a pipeline. Returns a run_id you can poll with " +
32
+ "edgegate_check_status.",
33
+ schema: runGateInputSchema,
34
+ handler: runGateHandler,
35
+ },
36
+ {
37
+ name: "edgegate_check_status",
38
+ description: "Get the current status of an EdgeGate run, including per-device metrics and " +
39
+ "which gates passed or failed.",
40
+ schema: checkStatusInputSchema,
41
+ handler: checkStatusHandler,
42
+ },
43
+ {
44
+ name: "edgegate_get_report",
45
+ description: "List recent EdgeGate runs in a workspace with status, duration, and trigger.",
46
+ schema: getReportInputSchema,
47
+ handler: getReportHandler,
48
+ },
49
+ {
50
+ name: "edgegate_get_audit_report",
51
+ description: "Get the signed audit report PDF URL for a completed EdgeGate run. Used for " +
52
+ "compliance records.",
53
+ schema: getAuditReportInputSchema,
54
+ handler: getAuditReportHandler,
55
+ },
56
+ {
57
+ name: "edgegate_setup_github_action",
58
+ description: "Generate the GitHub Actions workflow YAML + gh secret commands so every PR runs " +
59
+ "EdgeGate as a CI gate.",
60
+ schema: setupGithubActionInputSchema,
61
+ handler: setupGithubActionHandler,
62
+ },
63
+ ];
64
+ function getClient() {
65
+ const apiUrl = process.env.EDGEGATE_API_URL ?? "https://edgegateapi.frozo.ai";
66
+ const apiKey = process.env.EDGEGATE_API_KEY;
67
+ if (!apiKey) {
68
+ throw new Error("EDGEGATE_API_KEY is not set. Set it in your MCP client config. Generate a " +
69
+ "key at https://edgegate.frozo.ai/workspace/<id>/settings#api-keys.");
70
+ }
71
+ return new EdgeGateClient({ apiUrl, apiKey });
72
+ }
73
+ async function main() {
74
+ const server = new Server({ name: "edgegate-mcp", version: VERSION }, { capabilities: { tools: {} } });
75
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
76
+ tools: TOOLS.map((t) => ({
77
+ name: t.name,
78
+ description: t.description,
79
+ inputSchema: zodToJsonSchema(t.schema),
80
+ })),
81
+ }));
82
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
83
+ const tool = TOOLS.find((t) => t.name === req.params.name);
84
+ if (!tool) {
85
+ return {
86
+ isError: true,
87
+ content: [{ type: "text", text: `Unknown tool: ${req.params.name}` }],
88
+ };
89
+ }
90
+ const parsed = tool.schema.safeParse(req.params.arguments ?? {});
91
+ if (!parsed.success) {
92
+ return {
93
+ isError: true,
94
+ content: [
95
+ { type: "text", text: `Invalid arguments for ${tool.name}: ${parsed.error.message}` },
96
+ ],
97
+ };
98
+ }
99
+ const client = getClient();
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ return tool.handler(client, parsed.data);
102
+ });
103
+ const transport = new StdioServerTransport();
104
+ await server.connect(transport);
105
+ // eslint-disable-next-line no-console
106
+ console.error(`edgegate-mcp ${VERSION} listening on stdio`);
107
+ }
108
+ main().catch((err) => {
109
+ // eslint-disable-next-line no-console
110
+ console.error("Fatal:", err);
111
+ process.exit(1);
112
+ });
113
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ import { EdgeGateClient } from "../client.js";
3
+ import type { ToolResult } from "./setup_workspace.js";
4
+ export declare const checkStatusInputSchema: z.ZodObject<{
5
+ workspace_id: z.ZodString;
6
+ run_id: z.ZodString;
7
+ }, "strip", z.ZodTypeAny, {
8
+ workspace_id: string;
9
+ run_id: string;
10
+ }, {
11
+ workspace_id: string;
12
+ run_id: string;
13
+ }>;
14
+ export type CheckStatusInput = z.infer<typeof checkStatusInputSchema>;
15
+ export declare function checkStatusHandler(client: EdgeGateClient, input: CheckStatusInput): Promise<ToolResult>;
@@ -0,0 +1,48 @@
1
+ import { z } from "zod";
2
+ import { EdgeGateError } from "../client.js";
3
+ export const checkStatusInputSchema = z.object({
4
+ workspace_id: z.string().uuid(),
5
+ run_id: z.string().uuid(),
6
+ });
7
+ export async function checkStatusHandler(client, input) {
8
+ try {
9
+ const run = await client.getRun(input.workspace_id, input.run_id);
10
+ return { content: [{ type: "text", text: format(run) }] };
11
+ }
12
+ catch (err) {
13
+ if (err instanceof EdgeGateError) {
14
+ return {
15
+ isError: true,
16
+ content: [{ type: "text", text: `EdgeGate returned ${err.status}: ${err.detail}` }],
17
+ };
18
+ }
19
+ throw err;
20
+ }
21
+ }
22
+ function format(run) {
23
+ const badge = run.status.toUpperCase();
24
+ const lines = [
25
+ `Run **${run.id}**: ${badge}`,
26
+ `Pipeline: ${run.pipeline_id}`,
27
+ `Trigger: ${run.trigger}`,
28
+ `Started: ${run.started_at ?? "(pending)"}`,
29
+ `Completed: ${run.completed_at ?? "(in flight)"}`,
30
+ ``,
31
+ ];
32
+ for (const cell of run.cells ?? []) {
33
+ lines.push(`### Cell: ${cell.device_name}`);
34
+ for (const [m, v] of Object.entries(cell.metrics)) {
35
+ lines.push(`- ${m}: ${v}`);
36
+ }
37
+ for (const gr of cell.gate_results ?? []) {
38
+ const sym = gr.passed ? "✓" : "✗";
39
+ lines.push(` ${sym} ${gr.metric} ${gr.passed ? "≤" : ">"} ${gr.threshold} (actual ${gr.actual})`);
40
+ }
41
+ lines.push(``);
42
+ }
43
+ if (run.evidence_bundle_url) {
44
+ lines.push(`Evidence bundle: ${run.evidence_bundle_url}`);
45
+ }
46
+ return lines.join("\n");
47
+ }
48
+ //# sourceMappingURL=check_status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check_status.js","sourceRoot":"","sources":["../../src/tools/check_status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAkB,aAAa,EAAE,MAAM,cAAc,CAAC;AAI7D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;CAC1B,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAsB,EACtB,KAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;aACpF,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,GAAc;IAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,KAAK,GAAa;QACtB,SAAS,GAAG,CAAC,EAAE,OAAO,KAAK,EAAE;QAC7B,aAAa,GAAG,CAAC,WAAW,EAAE;QAC9B,YAAY,GAAG,CAAC,OAAO,EAAE;QACzB,YAAY,GAAG,CAAC,UAAU,IAAI,WAAW,EAAE;QAC3C,cAAc,GAAG,CAAC,YAAY,IAAI,aAAa,EAAE;QACjD,EAAE;KACH,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;YACzC,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,SAAS,YAAY,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;QACrG,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,GAAG,CAAC,mBAAmB,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,oBAAoB,GAAG,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}