@trigguard/mcp-server 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.
- package/README.md +66 -0
- package/assets/policy-metadata.json +84 -0
- package/dist/gatewayRegistry.d.ts +10 -0
- package/dist/gatewayRegistry.d.ts.map +1 -0
- package/dist/gatewayRegistry.js +18 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/policyMetadata.d.ts +17 -0
- package/dist/policyMetadata.d.ts.map +1 -0
- package/dist/policyMetadata.js +57 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +57 -0
- package/dist/tools.d.ts +48 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +66 -0
- package/mcp-tools-metadata.json +76 -0
- package/package.json +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# @trigguard/mcp-server
|
|
2
|
+
|
|
3
|
+
Production-grade **stdio MCP server** for TrigGuard authority.
|
|
4
|
+
|
|
5
|
+
Transport only — all decisions flow through:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
MCP tool → @trigguard/agent-sdk → POST /v1/execute
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Decision model:** PERMIT · DENY · SILENCE (no ESCALATE wire state)
|
|
12
|
+
|
|
13
|
+
## Install (npm)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g @trigguard/mcp-server
|
|
17
|
+
export TRIGGUARD_API_KEY=tg_live_…
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Full setup: [MCP npm quickstart](../../docs/adoption/MCP_NPM_QUICKSTART.md)
|
|
21
|
+
|
|
22
|
+
## Tools
|
|
23
|
+
|
|
24
|
+
| Tool | Purpose |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `authorize_action` | Governed PERMIT / DENY / SILENCE |
|
|
27
|
+
| `verify_receipt` | Lookup execution by id |
|
|
28
|
+
| `get_surface` | Surface registry metadata via gateway (read-only) |
|
|
29
|
+
| `get_policy` | Bundled policy metadata (read-only, no evaluation) |
|
|
30
|
+
|
|
31
|
+
## Cursor / Claude configuration
|
|
32
|
+
|
|
33
|
+
Use the `trigguard-mcp-server` binary:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"mcpServers": {
|
|
38
|
+
"trigguard": {
|
|
39
|
+
"command": "trigguard-mcp-server",
|
|
40
|
+
"env": {
|
|
41
|
+
"TRIGGUARD_GATEWAY_URL": "https://api.trigguardai.com",
|
|
42
|
+
"TRIGGUARD_API_KEY": "${env:TRIGGUARD_API_KEY}"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Environment
|
|
50
|
+
|
|
51
|
+
| Variable | Purpose |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `TRIGGUARD_GATEWAY_URL` | Gateway base URL (default: `https://api.trigguardai.com`) |
|
|
54
|
+
| `TRIGGUARD_API_KEY` | API key (`tg_live_…`) — required for `authorize_action` |
|
|
55
|
+
| `TRIGGUARD_MCP_ACTOR_ID` | Actor id for authorize calls (default: `trigguard-mcp-server`) |
|
|
56
|
+
| `TRIGGUARD_SURFACE_REGISTRY_PATH` | Optional local registry override (dev only) |
|
|
57
|
+
| `TRIGGUARD_POLICY_BUNDLE_PATH` | Optional local policy metadata override (dev only) |
|
|
58
|
+
|
|
59
|
+
Credentials stay in the MCP server process — never in LLM context.
|
|
60
|
+
|
|
61
|
+
## Monorepo development
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npm run build -w @trigguard/mcp-server
|
|
65
|
+
TRIGGUARD_API_KEY=tg_live_… npm run start -w @trigguard/mcp-server
|
|
66
|
+
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"bundle_id": "tg-staging",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"created_at": "2026-05-31",
|
|
5
|
+
"note": "Read-only policy metadata for MCP get_policy. Not an authority evaluation. Production decisions come from POST /v1/execute.",
|
|
6
|
+
"policies": [
|
|
7
|
+
{
|
|
8
|
+
"id": "deploy-main",
|
|
9
|
+
"surface": "deploy.release",
|
|
10
|
+
"conditions": [
|
|
11
|
+
{
|
|
12
|
+
"field": "repository",
|
|
13
|
+
"operator": "in",
|
|
14
|
+
"value": ["TrigGuard-AI/TrigGuard", "TrigGuard-AI/trigguard-example-deploy"]
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"decision": "PERMIT",
|
|
18
|
+
"reason": "AUTHORIZED_REPOSITORY_DEPLOY"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "pr-docs-permit",
|
|
22
|
+
"surface": "pr.docs.write",
|
|
23
|
+
"conditions": [],
|
|
24
|
+
"decision": "PERMIT",
|
|
25
|
+
"reason": "PR_DOCS_WRITE_PERMIT"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "pr-tests-permit",
|
|
29
|
+
"surface": "pr.tests.write",
|
|
30
|
+
"conditions": [],
|
|
31
|
+
"decision": "PERMIT",
|
|
32
|
+
"reason": "PR_TESTS_WRITE_PERMIT"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "pr-examples-permit",
|
|
36
|
+
"surface": "pr.examples.write",
|
|
37
|
+
"conditions": [],
|
|
38
|
+
"decision": "PERMIT",
|
|
39
|
+
"reason": "PR_EXAMPLES_WRITE_PERMIT"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "pr-scripts-review",
|
|
43
|
+
"surface": "pr.scripts.write",
|
|
44
|
+
"conditions": [],
|
|
45
|
+
"decision": "SILENCE",
|
|
46
|
+
"reason": "PR_SCRIPTS_WRITE_REVIEW"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "pr-workflows-review",
|
|
50
|
+
"surface": "pr.workflows.write",
|
|
51
|
+
"conditions": [],
|
|
52
|
+
"decision": "SILENCE",
|
|
53
|
+
"reason": "PR_WORKFLOWS_WRITE_REVIEW"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "pr-governance-review",
|
|
57
|
+
"surface": "pr.governance.write",
|
|
58
|
+
"conditions": [],
|
|
59
|
+
"decision": "SILENCE",
|
|
60
|
+
"reason": "PR_GOVERNANCE_WRITE_REVIEW"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "pr-mixed-review",
|
|
64
|
+
"surface": "pr.mixed.write",
|
|
65
|
+
"conditions": [],
|
|
66
|
+
"decision": "SILENCE",
|
|
67
|
+
"reason": "PR_MIXED_WRITE_REVIEW"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "pr-runtime-deny",
|
|
71
|
+
"surface": "pr.runtime.write",
|
|
72
|
+
"conditions": [],
|
|
73
|
+
"decision": "DENY",
|
|
74
|
+
"reason": "PR_RUNTIME_WRITE_DENIED"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "pr-kernel-deny",
|
|
78
|
+
"surface": "pr.kernel.write",
|
|
79
|
+
"conditions": [],
|
|
80
|
+
"decision": "DENY",
|
|
81
|
+
"reason": "PR_KERNEL_WRITE_DENIED"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type GatewayRegistryDocument = {
|
|
2
|
+
readonly surfaces: readonly string[];
|
|
3
|
+
readonly hash: string;
|
|
4
|
+
readonly registry_id?: string;
|
|
5
|
+
readonly version?: string;
|
|
6
|
+
};
|
|
7
|
+
export type FetchFn = typeof fetch;
|
|
8
|
+
/** GET /.well-known/trigguard/registry.json — live execution surface allowlist. */
|
|
9
|
+
export declare function fetchGatewayRegistry(gatewayUrl: string, fetchImpl?: FetchFn): Promise<GatewayRegistryDocument>;
|
|
10
|
+
//# sourceMappingURL=gatewayRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gatewayRegistry.d.ts","sourceRoot":"","sources":["../src/gatewayRegistry.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC;AAEnC,mFAAmF;AACnF,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,OAAe,GACzB,OAAO,CAAC,uBAAuB,CAAC,CAgBlC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** GET /.well-known/trigguard/registry.json — live execution surface allowlist. */
|
|
2
|
+
export async function fetchGatewayRegistry(gatewayUrl, fetchImpl = fetch) {
|
|
3
|
+
const base = gatewayUrl.replace(/\/$/, "");
|
|
4
|
+
const res = await fetchImpl(`${base}/.well-known/trigguard/registry.json`, {
|
|
5
|
+
headers: { Accept: "application/json" },
|
|
6
|
+
});
|
|
7
|
+
if (!res.ok) {
|
|
8
|
+
throw new Error(`gateway registry unavailable: HTTP ${res.status}`);
|
|
9
|
+
}
|
|
10
|
+
const body = (await res.json());
|
|
11
|
+
const surfaces = Array.isArray(body.surfaces) ? body.surfaces.map(String) : [];
|
|
12
|
+
return {
|
|
13
|
+
surfaces,
|
|
14
|
+
hash: String(body.hash ?? ""),
|
|
15
|
+
registry_id: body.registry_id ? String(body.registry_id) : undefined,
|
|
16
|
+
version: body.version ? String(body.version) : undefined,
|
|
17
|
+
};
|
|
18
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type PolicyRuleMetadata = {
|
|
2
|
+
readonly id: string;
|
|
3
|
+
readonly surface: string;
|
|
4
|
+
readonly decision: string;
|
|
5
|
+
readonly reason: string;
|
|
6
|
+
readonly conditions: ReadonlyArray<Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
export type PolicyMetadataResult = {
|
|
9
|
+
readonly bundleId: string;
|
|
10
|
+
readonly version: string;
|
|
11
|
+
readonly surface: string;
|
|
12
|
+
readonly matchingPolicies: ReadonlyArray<PolicyRuleMetadata>;
|
|
13
|
+
readonly note: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function resolvePolicyMetadataPath(): string;
|
|
16
|
+
export declare function loadPolicyMetadataForSurface(surface: string): PolicyMetadataResult;
|
|
17
|
+
//# sourceMappingURL=policyMetadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policyMetadata.d.ts","sourceRoot":"","sources":["../src/policyMetadata.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC7D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAaF,wBAAgB,yBAAyB,IAAI,MAAM,CAclD;AAYD,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,oBAAoB,CA4BlF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { matchSurface } from "@trigguard/surface-registry";
|
|
5
|
+
const PACKAGED_METADATA = join(dirname(fileURLToPath(import.meta.url)), "..", "assets", "policy-metadata.json");
|
|
6
|
+
function tryFile(p) {
|
|
7
|
+
return existsSync(p) ? p : null;
|
|
8
|
+
}
|
|
9
|
+
export function resolvePolicyMetadataPath() {
|
|
10
|
+
const fromEnv = (process.env.TRIGGUARD_POLICY_BUNDLE_PATH || "").trim();
|
|
11
|
+
if (fromEnv) {
|
|
12
|
+
const resolved = tryFile(fromEnv);
|
|
13
|
+
if (resolved)
|
|
14
|
+
return resolved;
|
|
15
|
+
throw new Error(`Policy metadata not found at ${fromEnv}. TRIGGUARD_POLICY_BUNDLE_PATH must point to a readable JSON file.`);
|
|
16
|
+
}
|
|
17
|
+
const packaged = tryFile(PACKAGED_METADATA);
|
|
18
|
+
if (packaged)
|
|
19
|
+
return packaged;
|
|
20
|
+
return PACKAGED_METADATA;
|
|
21
|
+
}
|
|
22
|
+
function loadPolicyDocument() {
|
|
23
|
+
const path = resolvePolicyMetadataPath();
|
|
24
|
+
if (!existsSync(path)) {
|
|
25
|
+
throw new Error(`Policy metadata not found at ${path}. Set TRIGGUARD_POLICY_BUNDLE_PATH to a readable JSON file.`);
|
|
26
|
+
}
|
|
27
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
28
|
+
}
|
|
29
|
+
export function loadPolicyMetadataForSurface(surface) {
|
|
30
|
+
const raw = loadPolicyDocument();
|
|
31
|
+
const bundleId = String(raw.bundle_id ?? raw.bundleId ?? "unknown");
|
|
32
|
+
const version = String(raw.version ?? "unknown");
|
|
33
|
+
const policies = Array.isArray(raw.policies) ? raw.policies : [];
|
|
34
|
+
const matchingPolicies = [];
|
|
35
|
+
for (const p of policies) {
|
|
36
|
+
if (!p || typeof p !== "object")
|
|
37
|
+
continue;
|
|
38
|
+
const rule = p;
|
|
39
|
+
const ruleSurface = String(rule.surface ?? "");
|
|
40
|
+
if (!ruleSurface || !matchSurface(ruleSurface, surface))
|
|
41
|
+
continue;
|
|
42
|
+
matchingPolicies.push({
|
|
43
|
+
id: String(rule.id ?? ""),
|
|
44
|
+
surface: ruleSurface,
|
|
45
|
+
decision: String(rule.decision ?? ""),
|
|
46
|
+
reason: String(rule.reason ?? ""),
|
|
47
|
+
conditions: Array.isArray(rule.conditions) ? rule.conditions : [],
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
bundleId,
|
|
52
|
+
version,
|
|
53
|
+
surface,
|
|
54
|
+
matchingPolicies,
|
|
55
|
+
note: "Metadata only — not an authority decision. Call authorize_action for governed evaluation.",
|
|
56
|
+
};
|
|
57
|
+
}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type McpServerConfig } from "./tools.js";
|
|
3
|
+
export declare function createTrigGuardMcpServer(config: McpServerConfig): McpServer;
|
|
4
|
+
export declare function startStdioServer(config?: McpServerConfig): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,OAAO,EAML,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAQpB,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAgE3E;AAED,wBAAsB,gBAAgB,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAK9E"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createTrigGuardAgent } from "@trigguard/agent-sdk";
|
|
4
|
+
import * as z from "zod";
|
|
5
|
+
import { handleAuthorizeAction, handleGetPolicy, handleGetSurface, handleVerifyReceipt, loadMcpServerConfig, } from "./tools.js";
|
|
6
|
+
function jsonContent(data) {
|
|
7
|
+
return {
|
|
8
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function createTrigGuardMcpServer(config) {
|
|
12
|
+
const agent = createTrigGuardAgent({
|
|
13
|
+
gatewayUrl: config.gatewayUrl,
|
|
14
|
+
apiKey: config.apiKey,
|
|
15
|
+
defaultActorId: config.defaultActorId,
|
|
16
|
+
});
|
|
17
|
+
const server = new McpServer({
|
|
18
|
+
name: "trigguard-mcp-server",
|
|
19
|
+
version: "0.1.0",
|
|
20
|
+
});
|
|
21
|
+
server.registerTool("authorize_action", {
|
|
22
|
+
description: "Request TrigGuard authority for an action. Returns PERMIT, DENY, or SILENCE with execution receipt metadata.",
|
|
23
|
+
inputSchema: {
|
|
24
|
+
surface: z.string().describe("Execution surface (e.g. deploy.release)"),
|
|
25
|
+
subject: z.string().optional().describe("Optional subject digest"),
|
|
26
|
+
context: z
|
|
27
|
+
.record(z.string(), z.unknown())
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Execution context (repository, environment, etc.)"),
|
|
30
|
+
},
|
|
31
|
+
}, async (input) => jsonContent(await handleAuthorizeAction(agent, config, input)));
|
|
32
|
+
server.registerTool("verify_receipt", {
|
|
33
|
+
description: "Verify a TrigGuard execution receipt by execution id.",
|
|
34
|
+
inputSchema: {
|
|
35
|
+
execution_id: z.string().describe("Execution id (exec_…)"),
|
|
36
|
+
},
|
|
37
|
+
}, async (input) => jsonContent(await handleVerifyReceipt(agent, input)));
|
|
38
|
+
server.registerTool("get_surface", {
|
|
39
|
+
description: "Read execution surface registry metadata (read-only, no evaluation).",
|
|
40
|
+
inputSchema: {
|
|
41
|
+
surface: z.string().describe("Surface id"),
|
|
42
|
+
},
|
|
43
|
+
}, async (input) => jsonContent(await handleGetSurface(config, input)));
|
|
44
|
+
server.registerTool("get_policy", {
|
|
45
|
+
description: "Read human-readable policy metadata for a surface from the bundled policy artifact. Does NOT evaluate policy.",
|
|
46
|
+
inputSchema: {
|
|
47
|
+
surface: z.string().describe("Surface id"),
|
|
48
|
+
},
|
|
49
|
+
}, async (input) => jsonContent(handleGetPolicy(input)));
|
|
50
|
+
return server;
|
|
51
|
+
}
|
|
52
|
+
export async function startStdioServer(config) {
|
|
53
|
+
const cfg = config ?? loadMcpServerConfig();
|
|
54
|
+
const server = createTrigGuardMcpServer(cfg);
|
|
55
|
+
const transport = new StdioServerTransport();
|
|
56
|
+
await server.connect(transport);
|
|
57
|
+
}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { TrigGuardAgent } from "@trigguard/agent-sdk";
|
|
2
|
+
import { BUILTIN_SURFACE_DEFINITIONS } from "@trigguard/surface-registry";
|
|
3
|
+
import { type FetchFn } from "./gatewayRegistry.js";
|
|
4
|
+
export type McpServerConfig = {
|
|
5
|
+
readonly gatewayUrl: string;
|
|
6
|
+
readonly apiKey?: string;
|
|
7
|
+
readonly defaultActorId: string;
|
|
8
|
+
readonly registryPath?: string;
|
|
9
|
+
readonly fetchImpl?: FetchFn;
|
|
10
|
+
};
|
|
11
|
+
export declare function loadMcpServerConfig(): McpServerConfig;
|
|
12
|
+
export type AuthorizeActionInput = {
|
|
13
|
+
readonly surface: string;
|
|
14
|
+
readonly subject?: string;
|
|
15
|
+
readonly context?: Record<string, unknown>;
|
|
16
|
+
};
|
|
17
|
+
export type AuthorizeActionOutput = {
|
|
18
|
+
readonly decision: string;
|
|
19
|
+
readonly execution_id: string | null;
|
|
20
|
+
readonly receipt_hash: string | null;
|
|
21
|
+
readonly verify_url: string | null;
|
|
22
|
+
};
|
|
23
|
+
export declare function handleAuthorizeAction(agent: TrigGuardAgent, config: McpServerConfig, input: AuthorizeActionInput): Promise<AuthorizeActionOutput>;
|
|
24
|
+
export type VerifyReceiptInput = {
|
|
25
|
+
readonly execution_id: string;
|
|
26
|
+
};
|
|
27
|
+
export type VerifyReceiptOutput = {
|
|
28
|
+
readonly valid: boolean;
|
|
29
|
+
readonly decision: string | null;
|
|
30
|
+
readonly surface: string | null;
|
|
31
|
+
};
|
|
32
|
+
export declare function handleVerifyReceipt(agent: TrigGuardAgent, input: VerifyReceiptInput): Promise<VerifyReceiptOutput>;
|
|
33
|
+
export type GetSurfaceInput = {
|
|
34
|
+
readonly surface: string;
|
|
35
|
+
};
|
|
36
|
+
export type GetSurfaceOutput = {
|
|
37
|
+
readonly surface: string;
|
|
38
|
+
readonly registered: boolean;
|
|
39
|
+
readonly metadata: (typeof BUILTIN_SURFACE_DEFINITIONS)[string] | null;
|
|
40
|
+
readonly registryHash: string;
|
|
41
|
+
readonly source: "gateway" | "local";
|
|
42
|
+
};
|
|
43
|
+
export declare function handleGetSurface(config: McpServerConfig, input: GetSurfaceInput): Promise<GetSurfaceOutput>;
|
|
44
|
+
export type GetPolicyInput = {
|
|
45
|
+
readonly surface: string;
|
|
46
|
+
};
|
|
47
|
+
export declare function handleGetPolicy(input: GetPolicyInput): import("./policyMetadata.js").PolicyMetadataResult;
|
|
48
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,2BAA2B,EAAyB,MAAM,6BAA6B,CAAC;AACjG,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG1E,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,wBAAgB,mBAAmB,IAAI,eAAe,CAUrD;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC,CAAC;AAEF,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,qBAAqB,CAAC,CAahC;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAW9B;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACvE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;CACtC,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,gBAAgB,CAAC,CA0B3B;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,sDAEpD"}
|
package/dist/tools.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { BUILTIN_SURFACE_DEFINITIONS, createSurfaceRegistry } from "@trigguard/surface-registry";
|
|
2
|
+
import { fetchGatewayRegistry } from "./gatewayRegistry.js";
|
|
3
|
+
import { loadPolicyMetadataForSurface } from "./policyMetadata.js";
|
|
4
|
+
export function loadMcpServerConfig() {
|
|
5
|
+
const gatewayUrl = process.env.TRIGGUARD_GATEWAY_URL?.trim() ||
|
|
6
|
+
process.env.TRIGGUARD_ENDPOINT?.trim() ||
|
|
7
|
+
"https://api.trigguardai.com";
|
|
8
|
+
const apiKey = process.env.TRIGGUARD_API_KEY?.trim() || undefined;
|
|
9
|
+
const defaultActorId = process.env.TRIGGUARD_MCP_ACTOR_ID?.trim() || "trigguard-mcp-server";
|
|
10
|
+
const registryPath = process.env.TRIGGUARD_SURFACE_REGISTRY_PATH?.trim() || undefined;
|
|
11
|
+
return { gatewayUrl, apiKey, defaultActorId, registryPath };
|
|
12
|
+
}
|
|
13
|
+
export async function handleAuthorizeAction(agent, config, input) {
|
|
14
|
+
const decision = await agent.authorize({
|
|
15
|
+
surface: input.surface,
|
|
16
|
+
actorId: config.defaultActorId,
|
|
17
|
+
subjectDigest: input.subject,
|
|
18
|
+
context: input.context,
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
decision: decision.label(),
|
|
22
|
+
execution_id: decision.executionId ?? null,
|
|
23
|
+
receipt_hash: decision.receipt?.receiptHash ?? null,
|
|
24
|
+
verify_url: decision.verifyUrl() ?? null,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export async function handleVerifyReceipt(agent, input) {
|
|
28
|
+
const result = await agent.verifyExecution(input.execution_id);
|
|
29
|
+
const receipt = result.receipt && typeof result.receipt === "object"
|
|
30
|
+
? result.receipt
|
|
31
|
+
: null;
|
|
32
|
+
return {
|
|
33
|
+
valid: result.valid,
|
|
34
|
+
decision: receipt ? String(receipt.decision ?? null) : null,
|
|
35
|
+
surface: receipt ? String(receipt.surface ?? null) : null,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export async function handleGetSurface(config, input) {
|
|
39
|
+
if (config.registryPath) {
|
|
40
|
+
const registry = createSurfaceRegistry({ registryPath: config.registryPath });
|
|
41
|
+
registry.load();
|
|
42
|
+
const meta = registry.getSurface(input.surface);
|
|
43
|
+
return {
|
|
44
|
+
surface: input.surface,
|
|
45
|
+
registered: Boolean(meta),
|
|
46
|
+
metadata: meta ?? null,
|
|
47
|
+
registryHash: registry.registryHash(),
|
|
48
|
+
source: "local",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const fetchImpl = config.fetchImpl ?? fetch;
|
|
52
|
+
const doc = await fetchGatewayRegistry(config.gatewayUrl, fetchImpl);
|
|
53
|
+
const meta = BUILTIN_SURFACE_DEFINITIONS[input.surface] ?? null;
|
|
54
|
+
const inAllowlist = doc.surfaces.includes(input.surface);
|
|
55
|
+
const registered = inAllowlist && Boolean(meta);
|
|
56
|
+
return {
|
|
57
|
+
surface: input.surface,
|
|
58
|
+
registered,
|
|
59
|
+
metadata: registered ? meta : null,
|
|
60
|
+
registryHash: doc.hash,
|
|
61
|
+
source: "gateway",
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export function handleGetPolicy(input) {
|
|
65
|
+
return loadPolicyMetadataForSurface(input.surface);
|
|
66
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"server": "trigguard-mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"package": "@trigguard/mcp-server",
|
|
5
|
+
"transport": "stdio",
|
|
6
|
+
"authority_path": "MCP → @trigguard/agent-sdk → POST /v1/execute",
|
|
7
|
+
"tools": [
|
|
8
|
+
{
|
|
9
|
+
"name": "authorize_action",
|
|
10
|
+
"classification": "AUTHORIZATION",
|
|
11
|
+
"mutates_reality": false,
|
|
12
|
+
"description": "Request TrigGuard authority for an action. Returns PERMIT, DENY, or SILENCE with execution receipt metadata.",
|
|
13
|
+
"parameters": {
|
|
14
|
+
"surface": { "type": "string", "required": true, "example": "deploy.release" },
|
|
15
|
+
"subject": { "type": "string", "required": false },
|
|
16
|
+
"context": { "type": "object", "required": false }
|
|
17
|
+
},
|
|
18
|
+
"returns": {
|
|
19
|
+
"decision": { "enum": ["PERMIT", "DENY", "SILENCE"] },
|
|
20
|
+
"execution_id": { "type": "string", "nullable": true },
|
|
21
|
+
"receipt_hash": { "type": "string", "nullable": true },
|
|
22
|
+
"verify_url": { "type": "string", "nullable": true }
|
|
23
|
+
},
|
|
24
|
+
"safety": "Calls production gateway. Does not execute side effects — authorization only."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "verify_receipt",
|
|
28
|
+
"classification": "VERIFICATION",
|
|
29
|
+
"mutates_reality": false,
|
|
30
|
+
"description": "Verify a TrigGuard execution receipt by execution id via gateway lookup.",
|
|
31
|
+
"parameters": {
|
|
32
|
+
"execution_id": { "type": "string", "required": true, "pattern": "^exec_" }
|
|
33
|
+
},
|
|
34
|
+
"returns": {
|
|
35
|
+
"valid": { "type": "boolean" },
|
|
36
|
+
"decision": { "type": "string", "nullable": true },
|
|
37
|
+
"surface": { "type": "string", "nullable": true }
|
|
38
|
+
},
|
|
39
|
+
"safety": "Read-only verification. No policy evaluation."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "get_surface",
|
|
43
|
+
"classification": "READ_ONLY",
|
|
44
|
+
"mutates_reality": false,
|
|
45
|
+
"description": "Read execution surface registry metadata. Does not evaluate policy.",
|
|
46
|
+
"parameters": {
|
|
47
|
+
"surface": { "type": "string", "required": true }
|
|
48
|
+
},
|
|
49
|
+
"returns": {
|
|
50
|
+
"registered": { "type": "boolean" },
|
|
51
|
+
"metadata": { "type": "object", "nullable": true },
|
|
52
|
+
"registryHash": { "type": "string" }
|
|
53
|
+
},
|
|
54
|
+
"safety": "Read-only registry lookup."
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "get_policy",
|
|
58
|
+
"classification": "READ_ONLY",
|
|
59
|
+
"mutates_reality": false,
|
|
60
|
+
"description": "Read human-readable policy metadata for a surface from bundled artifact. Does NOT evaluate policy.",
|
|
61
|
+
"parameters": {
|
|
62
|
+
"surface": { "type": "string", "required": true }
|
|
63
|
+
},
|
|
64
|
+
"returns": {
|
|
65
|
+
"surface": { "type": "string" },
|
|
66
|
+
"policyMetadata": { "type": "object", "nullable": true }
|
|
67
|
+
},
|
|
68
|
+
"safety": "Read-only metadata. No PERMIT/DENY emission."
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"classifications": {
|
|
72
|
+
"READ_ONLY": "No authority decision; safe discovery",
|
|
73
|
+
"AUTHORIZATION": "Returns PERMIT/DENY/SILENCE — call before mutating actions",
|
|
74
|
+
"VERIFICATION": "Validates existing receipt evidence"
|
|
75
|
+
}
|
|
76
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trigguard/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Production-grade TrigGuard MCP stdio server — authority via @trigguard/agent-sdk only",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"trigguard-mcp-server": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc -p tsconfig.json",
|
|
20
|
+
"start": "node dist/index.js",
|
|
21
|
+
"pretest": "npm run build",
|
|
22
|
+
"test": "node --test test/*.test.mjs",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"trigguard",
|
|
27
|
+
"mcp",
|
|
28
|
+
"authority",
|
|
29
|
+
"stdio",
|
|
30
|
+
"cursor",
|
|
31
|
+
"claude",
|
|
32
|
+
"execution-governance",
|
|
33
|
+
"ai-agents"
|
|
34
|
+
],
|
|
35
|
+
"license": "Apache-2.0",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/TrigGuard-AI/TrigGuard.git",
|
|
39
|
+
"directory": "packages/trigguard-mcp-server"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/TrigGuard-AI/TrigGuard/blob/main/docs/adoption/MCP_NPM_QUICKSTART.md",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/TrigGuard-AI/TrigGuard/issues"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.17.5",
|
|
50
|
+
"@trigguard/agent-sdk": "^0.1.0",
|
|
51
|
+
"@trigguard/surface-registry": "^0.1.0",
|
|
52
|
+
"zod": "^4.4.3"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/node": "^22.0.0",
|
|
56
|
+
"typescript": "^5.6.0"
|
|
57
|
+
},
|
|
58
|
+
"files": [
|
|
59
|
+
"dist",
|
|
60
|
+
"assets",
|
|
61
|
+
"README.md",
|
|
62
|
+
"mcp-tools-metadata.json"
|
|
63
|
+
],
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
66
|
+
}
|
|
67
|
+
}
|