@2kw/ai-mcp-server 7.4.0-dev.8 → 8.0.0-dev.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.
@@ -17,9 +17,10 @@ export const CONVERSATION_MODES = ["plan", "ask", "auto"];
17
17
  * that sets it, so a model that switched on its own would lift the user's choice for every later turn.
18
18
  */
19
19
  export const MODE_RULE = "Set `mode` only when the user explicitly asks for that mode. Never set it to retry a refused approval " +
20
- "or to leave plan mode on your own: ask the user first. plan = read-only; ask = no automatic approver, " +
21
- "calls that need approval wait for a person; auto = the operator's policy as written. Leave it out to " +
22
- "keep the conversation's mode.";
20
+ "or to leave plan mode on your own: ask the user first. plan = read-only; ask = calls that need approval " +
21
+ "wait for a person; auto = the automatic approver decides reads and writes the server marks safe, a person " +
22
+ "decides the rest. Leave it out to keep the conversation's mode, else the agent's default. A mode the agent " +
23
+ "does not offer is refused with `conversation_mode_not_offered`.";
23
24
  function isConversationMode(value) {
24
25
  return typeof value === "string" && CONVERSATION_MODES.includes(value);
25
26
  }
@@ -379,7 +379,7 @@ export function register(server, client) {
379
379
  mode: z
380
380
  .enum(["plan", "ask", "auto"])
381
381
  .optional()
382
- .describe("Answer as a conversation in this mode would be gated: plan refuses every call that is not read-only, ask puts a person where the policy would ask the judge, auto is the policy as written. A mode that contributed is listed in matchedRules as conversation_mode.<mode>. Omit for no mode."),
382
+ .describe("Answer as a conversation in this mode would be gated: plan refuses every call that is not read-only, ask puts a person on every call that needs approval, auto lets the automatic approver decide reads and writes the server marks safe. A mode that contributed is listed in matchedRules as conversation_mode.<mode>. Omit for the agent's default mode; a mode the agent does not offer is refused with `conversation_mode_not_offered`."),
383
383
  }, async ({ agentId, versionId, tool, installationId, mode }) => {
384
384
  try {
385
385
  const { data } = await client.GET("/v1/agents/{agentId}/versions/{versionId}/policy", {
@@ -195,7 +195,6 @@ export function register(server, client) {
195
195
  try {
196
196
  const { data } = await client.GET("/v1/datasets/{id}/versions/{versionId}", {
197
197
  params: {
198
- // OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
199
198
  path: { id: datasetId, versionId },
200
199
  },
201
200
  });
@@ -251,7 +250,6 @@ export function register(server, client) {
251
250
  body.metadata = metadata;
252
251
  const { data } = await client.POST("/v1/datasets/{id}/versions/{versionId}/items", {
253
252
  params: {
254
- // OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
255
253
  path: { id: datasetId, versionId: resolvedVersionId },
256
254
  },
257
255
  body: body,
@@ -285,7 +283,6 @@ export function register(server, client) {
285
283
  const resolvedVersionId = versionId ?? (await resolveLatestVersionId(client, datasetId));
286
284
  const { data } = await client.POST("/v1/datasets/{id}/versions/{versionId}/items/bulk", {
287
285
  params: {
288
- // OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
289
286
  path: { id: datasetId, versionId: resolvedVersionId },
290
287
  },
291
288
  body: items,
@@ -312,7 +309,6 @@ export function register(server, client) {
312
309
  const resolvedVersionId = versionId ?? (await resolveLatestVersionId(client, datasetId));
313
310
  const { data } = await client.GET("/v1/datasets/{id}/versions/{versionId}/items", {
314
311
  params: {
315
- // OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
316
312
  path: { id: datasetId, versionId: resolvedVersionId },
317
313
  query: { pageable: { page, size } },
318
314
  },
@@ -349,7 +345,6 @@ export function register(server, client) {
349
345
  const resolvedVersionId = versionId ?? (await resolveLatestVersionId(client, datasetId));
350
346
  await client.DELETE("/v1/datasets/{id}/versions/{versionId}/items/{itemId}", {
351
347
  params: {
352
- // OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
353
348
  path: { id: datasetId, versionId: resolvedVersionId, itemId },
354
349
  },
355
350
  });
@@ -379,7 +374,6 @@ export function register(server, client) {
379
374
  body.expectedOutput = expectedOutput;
380
375
  const { data } = await client.PATCH("/v1/datasets/{id}/versions/{versionId}/items/{itemId}/expected-output", {
381
376
  params: {
382
- // OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
383
377
  path: { id: datasetId, versionId: resolvedVersionId, itemId },
384
378
  },
385
379
  body: body,
@@ -384,7 +384,7 @@ export function register(server, client) {
384
384
  }
385
385
  });
386
386
  // ── get_run_results ─────────────────────────────────────────────
387
- server.tool("2kw_get_run_results", "Get detailed results for an experiment run, including output, token usage, cost, and errors per dataset item.", {
387
+ server.tool("2kw_get_run_results", "Get detailed results for an experiment run, including output, token usage, duration and errors per dataset item.", {
388
388
  experimentId: z.string().describe("The experiment ID"),
389
389
  runId: z.string().describe("The run ID"),
390
390
  page: z.number().optional().default(0).describe("Page number (0-based)"),
@@ -399,11 +399,10 @@ export function register(server, client) {
399
399
  });
400
400
  const result = data;
401
401
  const lines = (result.content ?? []).map((r) => {
402
- const cost = r.estimatedCost != null ? `$${r.estimatedCost}` : "—";
403
402
  const tokens = `${r.inputTokens ?? 0}in/${r.outputTokens ?? 0}out`;
404
403
  const duration = r.durationMs != null ? `${r.durationMs}ms` : "—";
405
404
  const error = r.error ? ` ERROR: ${JSON.stringify(r.error)}` : "";
406
- return `- Item ${r.datasetItemId}: ${duration}, ${tokens}, ${cost}${error}`;
405
+ return `- Item ${r.datasetItemId}: ${duration}, ${tokens}${error}`;
407
406
  });
408
407
  return {
409
408
  content: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2kw/ai-mcp-server",
3
- "version": "7.4.0-dev.8",
3
+ "version": "8.0.0-dev.1",
4
4
  "description": "MCP server for 2kw.ai — EU-hosted AI platform: OpenAI-compatible LLM gateway, schema-driven document extraction, transcription, agents with a knowledge base, and cost observability. 199 tools for Claude Code, Cursor, and Windsurf.",
5
5
  "mcpName": "ai.2kw/mcp-server",
6
6
  "keywords": [