@vorim/mcp-server 1.1.4 → 1.1.5

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.
Files changed (2) hide show
  1. package/build/index.js +35 -5
  2. package/package.json +1 -1
package/build/index.js CHANGED
@@ -21,6 +21,18 @@
21
21
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
22
22
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
23
23
  import { z } from "zod";
24
+ // SECURITY: The MCP server uses a single process-wide Vorim API key
25
+ // taken from VORIM_API_KEY at startup. The stdio transport between
26
+ // the MCP host (e.g. Claude Desktop) and this process carries NO
27
+ // per-call auth — every tool call is attributed to the configured
28
+ // key. Two consequences:
29
+ // 1. Scope the key tightly. The key's scopes (audit:read,
30
+ // audit:write, agent:write, etc.) determine which MCP tools
31
+ // will actually work; a least-privilege scoped key reduces
32
+ // blast radius if the host environment is compromised.
33
+ // 2. Do not share a key across MCP installations. Each user /
34
+ // machine should mint its own key so revocation surgically
35
+ // kills exactly one installation.
24
36
  const API_KEY = process.env.VORIM_API_KEY || "";
25
37
  const BASE_URL = (process.env.VORIM_BASE_URL || "https://api.vorim.ai").replace(/\/$/, "");
26
38
  if (!API_KEY) {
@@ -32,7 +44,7 @@ if (!API_KEY) {
32
44
  // server's advertised version stay in sync with package.json.
33
45
  // require() works in the CommonJS build path; for the ESM-only build
34
46
  // we fall back to a constant that must match package.json.
35
- const MCP_VERSION = "1.1.4";
47
+ const MCP_VERSION = "1.1.5";
36
48
  /**
37
49
  * URL-encode a user-supplied path segment. Agent ids, scopes, and
38
50
  * chain ids all reach the API via path interpolation; raw slashes or
@@ -52,6 +64,22 @@ async function vorimRequest(method, path, body) {
52
64
  },
53
65
  body: body ? JSON.stringify(body) : undefined,
54
66
  });
67
+ // Hand out clearer error messages for the common cases an MCP user
68
+ // will see. Auth: the API key is wrong or revoked. Scope: the key
69
+ // is missing the scope this route requires (e.g. audit:write).
70
+ if (response.status === 401) {
71
+ throw new Error("Vorim API key is invalid, revoked, or expired. Check VORIM_API_KEY.");
72
+ }
73
+ if (response.status === 403) {
74
+ const j = await response.json().catch(() => ({}));
75
+ const err = j.error;
76
+ const code = err?.code;
77
+ if (code === "INSUFFICIENT_SCOPE") {
78
+ throw new Error(err?.message ||
79
+ "Vorim API key is missing the scope required for this operation. Mint a new key with the required scope and update VORIM_API_KEY.");
80
+ }
81
+ throw new Error(err?.message || "Vorim API rejected with 403");
82
+ }
55
83
  const json = await response.json();
56
84
  if (!response.ok) {
57
85
  const err = json.error;
@@ -84,9 +112,10 @@ const server = new McpServer({
84
112
  server.registerTool("vorim_ping", {
85
113
  description: "Check Vorim AI API health and connectivity. Returns status, version, and service health.",
86
114
  inputSchema: {},
115
+ annotations: { readOnlyHint: true },
87
116
  }, async () => {
88
117
  const response = await fetch(`${BASE_URL}/health`, {
89
- headers: { "User-Agent": "vorim-mcp-server/1.0.0" },
118
+ headers: { "User-Agent": `vorim-mcp-server/${MCP_VERSION}` },
90
119
  });
91
120
  const data = await response.json();
92
121
  return text(data);
@@ -235,11 +264,12 @@ server.registerTool("vorim_emit_event", {
235
264
  return text(data);
236
265
  });
237
266
  server.registerTool("vorim_export_audit", {
238
- description: "Export a signed audit bundle for a date range. Returns events with a SHA-256 manifest for tamper-proof verification.",
267
+ description: "Export a signed audit bundle for a date range. Returns events with a SHA-256 manifest for tamper-proof verification. Window must be <= 90 days; the server returns 400 if from > to or the range exceeds the cap. The returned bundle has up to 1,000,000 events; if truncated, the response carries `truncated: true` and the caller should re-export a narrower window.",
239
268
  inputSchema: {
240
- from: z.string().describe("Start date (ISO 8601)"),
241
- to: z.string().describe("End date (ISO 8601)"),
269
+ from: z.string().describe("Start date in ISO 8601 (e.g. 2026-06-01T00:00:00Z)"),
270
+ to: z.string().describe("End date in ISO 8601 (must be on or after `from`; window <= 90 days)"),
242
271
  },
272
+ annotations: { readOnlyHint: true },
243
273
  }, async ({ from, to }) => {
244
274
  const result = await vorimPost("/audit/export", { from, to });
245
275
  return text(result);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vorim/mcp-server",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "mcpName": "io.github.Kzino/vorim-mcp-server",
5
5
  "description": "MCP server for Vorim AI — AI agent identity, permissions, and audit trails",
6
6
  "type": "module",