@atbash/atbash-mcp 0.0.6 → 0.0.7
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/dist/index.js +44 -112
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import {
|
|
4
|
+
import { Atbash, setupTelemetry, shutdownTelemetry } from "@atbash/sdk";
|
|
5
5
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
7
|
|
|
@@ -41,28 +41,15 @@ function registerSafetyPrompt(server2) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
// src/resources/policy.ts
|
|
44
|
-
function registerPolicyResource(server2,
|
|
44
|
+
function registerPolicyResource(server2, client2) {
|
|
45
45
|
void server2;
|
|
46
|
-
void
|
|
47
|
-
void endpoint2;
|
|
48
|
-
return;
|
|
46
|
+
void client2;
|
|
49
47
|
}
|
|
50
48
|
|
|
51
49
|
// src/tools/judge.ts
|
|
52
|
-
import {
|
|
53
|
-
checkAgentExists,
|
|
54
|
-
createAtbashClient
|
|
55
|
-
} from "@atbash/sdk";
|
|
56
50
|
import { z as z2 } from "zod";
|
|
57
51
|
|
|
58
52
|
// src/utils.ts
|
|
59
|
-
function createClientOpts(agent2, endpoint2, orgName2) {
|
|
60
|
-
const opts = {};
|
|
61
|
-
if (endpoint2) opts.endpoint = endpoint2;
|
|
62
|
-
if (agent2) opts.auth = agent2;
|
|
63
|
-
if (orgName2) opts.orgName = orgName2;
|
|
64
|
-
return Object.keys(opts).length > 0 ? opts : void 0;
|
|
65
|
-
}
|
|
66
53
|
function safeErrorMessage(error) {
|
|
67
54
|
return error instanceof Error ? error.message : String(error);
|
|
68
55
|
}
|
|
@@ -79,13 +66,7 @@ function toErrorContent(error) {
|
|
|
79
66
|
}
|
|
80
67
|
|
|
81
68
|
// src/tools/judge.ts
|
|
82
|
-
function registerJudgeTools(server2,
|
|
83
|
-
const opts = createClientOpts(agent2, endpoint2, orgName2);
|
|
84
|
-
const client = createAtbashClient({
|
|
85
|
-
keyPair: { privKey: agent2.privkey, pubKey: agent2.pubkey },
|
|
86
|
-
judge: endpoint2 ? { endpoint: endpoint2 } : void 0,
|
|
87
|
-
orgName: orgName2
|
|
88
|
-
});
|
|
69
|
+
function registerJudgeTools(server2, client2) {
|
|
89
70
|
server2.registerTool(
|
|
90
71
|
"atbash_judge",
|
|
91
72
|
{
|
|
@@ -107,18 +88,18 @@ function registerJudgeTools(server2, agent2, endpoint2, orgName2) {
|
|
|
107
88
|
parsedArgs = tool_args_json;
|
|
108
89
|
}
|
|
109
90
|
}
|
|
110
|
-
const decision = await
|
|
91
|
+
const decision = await client2.auditToolCall({
|
|
111
92
|
toolName: tool_name ?? "mcp_judge",
|
|
112
93
|
args: parsedArgs ?? { action },
|
|
113
94
|
context: `${action} \u2014 ${context}`
|
|
114
95
|
});
|
|
115
96
|
if (decision.verdict === "HOLD") {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
});
|
|
97
|
+
const holdParts = [
|
|
98
|
+
"Action held for operator review. The agent will not be jailed \u2014 please approve or reject this request from the Atbash dashboard, then ask the agent to try again.",
|
|
99
|
+
`Reason: ${decision.reason ?? ""}`
|
|
100
|
+
];
|
|
101
|
+
if (decision.toolCallId) holdParts.push(`Tool Call ID: ${decision.toolCallId}`);
|
|
102
|
+
return toJsonContent({ ...decision, allow: false, reason: holdParts.join("\n") });
|
|
122
103
|
}
|
|
123
104
|
return toJsonContent(decision);
|
|
124
105
|
} catch (error) {
|
|
@@ -147,18 +128,18 @@ Reason: ${decision.reason ?? ""}`
|
|
|
147
128
|
parsedArgs = tool_args_json;
|
|
148
129
|
}
|
|
149
130
|
}
|
|
150
|
-
const result = await
|
|
131
|
+
const result = await client2.auditToolCall({
|
|
151
132
|
toolName: tool_name ?? "mcp_log",
|
|
152
133
|
args: parsedArgs ?? { action },
|
|
153
134
|
context: `${action} \u2014 ${context}`
|
|
154
135
|
});
|
|
155
136
|
if (result.verdict === "HOLD") {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
});
|
|
137
|
+
const holdParts = [
|
|
138
|
+
"Action held for operator review. The agent will not be jailed \u2014 please approve or reject this request from the Atbash dashboard, then ask the agent to try again.",
|
|
139
|
+
`Reason: ${result.reason ?? ""}`
|
|
140
|
+
];
|
|
141
|
+
if (result.toolCallId) holdParts.push(`Tool Call ID: ${result.toolCallId}`);
|
|
142
|
+
return toJsonContent({ ...result, allow: false, reason: holdParts.join("\n") });
|
|
162
143
|
}
|
|
163
144
|
return toJsonContent(result);
|
|
164
145
|
} catch (error) {
|
|
@@ -176,8 +157,8 @@ Reason: ${result.reason ?? ""}`
|
|
|
176
157
|
},
|
|
177
158
|
async ({ pubkey }) => {
|
|
178
159
|
try {
|
|
179
|
-
const selectedPubkey = pubkey ??
|
|
180
|
-
const registered = await checkAgentExists(selectedPubkey
|
|
160
|
+
const selectedPubkey = pubkey ?? client2.pubkey;
|
|
161
|
+
const registered = await client2.checkAgentExists(selectedPubkey);
|
|
181
162
|
return toJsonContent({ registered, pubkey: selectedPubkey });
|
|
182
163
|
} catch (error) {
|
|
183
164
|
return toErrorContent(error);
|
|
@@ -187,25 +168,11 @@ Reason: ${result.reason ?? ""}`
|
|
|
187
168
|
}
|
|
188
169
|
|
|
189
170
|
// src/tools/queries.ts
|
|
190
|
-
import {
|
|
191
|
-
getAgentDetail,
|
|
192
|
-
getAgentPolicy,
|
|
193
|
-
getAgentToolCalls,
|
|
194
|
-
getHeldActionReviews,
|
|
195
|
-
getOrgSubscription,
|
|
196
|
-
getOrgToolCalls,
|
|
197
|
-
getPendingHeldActions,
|
|
198
|
-
getSafetyStats,
|
|
199
|
-
getToolCallCount,
|
|
200
|
-
getToolCallFull,
|
|
201
|
-
getToolCalls
|
|
202
|
-
} from "@atbash/sdk";
|
|
203
171
|
import { z as z3 } from "zod";
|
|
204
172
|
function defaultMaxCount(value) {
|
|
205
173
|
return value ?? 20;
|
|
206
174
|
}
|
|
207
|
-
function registerQueryTools(server2,
|
|
208
|
-
const opts = createClientOpts(agent2, endpoint2, orgName2);
|
|
175
|
+
function registerQueryTools(server2, client2) {
|
|
209
176
|
server2.registerTool(
|
|
210
177
|
"atbash_get_policy",
|
|
211
178
|
{
|
|
@@ -216,7 +183,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
216
183
|
},
|
|
217
184
|
async ({ pubkey }) => {
|
|
218
185
|
try {
|
|
219
|
-
return toJsonContent(await getAgentPolicy(pubkey ??
|
|
186
|
+
return toJsonContent(await client2.getAgentPolicy(pubkey ?? client2.pubkey));
|
|
220
187
|
} catch (error) {
|
|
221
188
|
return toErrorContent(error);
|
|
222
189
|
}
|
|
@@ -232,7 +199,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
232
199
|
},
|
|
233
200
|
async ({ pubkey }) => {
|
|
234
201
|
try {
|
|
235
|
-
return toJsonContent(await getAgentDetail(pubkey ??
|
|
202
|
+
return toJsonContent(await client2.getAgentDetail(pubkey ?? client2.pubkey));
|
|
236
203
|
} catch (error) {
|
|
237
204
|
return toErrorContent(error);
|
|
238
205
|
}
|
|
@@ -248,7 +215,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
248
215
|
},
|
|
249
216
|
async ({ max_count }) => {
|
|
250
217
|
try {
|
|
251
|
-
return toJsonContent(await getToolCalls(defaultMaxCount(max_count)
|
|
218
|
+
return toJsonContent(await client2.getToolCalls(defaultMaxCount(max_count)));
|
|
252
219
|
} catch (error) {
|
|
253
220
|
return toErrorContent(error);
|
|
254
221
|
}
|
|
@@ -266,7 +233,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
266
233
|
async ({ pubkey, max_count }) => {
|
|
267
234
|
try {
|
|
268
235
|
return toJsonContent(
|
|
269
|
-
await getAgentToolCalls(pubkey ??
|
|
236
|
+
await client2.getAgentToolCalls(pubkey ?? client2.pubkey, defaultMaxCount(max_count))
|
|
270
237
|
);
|
|
271
238
|
} catch (error) {
|
|
272
239
|
return toErrorContent(error);
|
|
@@ -284,7 +251,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
284
251
|
},
|
|
285
252
|
async ({ org_name, max_count }) => {
|
|
286
253
|
try {
|
|
287
|
-
return toJsonContent(await getOrgToolCalls(org_name, defaultMaxCount(max_count)
|
|
254
|
+
return toJsonContent(await client2.getOrgToolCalls(org_name, defaultMaxCount(max_count)));
|
|
288
255
|
} catch (error) {
|
|
289
256
|
return toErrorContent(error);
|
|
290
257
|
}
|
|
@@ -300,7 +267,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
300
267
|
},
|
|
301
268
|
async ({ tool_call_id }) => {
|
|
302
269
|
try {
|
|
303
|
-
return toJsonContent(await getToolCallFull(tool_call_id
|
|
270
|
+
return toJsonContent(await client2.getToolCallFull(tool_call_id));
|
|
304
271
|
} catch (error) {
|
|
305
272
|
return toErrorContent(error);
|
|
306
273
|
}
|
|
@@ -314,7 +281,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
314
281
|
},
|
|
315
282
|
async () => {
|
|
316
283
|
try {
|
|
317
|
-
return toJsonContent({ count: await getToolCallCount(
|
|
284
|
+
return toJsonContent({ count: await client2.getToolCallCount() });
|
|
318
285
|
} catch (error) {
|
|
319
286
|
return toErrorContent(error);
|
|
320
287
|
}
|
|
@@ -323,14 +290,14 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
323
290
|
server2.registerTool(
|
|
324
291
|
"atbash_get_tier_info",
|
|
325
292
|
{
|
|
326
|
-
description: "Get an organization's tier information.",
|
|
293
|
+
description: "Get an organization's tier and enforcement information.",
|
|
327
294
|
inputSchema: z3.object({
|
|
328
295
|
org_name: z3.string().describe("Organization name")
|
|
329
296
|
})
|
|
330
297
|
},
|
|
331
298
|
async ({ org_name }) => {
|
|
332
299
|
try {
|
|
333
|
-
return toJsonContent(await
|
|
300
|
+
return toJsonContent(await client2.getOrgTierInfo(org_name));
|
|
334
301
|
} catch (error) {
|
|
335
302
|
return toErrorContent(error);
|
|
336
303
|
}
|
|
@@ -348,7 +315,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
348
315
|
async ({ org_name, max_count }) => {
|
|
349
316
|
try {
|
|
350
317
|
return toJsonContent(
|
|
351
|
-
await getPendingHeldActions(org_name, defaultMaxCount(max_count)
|
|
318
|
+
await client2.getPendingHeldActions(org_name, defaultMaxCount(max_count))
|
|
352
319
|
);
|
|
353
320
|
} catch (error) {
|
|
354
321
|
return toErrorContent(error);
|
|
@@ -366,7 +333,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
366
333
|
},
|
|
367
334
|
async ({ org_name, max_count }) => {
|
|
368
335
|
try {
|
|
369
|
-
return toJsonContent(await getHeldActionReviews(org_name, defaultMaxCount(max_count)
|
|
336
|
+
return toJsonContent(await client2.getHeldActionReviews(org_name, defaultMaxCount(max_count)));
|
|
370
337
|
} catch (error) {
|
|
371
338
|
return toErrorContent(error);
|
|
372
339
|
}
|
|
@@ -380,7 +347,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
380
347
|
},
|
|
381
348
|
async () => {
|
|
382
349
|
try {
|
|
383
|
-
return toJsonContent(await getSafetyStats(
|
|
350
|
+
return toJsonContent(await client2.getSafetyStats());
|
|
384
351
|
} catch (error) {
|
|
385
352
|
return toErrorContent(error);
|
|
386
353
|
}
|
|
@@ -390,23 +357,7 @@ function registerQueryTools(server2, agent2, endpoint2, orgName2) {
|
|
|
390
357
|
|
|
391
358
|
// src/tools/status.ts
|
|
392
359
|
import { z as z4 } from "zod";
|
|
393
|
-
function
|
|
394
|
-
if (raw == null) return "No verdict";
|
|
395
|
-
const value = String(raw).toUpperCase();
|
|
396
|
-
if (value === "ALLOW" || value === "GREEN") return "ALLOW";
|
|
397
|
-
if (value === "HOLD" || value === "YELLOW") return "HOLD";
|
|
398
|
-
if (value === "BLOCK" || value === "RED") return "BLOCK";
|
|
399
|
-
return value;
|
|
400
|
-
}
|
|
401
|
-
function normalizeStatus(raw) {
|
|
402
|
-
const value = String(raw ?? "").toLowerCase();
|
|
403
|
-
if (value === "pending" || value === "answered" || value === "error") {
|
|
404
|
-
return value;
|
|
405
|
-
}
|
|
406
|
-
return "error";
|
|
407
|
-
}
|
|
408
|
-
function registerStatusTools(server2, defaultPubkey, endpoint2) {
|
|
409
|
-
const baseUrl = (endpoint2 ?? "https://atbash.ai").replace(/\/$/, "");
|
|
360
|
+
function registerStatusTools(server2, client2) {
|
|
410
361
|
server2.registerTool(
|
|
411
362
|
"atbash_judgment_status",
|
|
412
363
|
{
|
|
@@ -418,30 +369,8 @@ function registerStatusTools(server2, defaultPubkey, endpoint2) {
|
|
|
418
369
|
},
|
|
419
370
|
async ({ tool_call_id, agent_pubkey }) => {
|
|
420
371
|
try {
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
url.searchParams.set("tool_call_id", tool_call_id);
|
|
424
|
-
url.searchParams.set("agent_pubkey", pubkey);
|
|
425
|
-
const response = await fetch(url, {
|
|
426
|
-
method: "GET",
|
|
427
|
-
headers: { Accept: "application/json" }
|
|
428
|
-
});
|
|
429
|
-
if (!response.ok) {
|
|
430
|
-
const body = await response.text().catch(() => "");
|
|
431
|
-
throw new Error(`API error ${response.status}: ${body || response.statusText}`);
|
|
432
|
-
}
|
|
433
|
-
const data = await response.json();
|
|
434
|
-
return toJsonContent({
|
|
435
|
-
status: normalizeStatus(data.status),
|
|
436
|
-
verdict: normalizeVerdict(data.verdict),
|
|
437
|
-
reason: String(data.reason ?? ""),
|
|
438
|
-
judgmentId: String(data.judgmentId ?? tool_call_id),
|
|
439
|
-
onChain: Boolean(data.onChain),
|
|
440
|
-
cached: Boolean(data.cached),
|
|
441
|
-
responseTimeMs: Number(data.responseTimeMs ?? 0),
|
|
442
|
-
tool_call_id,
|
|
443
|
-
agent_pubkey: pubkey
|
|
444
|
-
});
|
|
372
|
+
const status = await client2.getJudgmentStatus(tool_call_id, agent_pubkey);
|
|
373
|
+
return toJsonContent(status);
|
|
445
374
|
} catch (error) {
|
|
446
375
|
return toErrorContent(error);
|
|
447
376
|
}
|
|
@@ -455,21 +384,24 @@ if (!privkey) {
|
|
|
455
384
|
console.error("ATBASH_AGENT_PRIVKEY env var is required");
|
|
456
385
|
process.exit(1);
|
|
457
386
|
}
|
|
458
|
-
var agent = loadAgent(privkey);
|
|
459
387
|
var endpoint = process.env.ATBASH_ENDPOINT;
|
|
460
388
|
var orgName = process.env.ATBASH_ORG_NAME;
|
|
461
389
|
setupTelemetry({ enabled: true, source: "plugin:mcp" });
|
|
462
390
|
process.once("beforeExit", () => shutdownTelemetry());
|
|
463
391
|
process.once("SIGINT", () => shutdownTelemetry().finally(() => process.exit(0)));
|
|
464
392
|
process.once("SIGTERM", () => shutdownTelemetry().finally(() => process.exit(0)));
|
|
393
|
+
var clientOpts = {};
|
|
394
|
+
if (endpoint) clientOpts.endpoint = endpoint;
|
|
395
|
+
if (orgName) clientOpts.orgName = orgName;
|
|
396
|
+
var client = new Atbash(privkey, clientOpts);
|
|
465
397
|
var server = new McpServer({
|
|
466
398
|
name: "atbash-safety",
|
|
467
399
|
version: "1.0.0"
|
|
468
400
|
});
|
|
469
|
-
registerJudgeTools(server,
|
|
470
|
-
registerStatusTools(server,
|
|
471
|
-
registerQueryTools(server,
|
|
472
|
-
registerPolicyResource(server,
|
|
401
|
+
registerJudgeTools(server, client);
|
|
402
|
+
registerStatusTools(server, client);
|
|
403
|
+
registerQueryTools(server, client);
|
|
404
|
+
registerPolicyResource(server, client);
|
|
473
405
|
registerSafetyPrompt(server);
|
|
474
406
|
var transport = new StdioServerTransport();
|
|
475
407
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atbash/atbash-mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Atbash safety judge exposed as a standalone MCP server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"publish:dev": "node scripts/publish-dev.mjs"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@atbash/sdk": "
|
|
44
|
+
"@atbash/sdk": "0.5.4",
|
|
45
45
|
"@modelcontextprotocol/sdk": "^1.12.3",
|
|
46
46
|
"zod": "^3.25.76"
|
|
47
47
|
},
|