@systemdox/mcp-server 0.1.23 → 0.1.25

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/cli.js CHANGED
@@ -10,6 +10,23 @@ var __export = (target, all) => {
10
10
  };
11
11
 
12
12
  // src/lib/config.ts
13
+ function requireHttpsApiUrl(apiUrl) {
14
+ let parsed;
15
+ try {
16
+ parsed = new URL(apiUrl);
17
+ } catch {
18
+ throw new Error(
19
+ `SYSTEMDOX_API_URL is not a valid URL: ${apiUrl}`
20
+ );
21
+ }
22
+ if (parsed.protocol === "https:") return apiUrl;
23
+ if (parsed.protocol === "http:" && LOOPBACK_HOSTS.has(parsed.hostname)) {
24
+ return apiUrl;
25
+ }
26
+ throw new Error(
27
+ `SYSTEMDOX_API_URL must use https:// \u2014 refusing to send the API key over ${parsed.protocol}// in cleartext. Got: ${apiUrl}`
28
+ );
29
+ }
13
30
  function loadConfig() {
14
31
  const apiKey = process.env.SYSTEMDOX_API_KEY;
15
32
  if (!apiKey) {
@@ -17,16 +34,22 @@ function loadConfig() {
17
34
  "SYSTEMDOX_API_KEY is required. Generate one at your SystemDox settings page."
18
35
  );
19
36
  }
37
+ const apiUrl = requireHttpsApiUrl(
38
+ process.env.SYSTEMDOX_API_URL ?? API_URL_DEFAULT
39
+ );
20
40
  return {
21
41
  apiKey,
22
- apiUrl: process.env.SYSTEMDOX_API_URL ?? "https://api.puglieseweb.com/systemdox",
42
+ apiUrl,
23
43
  cacheTtlMs: parseInt(process.env.SYSTEMDOX_CACHE_TTL ?? "300", 10) * 1e3,
24
44
  defaultOrg: process.env.SYSTEMDOX_DEFAULT_ORG
25
45
  };
26
46
  }
47
+ var API_URL_DEFAULT, LOOPBACK_HOSTS;
27
48
  var init_config = __esm({
28
49
  "src/lib/config.ts"() {
29
50
  "use strict";
51
+ API_URL_DEFAULT = "https://api.puglieseweb.com/systemdox";
52
+ LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
30
53
  }
31
54
  });
32
55
 
@@ -1979,7 +2002,7 @@ var init_server = __esm({
1979
2002
  init_create_project_rule();
1980
2003
  init_get_prompt_templates();
1981
2004
  init_create_prompt_template();
1982
- SERVER_VERSION = true ? "0.1.23" : "0.0.0-dev";
2005
+ SERVER_VERSION = true ? "0.1.25" : "0.0.0-dev";
1983
2006
  }
1984
2007
  });
1985
2008
 
@@ -2012,12 +2035,12 @@ var init_index = __esm({
2012
2035
  });
2013
2036
 
2014
2037
  // src/cli.ts
2015
- import { readFile, writeFile } from "fs/promises";
2038
+ init_config();
2039
+ import { readFile, writeFile, chmod } from "fs/promises";
2016
2040
  import { existsSync } from "fs";
2017
2041
  import { homedir } from "os";
2018
2042
  import { join } from "path";
2019
2043
  import { createInterface } from "readline";
2020
- var API_URL_DEFAULT = "https://api.puglieseweb.com/systemdox";
2021
2044
  function prompt(question) {
2022
2045
  const rl = createInterface({ input: process.stdin, output: process.stdout });
2023
2046
  return new Promise((resolve) => {
@@ -2093,7 +2116,11 @@ async function writeConfig(path, config2) {
2093
2116
  const { mkdir } = await import("fs/promises");
2094
2117
  await mkdir(dir, { recursive: true });
2095
2118
  }
2096
- await writeFile(path, JSON.stringify(config2, null, 2) + "\n");
2119
+ await writeFile(path, JSON.stringify(config2, null, 2) + "\n", { mode: 384 });
2120
+ try {
2121
+ await chmod(path, 384);
2122
+ } catch {
2123
+ }
2097
2124
  }
2098
2125
  function serverEntry(apiKey, apiUrl) {
2099
2126
  const entry = {
@@ -2121,6 +2148,14 @@ async function setup() {
2121
2148
  ` API URL [${API_URL_DEFAULT}]: `
2122
2149
  );
2123
2150
  const apiUrl = apiUrlInput || API_URL_DEFAULT;
2151
+ try {
2152
+ requireHttpsApiUrl(apiUrl);
2153
+ } catch (err) {
2154
+ console.error(`
2155
+ Error: ${err.message}
2156
+ `);
2157
+ process.exit(1);
2158
+ }
2124
2159
  console.log("\n Validating API key...");
2125
2160
  const valid = await validateApiKey(apiKey, apiUrl);
2126
2161
  if (!valid) {
package/dist/http.js CHANGED
@@ -1825,7 +1825,7 @@ function registerCreatePromptTemplate(server, apiClient) {
1825
1825
  }
1826
1826
 
1827
1827
  // src/server.ts
1828
- var SERVER_VERSION = true ? "0.1.23" : "0.0.0-dev";
1828
+ var SERVER_VERSION = true ? "0.1.25" : "0.0.0-dev";
1829
1829
  function createServer(apiClient) {
1830
1830
  const server = new McpServer({
1831
1831
  name: "systemdox-mcp-server",
package/dist/index.js CHANGED
@@ -4,6 +4,25 @@
4
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
5
 
6
6
  // src/lib/config.ts
7
+ var API_URL_DEFAULT = "https://api.puglieseweb.com/systemdox";
8
+ var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
9
+ function requireHttpsApiUrl(apiUrl) {
10
+ let parsed;
11
+ try {
12
+ parsed = new URL(apiUrl);
13
+ } catch {
14
+ throw new Error(
15
+ `SYSTEMDOX_API_URL is not a valid URL: ${apiUrl}`
16
+ );
17
+ }
18
+ if (parsed.protocol === "https:") return apiUrl;
19
+ if (parsed.protocol === "http:" && LOOPBACK_HOSTS.has(parsed.hostname)) {
20
+ return apiUrl;
21
+ }
22
+ throw new Error(
23
+ `SYSTEMDOX_API_URL must use https:// \u2014 refusing to send the API key over ${parsed.protocol}// in cleartext. Got: ${apiUrl}`
24
+ );
25
+ }
7
26
  function loadConfig() {
8
27
  const apiKey = process.env.SYSTEMDOX_API_KEY;
9
28
  if (!apiKey) {
@@ -11,9 +30,12 @@ function loadConfig() {
11
30
  "SYSTEMDOX_API_KEY is required. Generate one at your SystemDox settings page."
12
31
  );
13
32
  }
33
+ const apiUrl = requireHttpsApiUrl(
34
+ process.env.SYSTEMDOX_API_URL ?? API_URL_DEFAULT
35
+ );
14
36
  return {
15
37
  apiKey,
16
- apiUrl: process.env.SYSTEMDOX_API_URL ?? "https://api.puglieseweb.com/systemdox",
38
+ apiUrl,
17
39
  cacheTtlMs: parseInt(process.env.SYSTEMDOX_CACHE_TTL ?? "300", 10) * 1e3,
18
40
  defaultOrg: process.env.SYSTEMDOX_DEFAULT_ORG
19
41
  };
@@ -1806,7 +1828,7 @@ function registerCreatePromptTemplate(server2, apiClient2) {
1806
1828
  }
1807
1829
 
1808
1830
  // src/server.ts
1809
- var SERVER_VERSION = true ? "0.1.23" : "0.0.0-dev";
1831
+ var SERVER_VERSION = true ? "0.1.25" : "0.0.0-dev";
1810
1832
  function createServer(apiClient2) {
1811
1833
  const server2 = new McpServer({
1812
1834
  name: "systemdox-mcp-server",
@@ -4,4 +4,15 @@ export interface ServerConfig {
4
4
  cacheTtlMs: number;
5
5
  defaultOrg: string | undefined;
6
6
  }
7
+ export declare const API_URL_DEFAULT = "https://api.puglieseweb.com/systemdox";
8
+ /**
9
+ * Fail closed on a non-https API URL. The API key travels as a bearer token in
10
+ * the Authorization header on every request, so an http:// URL would leak it in
11
+ * cleartext. Reject rather than downgrade. Returns the URL unchanged when valid.
12
+ *
13
+ * http://localhost is allowed: see LOOPBACK_HOSTS. Local development and the
14
+ * MCP release gate (scripts/mcp-release-gate.mjs, which boots the published
15
+ * server against an http stub on 127.0.0.1) both depend on it.
16
+ */
17
+ export declare function requireHttpsApiUrl(apiUrl: string): string;
7
18
  export declare function loadConfig(): ServerConfig;
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/lib/config.ts
4
+ var API_URL_DEFAULT = "https://api.puglieseweb.com/systemdox";
5
+ var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
6
+ function requireHttpsApiUrl(apiUrl) {
7
+ let parsed;
8
+ try {
9
+ parsed = new URL(apiUrl);
10
+ } catch {
11
+ throw new Error(
12
+ `SYSTEMDOX_API_URL is not a valid URL: ${apiUrl}`
13
+ );
14
+ }
15
+ if (parsed.protocol === "https:") return apiUrl;
16
+ if (parsed.protocol === "http:" && LOOPBACK_HOSTS.has(parsed.hostname)) {
17
+ return apiUrl;
18
+ }
19
+ throw new Error(
20
+ `SYSTEMDOX_API_URL must use https:// \u2014 refusing to send the API key over ${parsed.protocol}// in cleartext. Got: ${apiUrl}`
21
+ );
22
+ }
23
+ function loadConfig() {
24
+ const apiKey = process.env.SYSTEMDOX_API_KEY;
25
+ if (!apiKey) {
26
+ throw new Error(
27
+ "SYSTEMDOX_API_KEY is required. Generate one at your SystemDox settings page."
28
+ );
29
+ }
30
+ const apiUrl = requireHttpsApiUrl(
31
+ process.env.SYSTEMDOX_API_URL ?? API_URL_DEFAULT
32
+ );
33
+ return {
34
+ apiKey,
35
+ apiUrl,
36
+ cacheTtlMs: parseInt(process.env.SYSTEMDOX_CACHE_TTL ?? "300", 10) * 1e3,
37
+ defaultOrg: process.env.SYSTEMDOX_DEFAULT_ORG
38
+ };
39
+ }
40
+ export {
41
+ API_URL_DEFAULT,
42
+ loadConfig,
43
+ requireHttpsApiUrl
44
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@systemdox/mcp-server",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "mcpName": "io.github.puglieseweb/systemdox",
5
5
  "type": "module",
6
6
  "description": "Give AI coding agents your architecture context over MCP — checks, specs, ADRs, project rules, and docs from SystemDox, delivered at write time",