@velocms/mcp 0.1.1 → 0.1.2

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/env.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  /**
2
2
  * Pure env-resolution helper — kept separate from `index.ts` (which has a
3
3
  * `#!/usr/bin/env node` shebang and starts the stdio server as a side effect
4
- * on import) so the fail-fast "missing env var" behavior is unit-testable
5
- * without spawning a subprocess or calling `process.exit`.
4
+ * on import) so the missing-env-var handling is unit-testable without
5
+ * spawning a subprocess. Since 0.1.2 a missing variable no longer exits the
6
+ * process at startup — the server boots for introspection and the error is
7
+ * returned per tool call instead.
6
8
  */
7
9
  export interface VeloCmsEnvConfig {
8
10
  siteUrl: string;
@@ -20,5 +22,5 @@ export type VeloCmsEnvResolution = {
20
22
  * (defaults to `process.env`). Never logs the resolved values.
21
23
  */
22
24
  export declare function resolveEnvConfig(env?: NodeJS.ProcessEnv): VeloCmsEnvResolution;
23
- /** Human-readable message for the missing-env-var fail-fast path (stderr only, never stdout). */
25
+ /** Human-readable message for the missing-env-var path (stderr warning at boot + per-tool-call error text; never stdout). */
24
26
  export declare function formatMissingEnvMessage(missing: string[]): string;
package/dist/env.js CHANGED
@@ -1,8 +1,10 @@
1
1
  /**
2
2
  * Pure env-resolution helper — kept separate from `index.ts` (which has a
3
3
  * `#!/usr/bin/env node` shebang and starts the stdio server as a side effect
4
- * on import) so the fail-fast "missing env var" behavior is unit-testable
5
- * without spawning a subprocess or calling `process.exit`.
4
+ * on import) so the missing-env-var handling is unit-testable without
5
+ * spawning a subprocess. Since 0.1.2 a missing variable no longer exits the
6
+ * process at startup — the server boots for introspection and the error is
7
+ * returned per tool call instead.
6
8
  */
7
9
  /**
8
10
  * Reads `VELOCMS_SITE_URL` + `VELOCMS_API_KEY` from the given environment
@@ -21,7 +23,7 @@ export function resolveEnvConfig(env = process.env) {
21
23
  }
22
24
  return { ok: true, config: { siteUrl, apiKey } };
23
25
  }
24
- /** Human-readable message for the missing-env-var fail-fast path (stderr only, never stdout). */
26
+ /** Human-readable message for the missing-env-var path (stderr warning at boot + per-tool-call error text; never stdout). */
25
27
  export function formatMissingEnvMessage(missing) {
26
28
  return (`[velocms-mcp] Missing required environment variable(s): ${missing.join(", ")}.\n` +
27
29
  " VELOCMS_SITE_URL — your blog's base URL, e.g. https://myblog.velocms.org (or a bound custom domain)\n" +
package/dist/index.js CHANGED
@@ -27,12 +27,30 @@ function formatError(err) {
27
27
  return `Error: ${String(err)}`;
28
28
  }
29
29
  async function main() {
30
+ // Env resolution is LAZY (first tool call), not a startup gate: MCP
31
+ // registries (e.g. Glama) boot the server without credentials and only
32
+ // need it to start + answer introspection (initialize / tools/list).
33
+ // A missing key therefore surfaces as a helpful per-call tool error
34
+ // inside the MCP client instead of a dead server. Warn once on stderr
35
+ // so interactive users still see the misconfiguration immediately.
30
36
  const resolution = resolveEnvConfig();
31
- if (!resolution.ok) {
37
+ let client = null;
38
+ if (resolution.ok) {
39
+ client = new VeloCmsClient(resolution.config);
40
+ }
41
+ else {
32
42
  console.error(formatMissingEnvMessage(resolution.missing));
33
- process.exit(1);
34
43
  }
35
- const client = new VeloCmsClient(resolution.config);
44
+ /** Returns the API client, or the missing-env error message if unconfigured. */
45
+ function requireClient() {
46
+ if (client)
47
+ return client;
48
+ const late = resolveEnvConfig();
49
+ if (!late.ok)
50
+ return formatMissingEnvMessage(late.missing);
51
+ client = new VeloCmsClient(late.config);
52
+ return client;
53
+ }
36
54
  const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION });
37
55
  for (const [name, tool] of Object.entries(tools)) {
38
56
  server.registerTool(name, {
@@ -40,8 +58,12 @@ async function main() {
40
58
  description: tool.description,
41
59
  inputSchema: tool.inputSchema,
42
60
  }, async (args) => {
61
+ const resolved = requireClient();
62
+ if (typeof resolved === "string") {
63
+ return { content: [{ type: "text", text: resolved }], isError: true };
64
+ }
43
65
  try {
44
- const result = await tool.handler(client, (args ?? {}));
66
+ const result = await tool.handler(resolved, (args ?? {}));
45
67
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
46
68
  }
47
69
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velocms/mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "MCP server for VeloCMS — draft, publish, and manage your blog (posts, media, comments, members) from Claude Code, Claude Desktop, Cursor, or any MCP client.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -48,17 +48,20 @@
48
48
  "prepublishOnly": "npm run build"
49
49
  },
50
50
  "dependencies": {
51
- "@modelcontextprotocol/sdk": "^1.12.1",
52
- "zod": "^3.24.1"
51
+ "@modelcontextprotocol/sdk": "1.22.0",
52
+ "zod": "3.25.76"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@types/node": "^20.14.0",
56
- "typescript": "^5.6.0",
56
+ "typescript": "5.6.3",
57
57
  "vitest": "^2.1.0"
58
58
  },
59
59
  "publishConfig": {
60
60
  "access": "public",
61
61
  "registry": "https://registry.npmjs.org/"
62
62
  },
63
- "mcpName": "org.velocms/mcp"
63
+ "mcpName": "org.velocms/mcp",
64
+ "overrides": {
65
+ "zod": "3.25.76"
66
+ }
64
67
  }