clinicaltrialsgov-mcp-server 1.0.2 → 1.0.4

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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # ClinicalTrials.gov MCP Server
2
2
 
3
3
  [![TypeScript](https://img.shields.io/badge/TypeScript-^5.8.3-blue.svg)](https://www.typescriptlang.org/)
4
- [![Model Context Protocol](https://img.shields.io/badge/MCP%20SDK-^1.13.0-green.svg)](https://modelcontextprotocol.io/)
5
- [![Version](https://img.shields.io/badge/Version-1.0.2-blue.svg)](./CHANGELOG.md)
4
+ [![Model Context Protocol](https://img.shields.io/badge/MCP%20SDK-^1.13.1-green.svg)](https://modelcontextprotocol.io/)
5
+ [![Version](https://img.shields.io/badge/Version-1.0.3-blue.svg)](./CHANGELOG.md)
6
6
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
7
7
  [![Status](https://img.shields.io/badge/Status-beta-orange.svg)](https://github.com/cyanheads/clinicaltrialsgov-mcp-server/issues)
8
8
  [![GitHub](https://img.shields.io/github/stars/cyanheads/clinicaltrialsgov-mcp-server?style=social)](https://github.com/cyanheads/clinicaltrialsgov-mcp-server)
@@ -31,7 +31,7 @@ export declare const config: {
31
31
  /** Logging level. From `MCP_LOG_LEVEL` env var. Default: "debug". */
32
32
  logLevel: string;
33
33
  /** Absolute path to the logs directory. From `LOGS_DIR` env var. */
34
- logsPath: string;
34
+ logsPath: string | null;
35
35
  /** Runtime environment. From `NODE_ENV` env var. Default: "development". */
36
36
  environment: string;
37
37
  /** MCP transport type ('stdio' or 'http'). From `MCP_TRANSPORT_TYPE` env var. Default: "stdio". */
@@ -86,7 +86,7 @@ export declare const config: {
86
86
  serviceRoleKey: string | undefined;
87
87
  } | undefined;
88
88
  /** Absolute path to the ClinicalTrials.gov data directory. From `CLINICALTRIALS_DATA_PATH` env var. */
89
- clinicalTrialsDataPath: string;
89
+ clinicalTrialsDataPath: string | null;
90
90
  };
91
91
  /**
92
92
  * Configured logging level for the application.
@@ -226,21 +226,38 @@ const ensureDirectory = (dirPath, rootDir, dirName) => {
226
226
  };
227
227
  // --- End Directory Ensurance Function ---
228
228
  // --- Logs Directory Handling ---
229
- const validatedLogsPath = ensureDirectory(env.LOGS_DIR, projectRoot, "logs");
229
+ let validatedLogsPath = ensureDirectory(env.LOGS_DIR, projectRoot, "logs");
230
230
  if (!validatedLogsPath) {
231
231
  if (process.stdout.isTTY) {
232
- console.error("FATAL: Logs directory configuration is invalid or could not be created. Please check permissions and path. Exiting.");
232
+ console.warn(`Warning: Custom logs directory ('${env.LOGS_DIR}') is invalid or outside the project boundary. Falling back to default.`);
233
+ }
234
+ // Try again with the absolute default path
235
+ const defaultLogsDir = path.join(projectRoot, "logs");
236
+ validatedLogsPath = ensureDirectory(defaultLogsDir, projectRoot, "logs");
237
+ if (!validatedLogsPath) {
238
+ if (process.stdout.isTTY) {
239
+ // This is just a warning now, not fatal.
240
+ console.warn("Warning: Default logs directory could not be created. File logging will be disabled.");
241
+ }
242
+ // Do not exit. validatedLogsPath remains null, and the logger will handle it.
233
243
  }
234
- process.exit(1); // Exit if logs directory is not usable
235
244
  }
236
245
  // --- End Logs Directory Handling ---
237
246
  // --- Data Directory Handling ---
238
- const validatedDataPath = ensureDirectory(env.CLINICALTRIALS_DATA_PATH, projectRoot, "data");
247
+ let validatedDataPath = ensureDirectory(env.CLINICALTRIALS_DATA_PATH, projectRoot, "data");
239
248
  if (!validatedDataPath) {
240
249
  if (process.stdout.isTTY) {
241
- console.error("FATAL: Data directory configuration is invalid or could not be created. Please check permissions and path. Exiting.");
250
+ console.warn(`Warning: Custom data directory ('${env.CLINICALTRIALS_DATA_PATH}') is invalid or outside the project boundary. Falling back to default.`);
251
+ }
252
+ // Try again with the absolute default path
253
+ const defaultDataDir = path.join(projectRoot, "data");
254
+ validatedDataPath = ensureDirectory(defaultDataDir, projectRoot, "data");
255
+ if (!validatedDataPath) {
256
+ if (process.stdout.isTTY) {
257
+ console.warn("Warning: Default data directory could not be created. Features requiring local data caching will be disabled.");
258
+ }
259
+ // Do not exit. validatedDataPath remains null.
242
260
  }
243
- process.exit(1); // Exit if data directory is not usable
244
261
  }
245
262
  // --- End Data Directory Handling ---
246
263
  /**
@@ -49,7 +49,7 @@ export declare class ClinicalTrialsGovService {
49
49
  }, context: RequestContext): Promise<any>;
50
50
  /**
51
51
  * A generic fetch method that handles backing up the response.
52
- * It always fetches live data and writes it to a backup file.
52
+ * It always fetches live data and writes it to a backup file if the data path is configured.
53
53
  * @param url - The URL to fetch.
54
54
  * @param fileName - The file name to use for the backup.
55
55
  * @param context - The request context for logging.
@@ -132,14 +132,13 @@ export class ClinicalTrialsGovService {
132
132
  }
133
133
  /**
134
134
  * A generic fetch method that handles backing up the response.
135
- * It always fetches live data and writes it to a backup file.
135
+ * It always fetches live data and writes it to a backup file if the data path is configured.
136
136
  * @param url - The URL to fetch.
137
137
  * @param fileName - The file name to use for the backup.
138
138
  * @param context - The request context for logging.
139
139
  * @returns A promise that resolves with the fetched data.
140
140
  */
141
141
  async fetchAndBackup(url, fileName, context) {
142
- const filePath = path.join(config.clinicalTrialsDataPath, fileName);
143
142
  logger.debug(`[API] Fetching from ${url}`, context);
144
143
  const fetchOptions = {
145
144
  headers: { Accept: "application/json" },
@@ -160,15 +159,21 @@ export class ClinicalTrialsGovService {
160
159
  });
161
160
  }
162
161
  const data = (await response.json());
163
- try {
164
- writeFileSync(filePath, JSON.stringify(data, null, 2));
165
- logger.debug(`[Backup] Wrote to ${filePath}`, context);
162
+ if (config.clinicalTrialsDataPath) {
163
+ const filePath = path.join(config.clinicalTrialsDataPath, fileName);
164
+ try {
165
+ writeFileSync(filePath, JSON.stringify(data, null, 2));
166
+ logger.debug(`[Backup] Wrote to ${filePath}`, context);
167
+ }
168
+ catch (error) {
169
+ logger.error(`Failed to write backup file: ${filePath}`, {
170
+ ...context,
171
+ error,
172
+ });
173
+ }
166
174
  }
167
- catch (error) {
168
- logger.error(`Failed to write backup file: ${filePath}`, {
169
- ...context,
170
- error,
171
- });
175
+ else {
176
+ logger.debug("[Backup] Skipping backup because data path is not configured.", context);
172
177
  }
173
178
  return data;
174
179
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clinicaltrialsgov-mcp-server",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "A Model Context Protocol (MCP) Server providing LLM tools for the official ClinicalTrials.gov REST API. Search and retrieve clinical trial data, including study details and more",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -35,21 +35,19 @@
35
35
  "db:duckdb-example": "MCP_LOG_LEVEL=debug tsc && node dist/storage/duckdbExample.js"
36
36
  },
37
37
  "dependencies": {
38
- "@hono/node-server": "^1.14.4",
39
- "@modelcontextprotocol/sdk": "^1.13.0",
40
- "@supabase/supabase-js": "^2.50.0",
41
- "@types/jsonwebtoken": "^9.0.10",
42
- "@types/node": "^24.0.3",
38
+ "@hono/node-server": "^1.15.0",
39
+ "@modelcontextprotocol/sdk": "^1.15.0",
40
+ "@supabase/supabase-js": "^2.50.3",
41
+ "@types/node": "^24.0.10",
43
42
  "@types/sanitize-html": "^2.16.0",
44
43
  "@types/validator": "13.15.2",
45
44
  "chrono-node": "^2.8.0",
46
45
  "dotenv": "^16.5.0",
47
- "hono": "^4.8.2",
46
+ "hono": "^4.8.4",
48
47
  "ignore": "^7.0.5",
49
48
  "jose": "^6.0.11",
50
- "jsonwebtoken": "^9.0.2",
51
49
  "npm": "^11.4.2",
52
- "openai": "^5.6.0",
50
+ "openai": "^5.8.2",
53
51
  "partial-json": "^0.1.7",
54
52
  "sanitize-html": "^2.17.0",
55
53
  "tiktoken": "^1.0.21",
@@ -58,7 +56,8 @@
58
56
  "validator": "13.15.15",
59
57
  "winston": "^3.17.0",
60
58
  "winston-transport": "^4.9.0",
61
- "zod": "^3.25.67"
59
+ "js-yaml": "^4.1.0",
60
+ "zod": "^3.25.74"
62
61
  },
63
62
  "keywords": [
64
63
  "typescript",
@@ -92,8 +91,7 @@
92
91
  "@types/js-yaml": "^4.0.9",
93
92
  "axios": "^1.10.0",
94
93
  "depcheck": "^1.4.7",
95
- "js-yaml": "^4.1.0",
96
- "prettier": "^3.5.3",
97
- "typedoc": "^0.28.5"
94
+ "prettier": "^3.6.2",
95
+ "typedoc": "^0.28.7"
98
96
  }
99
97
  }