@det-acp/core 0.2.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/LICENSE +21 -0
- package/README.md +492 -0
- package/dist/cli/index.d.ts +15 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +308 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +32 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +234 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/templates.d.ts +27 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +266 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/engine/action-registry.d.ts +49 -0
- package/dist/engine/action-registry.d.ts.map +1 -0
- package/dist/engine/action-registry.js +95 -0
- package/dist/engine/action-registry.js.map +1 -0
- package/dist/engine/gate.d.ts +57 -0
- package/dist/engine/gate.d.ts.map +1 -0
- package/dist/engine/gate.js +145 -0
- package/dist/engine/gate.js.map +1 -0
- package/dist/engine/runtime.d.ts +98 -0
- package/dist/engine/runtime.d.ts.map +1 -0
- package/dist/engine/runtime.js +138 -0
- package/dist/engine/runtime.js.map +1 -0
- package/dist/engine/session.d.ts +74 -0
- package/dist/engine/session.d.ts.map +1 -0
- package/dist/engine/session.js +343 -0
- package/dist/engine/session.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/ledger/ledger.d.ts +58 -0
- package/dist/ledger/ledger.d.ts.map +1 -0
- package/dist/ledger/ledger.js +188 -0
- package/dist/ledger/ledger.js.map +1 -0
- package/dist/ledger/query.d.ts +29 -0
- package/dist/ledger/query.d.ts.map +1 -0
- package/dist/ledger/query.js +61 -0
- package/dist/ledger/query.js.map +1 -0
- package/dist/ledger/types.d.ts +27 -0
- package/dist/ledger/types.d.ts.map +1 -0
- package/dist/ledger/types.js +5 -0
- package/dist/ledger/types.js.map +1 -0
- package/dist/policy/evaluator.d.ts +21 -0
- package/dist/policy/evaluator.d.ts.map +1 -0
- package/dist/policy/evaluator.js +383 -0
- package/dist/policy/evaluator.js.map +1 -0
- package/dist/policy/loader.d.ts +27 -0
- package/dist/policy/loader.d.ts.map +1 -0
- package/dist/policy/loader.js +69 -0
- package/dist/policy/loader.js.map +1 -0
- package/dist/policy/schema.d.ts +168 -0
- package/dist/policy/schema.d.ts.map +1 -0
- package/dist/policy/schema.js +107 -0
- package/dist/policy/schema.js.map +1 -0
- package/dist/proxy/mcp-proxy.d.ts +43 -0
- package/dist/proxy/mcp-proxy.d.ts.map +1 -0
- package/dist/proxy/mcp-proxy.js +240 -0
- package/dist/proxy/mcp-proxy.js.map +1 -0
- package/dist/proxy/mcp-types.d.ts +79 -0
- package/dist/proxy/mcp-types.d.ts.map +1 -0
- package/dist/proxy/mcp-types.js +28 -0
- package/dist/proxy/mcp-types.js.map +1 -0
- package/dist/proxy/shell-proxy.d.ts +52 -0
- package/dist/proxy/shell-proxy.d.ts.map +1 -0
- package/dist/proxy/shell-proxy.js +92 -0
- package/dist/proxy/shell-proxy.js.map +1 -0
- package/dist/rollback/manager.d.ts +62 -0
- package/dist/rollback/manager.d.ts.map +1 -0
- package/dist/rollback/manager.js +151 -0
- package/dist/rollback/manager.js.map +1 -0
- package/dist/server/server.d.ts +24 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +200 -0
- package/dist/server/server.js.map +1 -0
- package/dist/tools/base.d.ts +58 -0
- package/dist/tools/base.d.ts.map +1 -0
- package/dist/tools/base.js +48 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/command-run.d.ts +30 -0
- package/dist/tools/command-run.d.ts.map +1 -0
- package/dist/tools/command-run.js +87 -0
- package/dist/tools/command-run.js.map +1 -0
- package/dist/tools/file-read.d.ts +34 -0
- package/dist/tools/file-read.d.ts.map +1 -0
- package/dist/tools/file-read.js +67 -0
- package/dist/tools/file-read.js.map +1 -0
- package/dist/tools/file-write.d.ts +39 -0
- package/dist/tools/file-write.d.ts.map +1 -0
- package/dist/tools/file-write.js +158 -0
- package/dist/tools/file-write.js.map +1 -0
- package/dist/tools/git.d.ts +48 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +193 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/http-request.d.ts +48 -0
- package/dist/tools/http-request.d.ts.map +1 -0
- package/dist/tools/http-request.js +91 -0
- package/dist/tools/http-request.js.map +1 -0
- package/dist/types.d.ts +257 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/examples/coding-agent.policy.yaml +80 -0
- package/examples/devops-deploy.policy.yaml +107 -0
- package/examples/mcp-proxy.config.yaml +34 -0
- package/examples/simple-session.ts +161 -0
- package/examples/video-upscaler.policy.yaml +86 -0
- package/package.json +92 -0
- package/schemas/generate.ts +18 -0
- package/schemas/policy.schema.json +7 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas for the Agent Policy YAML DSL.
|
|
3
|
+
*
|
|
4
|
+
* These schemas are the source of truth for policy validation.
|
|
5
|
+
* They mirror (and enforce) the types defined in ../types.ts.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
export declare const ToolNameSchema: z.ZodString;
|
|
9
|
+
export declare const ApprovalModeSchema: z.ZodEnum<{
|
|
10
|
+
auto: "auto";
|
|
11
|
+
human: "human";
|
|
12
|
+
webhook: "webhook";
|
|
13
|
+
}>;
|
|
14
|
+
export declare const RiskLevelSchema: z.ZodEnum<{
|
|
15
|
+
low: "low";
|
|
16
|
+
medium: "medium";
|
|
17
|
+
high: "high";
|
|
18
|
+
critical: "critical";
|
|
19
|
+
}>;
|
|
20
|
+
export declare const CapabilityScopeSchema: z.ZodObject<{
|
|
21
|
+
paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
22
|
+
binaries: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
23
|
+
domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
24
|
+
methods: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
25
|
+
repos: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
export declare const CapabilitySchema: z.ZodObject<{
|
|
28
|
+
tool: z.ZodString;
|
|
29
|
+
scope: z.ZodObject<{
|
|
30
|
+
paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
31
|
+
binaries: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
32
|
+
domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
33
|
+
methods: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
34
|
+
repos: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
export declare const GateSchema: z.ZodObject<{
|
|
38
|
+
action: z.ZodString;
|
|
39
|
+
approval: z.ZodEnum<{
|
|
40
|
+
auto: "auto";
|
|
41
|
+
human: "human";
|
|
42
|
+
webhook: "webhook";
|
|
43
|
+
}>;
|
|
44
|
+
risk_level: z.ZodOptional<z.ZodEnum<{
|
|
45
|
+
low: "low";
|
|
46
|
+
medium: "medium";
|
|
47
|
+
high: "high";
|
|
48
|
+
critical: "critical";
|
|
49
|
+
}>>;
|
|
50
|
+
condition: z.ZodOptional<z.ZodString>;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
export declare const LimitsSchema: z.ZodObject<{
|
|
53
|
+
max_runtime_ms: z.ZodOptional<z.ZodNumber>;
|
|
54
|
+
max_output_bytes: z.ZodOptional<z.ZodNumber>;
|
|
55
|
+
max_files_changed: z.ZodOptional<z.ZodNumber>;
|
|
56
|
+
max_retries: z.ZodOptional<z.ZodNumber>;
|
|
57
|
+
max_cost_usd: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
export declare const EvidenceConfigSchema: z.ZodObject<{
|
|
60
|
+
require: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
61
|
+
format: z.ZodDefault<z.ZodLiteral<"jsonl">>;
|
|
62
|
+
}, z.core.$strip>;
|
|
63
|
+
export declare const ForbiddenPatternSchema: z.ZodObject<{
|
|
64
|
+
pattern: z.ZodString;
|
|
65
|
+
}, z.core.$strip>;
|
|
66
|
+
export declare const RemediationRuleSchema: z.ZodObject<{
|
|
67
|
+
match: z.ZodString;
|
|
68
|
+
action: z.ZodString;
|
|
69
|
+
}, z.core.$strip>;
|
|
70
|
+
export declare const RemediationSchema: z.ZodObject<{
|
|
71
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
72
|
+
match: z.ZodString;
|
|
73
|
+
action: z.ZodString;
|
|
74
|
+
}, z.core.$strip>>>;
|
|
75
|
+
fallback_chain: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
76
|
+
}, z.core.$strip>;
|
|
77
|
+
export declare const RateLimitSchema: z.ZodObject<{
|
|
78
|
+
max_per_minute: z.ZodNumber;
|
|
79
|
+
}, z.core.$strip>;
|
|
80
|
+
export declare const EscalationRuleSchema: z.ZodObject<{
|
|
81
|
+
after_actions: z.ZodOptional<z.ZodNumber>;
|
|
82
|
+
after_minutes: z.ZodOptional<z.ZodNumber>;
|
|
83
|
+
require: z.ZodEnum<{
|
|
84
|
+
human_checkin: "human_checkin";
|
|
85
|
+
}>;
|
|
86
|
+
}, z.core.$strip>;
|
|
87
|
+
export declare const SessionConstraintsSchema: z.ZodObject<{
|
|
88
|
+
max_actions: z.ZodOptional<z.ZodNumber>;
|
|
89
|
+
max_denials: z.ZodOptional<z.ZodNumber>;
|
|
90
|
+
rate_limit: z.ZodOptional<z.ZodObject<{
|
|
91
|
+
max_per_minute: z.ZodNumber;
|
|
92
|
+
}, z.core.$strip>>;
|
|
93
|
+
escalation: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
94
|
+
after_actions: z.ZodOptional<z.ZodNumber>;
|
|
95
|
+
after_minutes: z.ZodOptional<z.ZodNumber>;
|
|
96
|
+
require: z.ZodEnum<{
|
|
97
|
+
human_checkin: "human_checkin";
|
|
98
|
+
}>;
|
|
99
|
+
}, z.core.$strip>>>;
|
|
100
|
+
}, z.core.$strip>;
|
|
101
|
+
export declare const PolicySchema: z.ZodObject<{
|
|
102
|
+
version: z.ZodDefault<z.ZodString>;
|
|
103
|
+
name: z.ZodString;
|
|
104
|
+
description: z.ZodOptional<z.ZodString>;
|
|
105
|
+
capabilities: z.ZodArray<z.ZodObject<{
|
|
106
|
+
tool: z.ZodString;
|
|
107
|
+
scope: z.ZodObject<{
|
|
108
|
+
paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
109
|
+
binaries: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
110
|
+
domains: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
111
|
+
methods: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
112
|
+
repos: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
113
|
+
}, z.core.$strip>;
|
|
114
|
+
}, z.core.$strip>>;
|
|
115
|
+
limits: z.ZodDefault<z.ZodObject<{
|
|
116
|
+
max_runtime_ms: z.ZodOptional<z.ZodNumber>;
|
|
117
|
+
max_output_bytes: z.ZodOptional<z.ZodNumber>;
|
|
118
|
+
max_files_changed: z.ZodOptional<z.ZodNumber>;
|
|
119
|
+
max_retries: z.ZodOptional<z.ZodNumber>;
|
|
120
|
+
max_cost_usd: z.ZodOptional<z.ZodNumber>;
|
|
121
|
+
}, z.core.$strip>>;
|
|
122
|
+
gates: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
123
|
+
action: z.ZodString;
|
|
124
|
+
approval: z.ZodEnum<{
|
|
125
|
+
auto: "auto";
|
|
126
|
+
human: "human";
|
|
127
|
+
webhook: "webhook";
|
|
128
|
+
}>;
|
|
129
|
+
risk_level: z.ZodOptional<z.ZodEnum<{
|
|
130
|
+
low: "low";
|
|
131
|
+
medium: "medium";
|
|
132
|
+
high: "high";
|
|
133
|
+
critical: "critical";
|
|
134
|
+
}>>;
|
|
135
|
+
condition: z.ZodOptional<z.ZodString>;
|
|
136
|
+
}, z.core.$strip>>>;
|
|
137
|
+
evidence: z.ZodDefault<z.ZodObject<{
|
|
138
|
+
require: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
139
|
+
format: z.ZodDefault<z.ZodLiteral<"jsonl">>;
|
|
140
|
+
}, z.core.$strip>>;
|
|
141
|
+
forbidden: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
142
|
+
pattern: z.ZodString;
|
|
143
|
+
}, z.core.$strip>>>;
|
|
144
|
+
remediation: z.ZodOptional<z.ZodObject<{
|
|
145
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
146
|
+
match: z.ZodString;
|
|
147
|
+
action: z.ZodString;
|
|
148
|
+
}, z.core.$strip>>>;
|
|
149
|
+
fallback_chain: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
150
|
+
}, z.core.$strip>>;
|
|
151
|
+
session: z.ZodOptional<z.ZodObject<{
|
|
152
|
+
max_actions: z.ZodOptional<z.ZodNumber>;
|
|
153
|
+
max_denials: z.ZodOptional<z.ZodNumber>;
|
|
154
|
+
rate_limit: z.ZodOptional<z.ZodObject<{
|
|
155
|
+
max_per_minute: z.ZodNumber;
|
|
156
|
+
}, z.core.$strip>>;
|
|
157
|
+
escalation: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
158
|
+
after_actions: z.ZodOptional<z.ZodNumber>;
|
|
159
|
+
after_minutes: z.ZodOptional<z.ZodNumber>;
|
|
160
|
+
require: z.ZodEnum<{
|
|
161
|
+
human_checkin: "human_checkin";
|
|
162
|
+
}>;
|
|
163
|
+
}, z.core.$strip>>>;
|
|
164
|
+
}, z.core.$strip>>;
|
|
165
|
+
}, z.core.$strip>;
|
|
166
|
+
export type PolicyInput = z.input<typeof PolicySchema>;
|
|
167
|
+
export type PolicyOutput = z.output<typeof PolicySchema>;
|
|
168
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/policy/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,cAAc,aAAkE,CAAC;AAE9F,eAAO,MAAM,kBAAkB;;;;EAAuC,CAAC;AAEvE,eAAO,MAAM,eAAe;;;;;EAAgD,CAAC;AAM7E,eAAO,MAAM,qBAAqB;;;;;;iBAMe,CAAC;AAElD,eAAO,MAAM,gBAAgB;;;;;;;;;iBAG3B,CAAC;AAMH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;iBAKrB,CAAC;AAMH,eAAO,MAAM,YAAY;;;;;;iBAMc,CAAC;AAMxC,eAAO,MAAM,oBAAoB;;;iBAG/B,CAAC;AAMH,eAAO,MAAM,sBAAsB;;iBAEjC,CAAC;AAMH,eAAO,MAAM,qBAAqB;;;iBAGhC,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;iBAG5B,CAAC;AAMH,eAAO,MAAM,eAAe;;iBAE1B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;iBAI/B,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;iBASyB,CAAC;AAM/D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAWvB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AACvD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,YAAY,CAAC,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas for the Agent Policy YAML DSL.
|
|
3
|
+
*
|
|
4
|
+
* These schemas are the source of truth for policy validation.
|
|
5
|
+
* They mirror (and enforce) the types defined in ../types.ts.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Primitives
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
export const ToolNameSchema = z.string().min(1).describe('Tool identifier, e.g. "file:read"');
|
|
12
|
+
export const ApprovalModeSchema = z.enum(['auto', 'human', 'webhook']);
|
|
13
|
+
export const RiskLevelSchema = z.enum(['low', 'medium', 'high', 'critical']);
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Capability
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
export const CapabilityScopeSchema = z.object({
|
|
18
|
+
paths: z.array(z.string()).optional(),
|
|
19
|
+
binaries: z.array(z.string()).optional(),
|
|
20
|
+
domains: z.array(z.string()).optional(),
|
|
21
|
+
methods: z.array(z.string().toUpperCase()).optional(),
|
|
22
|
+
repos: z.array(z.string()).optional(),
|
|
23
|
+
}).describe('Scope constraints for a capability');
|
|
24
|
+
export const CapabilitySchema = z.object({
|
|
25
|
+
tool: ToolNameSchema,
|
|
26
|
+
scope: CapabilityScopeSchema,
|
|
27
|
+
});
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Gate
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
export const GateSchema = z.object({
|
|
32
|
+
action: ToolNameSchema,
|
|
33
|
+
approval: ApprovalModeSchema,
|
|
34
|
+
risk_level: RiskLevelSchema.optional(),
|
|
35
|
+
condition: z.string().optional(),
|
|
36
|
+
});
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Limits
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
export const LimitsSchema = z.object({
|
|
41
|
+
max_runtime_ms: z.number().positive().optional(),
|
|
42
|
+
max_output_bytes: z.number().positive().optional(),
|
|
43
|
+
max_files_changed: z.number().int().positive().optional(),
|
|
44
|
+
max_retries: z.number().int().nonnegative().optional(),
|
|
45
|
+
max_cost_usd: z.number().nonnegative().optional(),
|
|
46
|
+
}).describe('Budget / resource limits');
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Evidence
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
export const EvidenceConfigSchema = z.object({
|
|
51
|
+
require: z.array(z.string()).default([]),
|
|
52
|
+
format: z.literal('jsonl').default('jsonl'),
|
|
53
|
+
});
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Forbidden
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
export const ForbiddenPatternSchema = z.object({
|
|
58
|
+
pattern: z.string().min(1),
|
|
59
|
+
});
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Remediation
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
export const RemediationRuleSchema = z.object({
|
|
64
|
+
match: z.string().min(1),
|
|
65
|
+
action: z.string().min(1),
|
|
66
|
+
});
|
|
67
|
+
export const RemediationSchema = z.object({
|
|
68
|
+
rules: z.array(RemediationRuleSchema).default([]),
|
|
69
|
+
fallback_chain: z.array(z.string()).optional(),
|
|
70
|
+
});
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Session Constraints
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
export const RateLimitSchema = z.object({
|
|
75
|
+
max_per_minute: z.number().int().positive(),
|
|
76
|
+
});
|
|
77
|
+
export const EscalationRuleSchema = z.object({
|
|
78
|
+
after_actions: z.number().int().positive().optional(),
|
|
79
|
+
after_minutes: z.number().positive().optional(),
|
|
80
|
+
require: z.enum(['human_checkin']),
|
|
81
|
+
});
|
|
82
|
+
export const SessionConstraintsSchema = z.object({
|
|
83
|
+
/** Maximum actions per session */
|
|
84
|
+
max_actions: z.number().int().positive().optional(),
|
|
85
|
+
/** Terminate session after N denials */
|
|
86
|
+
max_denials: z.number().int().positive().optional(),
|
|
87
|
+
/** Rate limiting for actions */
|
|
88
|
+
rate_limit: RateLimitSchema.optional(),
|
|
89
|
+
/** Escalation rules based on thresholds */
|
|
90
|
+
escalation: z.array(EscalationRuleSchema).optional(),
|
|
91
|
+
}).describe('Session-level constraints for the gateway model');
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Top-level Policy
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
export const PolicySchema = z.object({
|
|
96
|
+
version: z.string().default('1.0'),
|
|
97
|
+
name: z.string().min(1),
|
|
98
|
+
description: z.string().optional(),
|
|
99
|
+
capabilities: z.array(CapabilitySchema).min(1, 'At least one capability must be defined'),
|
|
100
|
+
limits: LimitsSchema.default({}),
|
|
101
|
+
gates: z.array(GateSchema).default([]),
|
|
102
|
+
evidence: EvidenceConfigSchema.default({ require: [], format: 'jsonl' }),
|
|
103
|
+
forbidden: z.array(ForbiddenPatternSchema).default([]),
|
|
104
|
+
remediation: RemediationSchema.optional(),
|
|
105
|
+
session: SessionConstraintsSchema.optional(),
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/policy/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Proxy Server — transparent governance layer for MCP-compatible agents.
|
|
3
|
+
*
|
|
4
|
+
* Sits between an MCP client (e.g. Cursor, Claude Code) and backend MCP
|
|
5
|
+
* tool servers. Every tool call is validated against the session policy
|
|
6
|
+
* before being forwarded to the real backend.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* Agent (MCP Client) → MCP Proxy (this) → Backend MCP Servers
|
|
10
|
+
*
|
|
11
|
+
* The proxy:
|
|
12
|
+
* 1. Connects to all configured backend MCP servers
|
|
13
|
+
* 2. Discovers tools from each backend
|
|
14
|
+
* 3. Presents aggregated tool list as its own MCP server
|
|
15
|
+
* 4. On each tool call: evaluate against policy → forward or deny
|
|
16
|
+
* 5. Records all actions and results in the evidence ledger
|
|
17
|
+
*/
|
|
18
|
+
import type { AgentGateway } from '../engine/runtime.js';
|
|
19
|
+
import type { MCPProxyConfig } from './mcp-types.js';
|
|
20
|
+
export declare class MCPProxyServer {
|
|
21
|
+
private server;
|
|
22
|
+
private backends;
|
|
23
|
+
private toolMap;
|
|
24
|
+
private gateway;
|
|
25
|
+
private config;
|
|
26
|
+
private sessionId;
|
|
27
|
+
constructor(config: MCPProxyConfig, gateway: AgentGateway);
|
|
28
|
+
/**
|
|
29
|
+
* Start the MCP proxy server.
|
|
30
|
+
*/
|
|
31
|
+
start(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Stop the MCP proxy server.
|
|
34
|
+
*/
|
|
35
|
+
stop(): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Get the current session ID.
|
|
38
|
+
*/
|
|
39
|
+
getSessionId(): string | null;
|
|
40
|
+
private setupHandlers;
|
|
41
|
+
private connectBackends;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=mcp-proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-proxy.d.ts","sourceRoot":"","sources":["../../src/proxy/mcp-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAWH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAiC,MAAM,gBAAgB,CAAC;AASpF,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAuB;gBAE5B,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY;IAmBzD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB3B;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAQ7B,OAAO,CAAC,aAAa;YA2GP,eAAe;CAyD9B"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Proxy Server — transparent governance layer for MCP-compatible agents.
|
|
3
|
+
*
|
|
4
|
+
* Sits between an MCP client (e.g. Cursor, Claude Code) and backend MCP
|
|
5
|
+
* tool servers. Every tool call is validated against the session policy
|
|
6
|
+
* before being forwarded to the real backend.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* Agent (MCP Client) → MCP Proxy (this) → Backend MCP Servers
|
|
10
|
+
*
|
|
11
|
+
* The proxy:
|
|
12
|
+
* 1. Connects to all configured backend MCP servers
|
|
13
|
+
* 2. Discovers tools from each backend
|
|
14
|
+
* 3. Presents aggregated tool list as its own MCP server
|
|
15
|
+
* 4. On each tool call: evaluate against policy → forward or deny
|
|
16
|
+
* 5. Records all actions and results in the evidence ledger
|
|
17
|
+
*/
|
|
18
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
19
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
20
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
21
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
22
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
23
|
+
export class MCPProxyServer {
|
|
24
|
+
server;
|
|
25
|
+
backends = [];
|
|
26
|
+
toolMap = new Map();
|
|
27
|
+
gateway;
|
|
28
|
+
config;
|
|
29
|
+
sessionId = null;
|
|
30
|
+
constructor(config, gateway) {
|
|
31
|
+
this.config = config;
|
|
32
|
+
this.gateway = gateway;
|
|
33
|
+
this.server = new Server({
|
|
34
|
+
name: 'det-acp-proxy',
|
|
35
|
+
version: '0.1.0',
|
|
36
|
+
}, {
|
|
37
|
+
capabilities: {
|
|
38
|
+
tools: {},
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
this.setupHandlers();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Start the MCP proxy server.
|
|
45
|
+
*/
|
|
46
|
+
async start() {
|
|
47
|
+
// Connect to all backend MCP servers
|
|
48
|
+
await this.connectBackends();
|
|
49
|
+
// Create a session for this proxy connection
|
|
50
|
+
const session = await this.gateway.createSession(this.config.policy, {
|
|
51
|
+
source: 'mcp-proxy',
|
|
52
|
+
...this.config.sessionMetadata,
|
|
53
|
+
});
|
|
54
|
+
this.sessionId = session.id;
|
|
55
|
+
// Start the proxy server
|
|
56
|
+
if (this.config.transport === 'stdio') {
|
|
57
|
+
const transport = new StdioServerTransport();
|
|
58
|
+
await this.server.connect(transport);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
throw new Error('SSE transport not yet implemented for MCP proxy server');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Stop the MCP proxy server.
|
|
66
|
+
*/
|
|
67
|
+
async stop() {
|
|
68
|
+
// Terminate the session
|
|
69
|
+
if (this.sessionId) {
|
|
70
|
+
try {
|
|
71
|
+
await this.gateway.terminateSession(this.sessionId, 'MCP proxy stopped');
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Best effort
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Disconnect backends
|
|
78
|
+
for (const backend of this.backends) {
|
|
79
|
+
try {
|
|
80
|
+
await backend.transport.close();
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Best effort
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
await this.server.close();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get the current session ID.
|
|
90
|
+
*/
|
|
91
|
+
getSessionId() {
|
|
92
|
+
return this.sessionId;
|
|
93
|
+
}
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Private: handler setup
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
setupHandlers() {
|
|
98
|
+
// Handle tools/list — return aggregated tools from all backends
|
|
99
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
100
|
+
const tools = [];
|
|
101
|
+
for (const backend of this.backends) {
|
|
102
|
+
for (const tool of backend.tools) {
|
|
103
|
+
tools.push({
|
|
104
|
+
name: tool.name,
|
|
105
|
+
description: tool.description
|
|
106
|
+
? `[${backend.config.name}] ${tool.description}`
|
|
107
|
+
: `Tool from ${backend.config.name}`,
|
|
108
|
+
inputSchema: tool.inputSchema ?? { type: 'object', properties: {} },
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { tools };
|
|
113
|
+
});
|
|
114
|
+
// Handle tools/call — evaluate against policy, then forward
|
|
115
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
116
|
+
const { name: toolName, arguments: toolArgs } = request.params;
|
|
117
|
+
const mapping = this.toolMap.get(toolName);
|
|
118
|
+
if (!mapping) {
|
|
119
|
+
return {
|
|
120
|
+
content: [{ type: 'text', text: `Unknown tool: ${toolName}` }],
|
|
121
|
+
isError: true,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if (!this.sessionId) {
|
|
125
|
+
return {
|
|
126
|
+
content: [{ type: 'text', text: 'No active session' }],
|
|
127
|
+
isError: true,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Evaluate the action against the session policy
|
|
131
|
+
const evaluation = await this.gateway.evaluate(this.sessionId, {
|
|
132
|
+
tool: toolName,
|
|
133
|
+
input: (toolArgs ?? {}),
|
|
134
|
+
});
|
|
135
|
+
// If denied, return the denial reasons
|
|
136
|
+
if (evaluation.decision === 'deny') {
|
|
137
|
+
return {
|
|
138
|
+
content: [{
|
|
139
|
+
type: 'text',
|
|
140
|
+
text: `Action denied by policy: ${evaluation.reasons.join('; ')}`,
|
|
141
|
+
}],
|
|
142
|
+
isError: true,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// If gated and pending, return a message indicating approval is needed
|
|
146
|
+
if (evaluation.decision === 'gate') {
|
|
147
|
+
return {
|
|
148
|
+
content: [{
|
|
149
|
+
type: 'text',
|
|
150
|
+
text: `Action requires approval: ${evaluation.reasons.join('; ')}. Waiting for gate resolution.`,
|
|
151
|
+
}],
|
|
152
|
+
isError: true,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
// Allowed — forward to the backend
|
|
156
|
+
const backend = this.backends[mapping.backendIndex];
|
|
157
|
+
try {
|
|
158
|
+
const result = await backend.client.callTool({
|
|
159
|
+
name: toolName,
|
|
160
|
+
arguments: toolArgs,
|
|
161
|
+
});
|
|
162
|
+
// Record the result
|
|
163
|
+
const isError = result.isError === true;
|
|
164
|
+
const resultText = Array.isArray(result.content)
|
|
165
|
+
? result.content.map((c) => c.text ?? '').join('\n')
|
|
166
|
+
: String(result.content);
|
|
167
|
+
await this.gateway.recordResult(this.sessionId, evaluation.actionId, {
|
|
168
|
+
success: !isError,
|
|
169
|
+
output: resultText,
|
|
170
|
+
error: isError ? resultText : undefined,
|
|
171
|
+
});
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
const errorMsg = err.message;
|
|
176
|
+
// Record the failure
|
|
177
|
+
await this.gateway.recordResult(this.sessionId, evaluation.actionId, {
|
|
178
|
+
success: false,
|
|
179
|
+
error: errorMsg,
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
content: [{ type: 'text', text: `Backend error: ${errorMsg}` }],
|
|
183
|
+
isError: true,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// Private: backend connections
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
async connectBackends() {
|
|
192
|
+
for (let i = 0; i < this.config.backends.length; i++) {
|
|
193
|
+
const backendConfig = this.config.backends[i];
|
|
194
|
+
if (backendConfig.transport === 'stdio') {
|
|
195
|
+
if (!backendConfig.command) {
|
|
196
|
+
throw new Error(`Backend "${backendConfig.name}" is stdio but has no command`);
|
|
197
|
+
}
|
|
198
|
+
const client = new Client({
|
|
199
|
+
name: `det-acp-proxy-client-${backendConfig.name}`,
|
|
200
|
+
version: '0.1.0',
|
|
201
|
+
}, {
|
|
202
|
+
capabilities: {},
|
|
203
|
+
});
|
|
204
|
+
const transport = new StdioClientTransport({
|
|
205
|
+
command: backendConfig.command,
|
|
206
|
+
args: backendConfig.args,
|
|
207
|
+
env: backendConfig.env
|
|
208
|
+
? { ...process.env, ...backendConfig.env }
|
|
209
|
+
: undefined,
|
|
210
|
+
});
|
|
211
|
+
await client.connect(transport);
|
|
212
|
+
// Discover tools
|
|
213
|
+
const toolsResponse = await client.listTools();
|
|
214
|
+
const tools = toolsResponse.tools.map((t) => ({
|
|
215
|
+
name: t.name,
|
|
216
|
+
description: t.description,
|
|
217
|
+
inputSchema: t.inputSchema,
|
|
218
|
+
}));
|
|
219
|
+
// Map tools to this backend
|
|
220
|
+
for (const tool of tools) {
|
|
221
|
+
this.toolMap.set(tool.name, {
|
|
222
|
+
toolName: tool.name,
|
|
223
|
+
backendName: backendConfig.name,
|
|
224
|
+
backendIndex: i,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
this.backends.push({
|
|
228
|
+
config: backendConfig,
|
|
229
|
+
client,
|
|
230
|
+
transport,
|
|
231
|
+
tools,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
throw new Error(`SSE transport not yet implemented for backend "${backendConfig.name}"`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=mcp-proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-proxy.js","sourceRoot":"","sources":["../../src/proxy/mcp-proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Proxy configuration types.
|
|
3
|
+
*
|
|
4
|
+
* Defines the configuration for the MCP proxy server, including
|
|
5
|
+
* backend MCP server connections and transport settings.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
export interface MCPBackendConfig {
|
|
9
|
+
/** Human-readable name for this backend */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Transport type */
|
|
12
|
+
transport: 'stdio' | 'sse';
|
|
13
|
+
/** Command to spawn (for stdio transport) */
|
|
14
|
+
command?: string;
|
|
15
|
+
/** Arguments for the command (for stdio transport) */
|
|
16
|
+
args?: string[];
|
|
17
|
+
/** Environment variables for the command (for stdio transport) */
|
|
18
|
+
env?: Record<string, string>;
|
|
19
|
+
/** URL for SSE transport */
|
|
20
|
+
url?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface MCPProxyConfig {
|
|
23
|
+
/** Path to policy YAML file or inline YAML */
|
|
24
|
+
policy: string;
|
|
25
|
+
/** Directory for evidence ledger files */
|
|
26
|
+
ledgerDir: string;
|
|
27
|
+
/** Backend MCP servers to proxy to */
|
|
28
|
+
backends: MCPBackendConfig[];
|
|
29
|
+
/** Transport to expose to agents (stdio for local, sse for remote) */
|
|
30
|
+
transport: 'stdio' | 'sse';
|
|
31
|
+
/** Port for SSE transport */
|
|
32
|
+
port?: number;
|
|
33
|
+
/** Host for SSE transport */
|
|
34
|
+
host?: string;
|
|
35
|
+
/** Metadata to attach to sessions */
|
|
36
|
+
sessionMetadata?: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
export declare const MCPBackendConfigSchema: z.ZodObject<{
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
transport: z.ZodEnum<{
|
|
41
|
+
stdio: "stdio";
|
|
42
|
+
sse: "sse";
|
|
43
|
+
}>;
|
|
44
|
+
command: z.ZodOptional<z.ZodString>;
|
|
45
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
46
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
47
|
+
url: z.ZodOptional<z.ZodString>;
|
|
48
|
+
}, z.core.$strip>;
|
|
49
|
+
export declare const MCPProxyConfigSchema: z.ZodObject<{
|
|
50
|
+
policy: z.ZodString;
|
|
51
|
+
ledger_dir: z.ZodDefault<z.ZodString>;
|
|
52
|
+
backends: z.ZodArray<z.ZodObject<{
|
|
53
|
+
name: z.ZodString;
|
|
54
|
+
transport: z.ZodEnum<{
|
|
55
|
+
stdio: "stdio";
|
|
56
|
+
sse: "sse";
|
|
57
|
+
}>;
|
|
58
|
+
command: z.ZodOptional<z.ZodString>;
|
|
59
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
60
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
61
|
+
url: z.ZodOptional<z.ZodString>;
|
|
62
|
+
}, z.core.$strip>>;
|
|
63
|
+
transport: z.ZodDefault<z.ZodEnum<{
|
|
64
|
+
stdio: "stdio";
|
|
65
|
+
sse: "sse";
|
|
66
|
+
}>>;
|
|
67
|
+
port: z.ZodOptional<z.ZodNumber>;
|
|
68
|
+
host: z.ZodOptional<z.ZodString>;
|
|
69
|
+
session_metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
70
|
+
}, z.core.$strip>;
|
|
71
|
+
/**
|
|
72
|
+
* Resolved tool-to-backend mapping.
|
|
73
|
+
*/
|
|
74
|
+
export interface ToolMapping {
|
|
75
|
+
toolName: string;
|
|
76
|
+
backendName: string;
|
|
77
|
+
backendIndex: number;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=mcp-types.d.ts.map
|