@2kw/ai-mcp-server 6.1.0-dev.8 → 6.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.
- package/README.md +5 -1
- package/dist/index.js +10 -0
- package/dist/tools/agents.d.ts +4 -0
- package/dist/tools/agents.js +434 -0
- package/dist/tools/annotation-queues.d.ts +4 -0
- package/dist/tools/annotation-queues.js +322 -0
- package/dist/tools/conversations.d.ts +4 -0
- package/dist/tools/conversations.js +102 -0
- package/dist/tools/files.d.ts +4 -0
- package/dist/tools/files.js +143 -0
- package/dist/tools/knowledge.d.ts +4 -0
- package/dist/tools/knowledge.js +382 -0
- package/dist/tools/scores.js +53 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 2kw.ai MCP Server
|
|
2
2
|
|
|
3
|
-
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server for [2kw.ai](https://2kw.ai) — the EU-hosted AI integration platform. It gives AI coding assistants like Claude Code, Cursor, and Windsurf direct access to an [OpenAI-compatible LLM gateway](https://2kw.ai/gateway), [schema-driven document extraction](https://2kw.ai/extraction), audio transcription, and [cost observability](https://2kw.ai/observability) —
|
|
3
|
+
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server for [2kw.ai](https://2kw.ai) — the EU-hosted AI integration platform. It gives AI coding assistants like Claude Code, Cursor, and Windsurf direct access to an [OpenAI-compatible LLM gateway](https://2kw.ai/gateway), [schema-driven document extraction](https://2kw.ai/extraction), audio transcription, custom agents with a knowledge base, and [cost observability](https://2kw.ai/observability) — 158 tools, straight from your editor.
|
|
4
4
|
|
|
5
5
|
Typical prompts once installed: *"extract the line items from this invoice PDF"*, *"create a schema for purchase orders and test it against these samples"*, *"transcribe this call recording"*, *"what did our extraction traffic cost this week?"*.
|
|
6
6
|
|
|
@@ -56,6 +56,10 @@ Get an API key from your [2kw.ai dashboard](https://2kw.ai) — paid plans start
|
|
|
56
56
|
| **Schemas** | CRUD, versioning, labels, validation, and testing against sample documents |
|
|
57
57
|
| **Prompts** | Versioned prompt management, labels, compilation, testing |
|
|
58
58
|
| **Datasets & experiments** | Build datasets, run experiments, manage evaluators, record scores |
|
|
59
|
+
| **Agents** | CRUD, versioning, labels, tool-approval history, and tool-catalog sync history |
|
|
60
|
+
| **Conversations** | Create/inspect/delete conversations and replay their items for the responses API |
|
|
61
|
+
| **Knowledge base** | CRUD, document upload/attach/versioning, hybrid search, and citation resolution |
|
|
62
|
+
| **Files** | Upload, list, download, and delete files (agent input or knowledge documents) |
|
|
59
63
|
| **Observability** | Analytics (spend, quality, providers, errors), traces, billing limits |
|
|
60
64
|
| **API docs** | Browse the platform API documentation by section |
|
|
61
65
|
|
package/dist/index.js
CHANGED
|
@@ -21,9 +21,14 @@ import * as prompts from "./tools/prompts.js";
|
|
|
21
21
|
import * as providers from "./tools/providers.js";
|
|
22
22
|
import * as billing from "./tools/billing.js";
|
|
23
23
|
import * as scores from "./tools/scores.js";
|
|
24
|
+
import * as annotationQueues from "./tools/annotation-queues.js";
|
|
24
25
|
import * as tracing from "./tools/tracing.js";
|
|
25
26
|
import * as analytics from "./tools/analytics.js";
|
|
26
27
|
import * as docs from "./tools/docs.js";
|
|
28
|
+
import * as agents from "./tools/agents.js";
|
|
29
|
+
import * as conversations from "./tools/conversations.js";
|
|
30
|
+
import * as knowledge from "./tools/knowledge.js";
|
|
31
|
+
import * as files from "./tools/files.js";
|
|
27
32
|
// Read the canonical KW_* env var; fall back to legacy BACKBONE_* for
|
|
28
33
|
// backwards compatibility. Warn once on stderr when the legacy name supplied
|
|
29
34
|
// the value.
|
|
@@ -81,9 +86,14 @@ async function main() {
|
|
|
81
86
|
providers.register(server, client);
|
|
82
87
|
billing.register(server, client);
|
|
83
88
|
scores.register(server, client);
|
|
89
|
+
annotationQueues.register(server, client);
|
|
84
90
|
tracing.register(server, client);
|
|
85
91
|
analytics.register(server, client);
|
|
86
92
|
docs.register(server, client, baseUrl, apiKey);
|
|
93
|
+
agents.register(server, client);
|
|
94
|
+
conversations.register(server, client);
|
|
95
|
+
knowledge.register(server, client);
|
|
96
|
+
files.register(server, client);
|
|
87
97
|
if (transport === "http") {
|
|
88
98
|
const httpTransport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
89
99
|
const httpServer = createServer(async (req, res) => {
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatErrorForMcp } from "../errors.js";
|
|
3
|
+
export function register(server, client) {
|
|
4
|
+
// ── list_agents ─────────────────────────────────────────────────────────
|
|
5
|
+
server.tool("2kw_list_agents", "List agents in the organization with optional search and pagination.", {
|
|
6
|
+
search: z.string().optional().describe("Filter agents by name"),
|
|
7
|
+
page: z.number().optional().default(0).describe("Page number (0-based)"),
|
|
8
|
+
size: z.number().optional().default(20).describe("Page size"),
|
|
9
|
+
sort: z.string().optional().describe("Sort field and direction"),
|
|
10
|
+
}, async ({ search, page, size, sort }) => {
|
|
11
|
+
try {
|
|
12
|
+
const { data } = await client.GET("/v1/agents", {
|
|
13
|
+
params: {
|
|
14
|
+
query: {
|
|
15
|
+
search,
|
|
16
|
+
pageable: { page, size, sort: sort ? [sort] : undefined },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
const result = data;
|
|
21
|
+
const lines = (result.content ?? []).map((a) => `- ${a.name} (id: ${a.id}, model: ${a.model})${a.description ? ` — ${a.description}` : ""}`);
|
|
22
|
+
return {
|
|
23
|
+
content: [
|
|
24
|
+
{
|
|
25
|
+
type: "text",
|
|
26
|
+
text: `Agents (${result.totalElements} total, page ${(result.number ?? 0) + 1}/${result.totalPages}):\n${lines.join("\n") || "(none)"}`,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
return {
|
|
33
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
34
|
+
isError: true,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
// ── get_agent ───────────────────────────────────────────────────────────
|
|
39
|
+
server.tool("2kw_get_agent", "Get an agent by its ID.", { agentId: z.string().describe("The agent ID") }, async ({ agentId }) => {
|
|
40
|
+
try {
|
|
41
|
+
const { data } = await client.GET("/v1/agents/{id}", {
|
|
42
|
+
params: { path: { id: agentId } },
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return {
|
|
50
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
51
|
+
isError: true,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// ── create_agent ────────────────────────────────────────────────────────
|
|
56
|
+
server.tool("2kw_create_agent", "Create a new agent for the organization.", {
|
|
57
|
+
name: z.string().min(1).describe("Agent name"),
|
|
58
|
+
model: z.string().min(1).describe("Model in 'provider/model' format (e.g. 'openai/gpt-4o')"),
|
|
59
|
+
description: z.string().optional().describe("Agent description"),
|
|
60
|
+
instructions: z.string().optional().describe("System instructions for the agent"),
|
|
61
|
+
options: z.unknown().optional().describe("Arbitrary model options (JSON object)"),
|
|
62
|
+
tools: z.unknown().optional().describe("Tool configuration (JSON object)"),
|
|
63
|
+
skills: z.unknown().optional().describe("Skill configuration (JSON object)"),
|
|
64
|
+
hitlPolicy: z.unknown().optional().describe("Human-in-the-loop approval policy (JSON object)"),
|
|
65
|
+
}, async ({ name, model, description, instructions, options, tools, skills, hitlPolicy }) => {
|
|
66
|
+
try {
|
|
67
|
+
const body = { name, model };
|
|
68
|
+
if (description !== undefined)
|
|
69
|
+
body.description = description;
|
|
70
|
+
if (instructions !== undefined)
|
|
71
|
+
body.instructions = instructions;
|
|
72
|
+
if (options !== undefined)
|
|
73
|
+
body.options = options;
|
|
74
|
+
if (tools !== undefined)
|
|
75
|
+
body.tools = tools;
|
|
76
|
+
if (skills !== undefined)
|
|
77
|
+
body.skills = skills;
|
|
78
|
+
if (hitlPolicy !== undefined)
|
|
79
|
+
body.hitlPolicy = hitlPolicy;
|
|
80
|
+
const { data } = await client.POST("/v1/agents", {
|
|
81
|
+
body: body,
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
return {
|
|
89
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
90
|
+
isError: true,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// ── update_agent ────────────────────────────────────────────────────────
|
|
95
|
+
server.tool("2kw_update_agent", "Update an agent's metadata and configuration. name and model are required on every update — the backend treats this as a full replace of those fields.", {
|
|
96
|
+
agentId: z.string().describe("The agent ID"),
|
|
97
|
+
name: z.string().min(1).describe("Agent name"),
|
|
98
|
+
model: z.string().min(1).describe("Model in 'provider/model' format (e.g. 'openai/gpt-4o')"),
|
|
99
|
+
description: z.string().optional().describe("Agent description"),
|
|
100
|
+
instructions: z.string().optional().describe("System instructions for the agent"),
|
|
101
|
+
options: z.unknown().optional().describe("Arbitrary model options (JSON object)"),
|
|
102
|
+
tools: z.unknown().optional().describe("Tool configuration (JSON object)"),
|
|
103
|
+
skills: z.unknown().optional().describe("Skill configuration (JSON object)"),
|
|
104
|
+
hitlPolicy: z.unknown().optional().describe("Human-in-the-loop approval policy (JSON object)"),
|
|
105
|
+
}, async ({ agentId, name, model, description, instructions, options, tools, skills, hitlPolicy }) => {
|
|
106
|
+
try {
|
|
107
|
+
const body = { name, model };
|
|
108
|
+
if (description !== undefined)
|
|
109
|
+
body.description = description;
|
|
110
|
+
if (instructions !== undefined)
|
|
111
|
+
body.instructions = instructions;
|
|
112
|
+
if (options !== undefined)
|
|
113
|
+
body.options = options;
|
|
114
|
+
if (tools !== undefined)
|
|
115
|
+
body.tools = tools;
|
|
116
|
+
if (skills !== undefined)
|
|
117
|
+
body.skills = skills;
|
|
118
|
+
if (hitlPolicy !== undefined)
|
|
119
|
+
body.hitlPolicy = hitlPolicy;
|
|
120
|
+
const { data } = await client.PUT("/v1/agents/{id}", {
|
|
121
|
+
params: { path: { id: agentId } },
|
|
122
|
+
body: body,
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
return {
|
|
130
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
131
|
+
isError: true,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
// ── delete_agent ────────────────────────────────────────────────────────
|
|
136
|
+
server.tool("2kw_delete_agent", "Delete an agent and cascade-delete its versions and labels. This action is irreversible.", { agentId: z.string().describe("The agent ID to delete") }, async ({ agentId }) => {
|
|
137
|
+
try {
|
|
138
|
+
await client.DELETE("/v1/agents/{id}", {
|
|
139
|
+
params: { path: { id: agentId } },
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
content: [{ type: "text", text: `Agent ${agentId} deleted successfully.` }],
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
return {
|
|
147
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
148
|
+
isError: true,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
// ── list_agent_versions ─────────────────────────────────────────────────
|
|
153
|
+
server.tool("2kw_list_agent_versions", "List version history for an agent, with pagination.", {
|
|
154
|
+
agentId: z.string().describe("The agent ID"),
|
|
155
|
+
page: z.number().optional().default(0).describe("Page number (0-based)"),
|
|
156
|
+
size: z.number().optional().default(20).describe("Page size"),
|
|
157
|
+
}, async ({ agentId, page, size }) => {
|
|
158
|
+
try {
|
|
159
|
+
const { data } = await client.GET("/v1/agents/{agentId}/versions", {
|
|
160
|
+
params: { path: { agentId }, query: { pageable: { page, size } } },
|
|
161
|
+
});
|
|
162
|
+
const result = data;
|
|
163
|
+
const lines = (result.content ?? []).map((v) => `- v${v.versionNumber} (id: ${v.id})${v.changeDescription ? ` — ${v.changeDescription}` : ""}`);
|
|
164
|
+
return {
|
|
165
|
+
content: [
|
|
166
|
+
{
|
|
167
|
+
type: "text",
|
|
168
|
+
text: `Agent versions (${result.totalElements} total, page ${(result.number ?? 0) + 1}/${result.totalPages}):\n${lines.join("\n") || "(none)"}`,
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
return {
|
|
175
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
176
|
+
isError: true,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
// ── create_agent_version ────────────────────────────────────────────────
|
|
181
|
+
server.tool("2kw_create_agent_version", "Create a new version of an agent. Auto-updates the 'latest' label.", {
|
|
182
|
+
agentId: z.string().describe("The agent ID"),
|
|
183
|
+
model: z.string().min(1).describe("Model in 'provider/model' format (e.g. 'openai/gpt-4o')"),
|
|
184
|
+
changeDescription: z.string().optional().describe("Description of what changed in this version"),
|
|
185
|
+
instructions: z.string().optional().describe("System instructions for the agent"),
|
|
186
|
+
options: z.unknown().optional().describe("Arbitrary model options (JSON object)"),
|
|
187
|
+
tools: z.unknown().optional().describe("Tool configuration (JSON object)"),
|
|
188
|
+
skills: z.unknown().optional().describe("Skill configuration (JSON object)"),
|
|
189
|
+
hitlPolicy: z.unknown().optional().describe("Human-in-the-loop approval policy (JSON object)"),
|
|
190
|
+
}, async ({ agentId, model, changeDescription, instructions, options, tools, skills, hitlPolicy }) => {
|
|
191
|
+
try {
|
|
192
|
+
const body = { model };
|
|
193
|
+
if (changeDescription !== undefined)
|
|
194
|
+
body.changeDescription = changeDescription;
|
|
195
|
+
if (instructions !== undefined)
|
|
196
|
+
body.instructions = instructions;
|
|
197
|
+
if (options !== undefined)
|
|
198
|
+
body.options = options;
|
|
199
|
+
if (tools !== undefined)
|
|
200
|
+
body.tools = tools;
|
|
201
|
+
if (skills !== undefined)
|
|
202
|
+
body.skills = skills;
|
|
203
|
+
if (hitlPolicy !== undefined)
|
|
204
|
+
body.hitlPolicy = hitlPolicy;
|
|
205
|
+
const { data } = await client.POST("/v1/agents/{agentId}/versions", {
|
|
206
|
+
params: { path: { agentId } },
|
|
207
|
+
body: body,
|
|
208
|
+
});
|
|
209
|
+
return {
|
|
210
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
return {
|
|
215
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
216
|
+
isError: true,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
// ── get_latest_agent_version ────────────────────────────────────────────
|
|
221
|
+
server.tool("2kw_get_latest_agent_version", "Retrieve the most recent version of an agent.", { agentId: z.string().describe("The agent ID") }, async ({ agentId }) => {
|
|
222
|
+
try {
|
|
223
|
+
const { data } = await client.GET("/v1/agents/{agentId}/versions/latest", {
|
|
224
|
+
params: { path: { agentId } },
|
|
225
|
+
});
|
|
226
|
+
return {
|
|
227
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
return {
|
|
232
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
233
|
+
isError: true,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
// ── get_agent_version ───────────────────────────────────────────────────
|
|
238
|
+
server.tool("2kw_get_agent_version", "Retrieve a specific version of an agent.", {
|
|
239
|
+
agentId: z.string().describe("The agent ID"),
|
|
240
|
+
versionId: z.string().describe("The version ID"),
|
|
241
|
+
}, async ({ agentId, versionId }) => {
|
|
242
|
+
try {
|
|
243
|
+
const { data } = await client.GET("/v1/agents/{agentId}/versions/{versionId}", {
|
|
244
|
+
params: { path: { agentId, versionId } },
|
|
245
|
+
});
|
|
246
|
+
return {
|
|
247
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
return {
|
|
252
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
253
|
+
isError: true,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
// ── deactivate_agent_version ────────────────────────────────────────────
|
|
258
|
+
server.tool("2kw_deactivate_agent_version", "Soft-delete an agent version.", {
|
|
259
|
+
agentId: z.string().describe("The agent ID"),
|
|
260
|
+
versionId: z.string().describe("The version ID to deactivate"),
|
|
261
|
+
}, async ({ agentId, versionId }) => {
|
|
262
|
+
try {
|
|
263
|
+
await client.DELETE("/v1/agents/{agentId}/versions/{versionId}", {
|
|
264
|
+
params: { path: { agentId, versionId } },
|
|
265
|
+
});
|
|
266
|
+
return {
|
|
267
|
+
content: [
|
|
268
|
+
{ type: "text", text: `Agent version ${versionId} deactivated.` },
|
|
269
|
+
],
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
return {
|
|
274
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
275
|
+
isError: true,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
// ── activate_agent_version ──────────────────────────────────────────────
|
|
280
|
+
server.tool("2kw_activate_agent_version", "Re-activate a historical agent version by creating a copy at the head.", {
|
|
281
|
+
agentId: z.string().describe("The agent ID"),
|
|
282
|
+
versionId: z.string().describe("The version ID to activate"),
|
|
283
|
+
}, async ({ agentId, versionId }) => {
|
|
284
|
+
try {
|
|
285
|
+
const { data } = await client.PUT("/v1/agents/{agentId}/versions/{versionId}/activate", { params: { path: { agentId, versionId } } });
|
|
286
|
+
return {
|
|
287
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
return {
|
|
292
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
293
|
+
isError: true,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
// ── list_agent_labels ───────────────────────────────────────────────────
|
|
298
|
+
server.tool("2kw_list_agent_labels", "List labels defined on an agent (e.g. production, staging) and which version each points to.", { agentId: z.string().describe("The agent ID") }, async ({ agentId }) => {
|
|
299
|
+
try {
|
|
300
|
+
const { data } = await client.GET("/v1/agents/{agentId}/labels", {
|
|
301
|
+
params: { path: { agentId } },
|
|
302
|
+
});
|
|
303
|
+
return {
|
|
304
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
return {
|
|
309
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
310
|
+
isError: true,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
// ── create_agent_label ──────────────────────────────────────────────────
|
|
315
|
+
server.tool("2kw_create_agent_label", "Label an agent version (e.g. tag as 'production'). Labels are unique per agent. The 'latest' label is system-managed and cannot be created manually.", {
|
|
316
|
+
agentId: z.string().describe("The agent ID"),
|
|
317
|
+
name: z.string().describe("Label name"),
|
|
318
|
+
agentVersionId: z.string().describe("Version id the label should point to"),
|
|
319
|
+
}, async ({ agentId, name, agentVersionId }) => {
|
|
320
|
+
try {
|
|
321
|
+
const { data } = await client.POST("/v1/agents/{agentId}/labels", {
|
|
322
|
+
params: { path: { agentId } },
|
|
323
|
+
body: { name, agentVersionId },
|
|
324
|
+
});
|
|
325
|
+
return {
|
|
326
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
return {
|
|
331
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
332
|
+
isError: true,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
// ── update_agent_label ──────────────────────────────────────────────────
|
|
337
|
+
server.tool("2kw_update_agent_label", "Repoint an existing agent label to a different version — typical release cutover. The 'latest' label is system-managed and cannot be updated manually.", {
|
|
338
|
+
agentId: z.string().describe("The agent ID"),
|
|
339
|
+
labelName: z.string().describe("The label name"),
|
|
340
|
+
agentVersionId: z.string().describe("Version id the label should now point to"),
|
|
341
|
+
}, async ({ agentId, labelName, agentVersionId }) => {
|
|
342
|
+
try {
|
|
343
|
+
const { data } = await client.PUT("/v1/agents/{agentId}/labels/{labelName}", {
|
|
344
|
+
params: { path: { agentId, labelName } },
|
|
345
|
+
body: { agentVersionId },
|
|
346
|
+
});
|
|
347
|
+
return {
|
|
348
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
catch (error) {
|
|
352
|
+
return {
|
|
353
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
354
|
+
isError: true,
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
// ── delete_agent_label ──────────────────────────────────────────────────
|
|
359
|
+
server.tool("2kw_delete_agent_label", "Delete a label from an agent. The 'latest' label cannot be deleted.", {
|
|
360
|
+
agentId: z.string().describe("The agent ID"),
|
|
361
|
+
labelName: z.string().describe("The label name"),
|
|
362
|
+
}, async ({ agentId, labelName }) => {
|
|
363
|
+
try {
|
|
364
|
+
await client.DELETE("/v1/agents/{agentId}/labels/{labelName}", {
|
|
365
|
+
params: { path: { agentId, labelName } },
|
|
366
|
+
});
|
|
367
|
+
return {
|
|
368
|
+
content: [
|
|
369
|
+
{
|
|
370
|
+
type: "text",
|
|
371
|
+
text: `Label "${labelName}" deleted from agent ${agentId}.`,
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
catch (error) {
|
|
377
|
+
return {
|
|
378
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
379
|
+
isError: true,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
// ── list_agent_approvals ────────────────────────────────────────────────
|
|
384
|
+
server.tool("2kw_list_agent_approvals", "List human-in-the-loop tool approvals raised by an agent, newest first. Filter with status=pending|approved|rejected|cancelled. A surface principal sees only their own.", {
|
|
385
|
+
agentId: z.string().describe("The agent ID"),
|
|
386
|
+
status: z.string().optional().describe("Filter by approval status"),
|
|
387
|
+
page: z.number().optional().default(0).describe("Page number (0-based)"),
|
|
388
|
+
size: z.number().optional().default(20).describe("Page size"),
|
|
389
|
+
}, async ({ agentId, status, page, size }) => {
|
|
390
|
+
try {
|
|
391
|
+
const { data } = await client.GET("/v1/agents/{agentId}/approvals", {
|
|
392
|
+
params: {
|
|
393
|
+
path: { agentId },
|
|
394
|
+
query: { status, pageable: { page, size } },
|
|
395
|
+
},
|
|
396
|
+
});
|
|
397
|
+
return {
|
|
398
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
catch (error) {
|
|
402
|
+
return {
|
|
403
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
404
|
+
isError: true,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
// ── list_agent_tool_catalogs ─────────────────────────────────────────────
|
|
409
|
+
server.tool("2kw_list_agent_tool_catalogs", "List an agent's tool-catalog sync history, newest first. Optionally narrow to one installation. The signed bytes and their signature are never returned.", {
|
|
410
|
+
agentId: z.string().describe("The agent ID"),
|
|
411
|
+
installationId: z.string().optional().describe("Narrow to a single installation"),
|
|
412
|
+
page: z.number().optional().default(0).describe("Page number (0-based)"),
|
|
413
|
+
size: z.number().optional().default(20).describe("Page size"),
|
|
414
|
+
}, async ({ agentId, installationId, page, size }) => {
|
|
415
|
+
try {
|
|
416
|
+
const { data } = await client.GET("/v1/agents/{agentId}/tool-catalogs", {
|
|
417
|
+
params: {
|
|
418
|
+
path: { agentId },
|
|
419
|
+
query: { installationId, pageable: { page, size } },
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
return {
|
|
423
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
catch (error) {
|
|
427
|
+
return {
|
|
428
|
+
content: [{ type: "text", text: formatErrorForMcp(error) }],
|
|
429
|
+
isError: true,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
//# sourceMappingURL=agents.js.map
|