@ncodeuy/medplum-mcp 0.1.2 → 0.2.0

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 (3) hide show
  1. package/README.md +33 -10
  2. package/dist/config.js +45 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -31,7 +31,29 @@ npm install @ncodeuy/medplum-mcp
31
31
 
32
32
  ### Configure
33
33
 
34
- The server reads configuration from the `MEDPLUM_PROJECTS` environment variable a JSON object mapping environment names to their connection details:
34
+ Set one environment variable per field, using the pattern `MEDPLUM_PROJECT_<NAME>_<FIELD>`:
35
+
36
+ ```bash
37
+ # Required
38
+ MEDPLUM_PROJECT_STAGING_CLIENT_ID=staging-client-id
39
+ MEDPLUM_PROJECT_STAGING_CLIENT_SECRET=staging-secret
40
+
41
+ # Optional (defaults to https://api.medplum.com/)
42
+ MEDPLUM_PROJECT_STAGING_BASE_URL=https://staging.example.com/
43
+ MEDPLUM_PROJECT_STAGING_PROJECT_ID=proj-staging
44
+
45
+ # Add more projects by changing the name segment
46
+ MEDPLUM_PROJECT_PRODUCTION_CLIENT_ID=prod-client-id
47
+ MEDPLUM_PROJECT_PRODUCTION_CLIENT_SECRET=prod-secret
48
+
49
+ # Optional — defaults to the first project found
50
+ MEDPLUM_DEFAULT_PROJECT=staging
51
+ ```
52
+
53
+ <details>
54
+ <summary>Alternative: JSON configuration</summary>
55
+
56
+ You can also use the `MEDPLUM_PROJECTS` environment variable with a JSON object:
35
57
 
36
58
  ```bash
37
59
  MEDPLUM_PROJECTS='{
@@ -42,16 +64,15 @@ MEDPLUM_PROJECTS='{
42
64
  "projectId": "proj-staging"
43
65
  },
44
66
  "production": {
45
- "baseUrl": "https://api.medplum.com/",
46
67
  "clientId": "prod-client-id",
47
- "clientSecret": "prod-secret",
48
- "projectId": "proj-prod"
68
+ "clientSecret": "prod-secret"
49
69
  }
50
70
  }'
51
- MEDPLUM_DEFAULT_PROJECT=staging
52
71
  ```
53
72
 
54
- `MEDPLUM_DEFAULT_PROJECT` is optional and defaults to the first entry.
73
+ Flat env vars take priority when both are set.
74
+
75
+ </details>
55
76
 
56
77
  ### Use with Claude Desktop
57
78
 
@@ -64,7 +85,8 @@ Add the server to your Claude Desktop configuration (`claude_desktop_config.json
64
85
  "command": "npx",
65
86
  "args": ["@ncodeuy/medplum-mcp"],
66
87
  "env": {
67
- "MEDPLUM_PROJECTS": "{\"default\":{\"clientId\":\"your-client-id\",\"clientSecret\":\"your-client-secret\"}}"
88
+ "MEDPLUM_PROJECT_DEFAULT_CLIENT_ID": "your-client-id",
89
+ "MEDPLUM_PROJECT_DEFAULT_CLIENT_SECRET": "your-client-secret"
68
90
  }
69
91
  }
70
92
  }
@@ -76,11 +98,12 @@ Add the server to your Claude Desktop configuration (`claude_desktop_config.json
76
98
  Add the server to your Claude Code MCP settings:
77
99
 
78
100
  ```bash
79
- claude mcp add medplum -- npx @ncodeuy/medplum-mcp
101
+ claude mcp add medplum \
102
+ -e MEDPLUM_PROJECT_DEFAULT_CLIENT_ID=your-client-id \
103
+ -e MEDPLUM_PROJECT_DEFAULT_CLIENT_SECRET=your-client-secret \
104
+ -- npx @ncodeuy/medplum-mcp
80
105
  ```
81
106
 
82
- Then set the required environment variables in your shell before launching Claude Code.
83
-
84
107
  ## Development
85
108
 
86
109
  ```bash
package/dist/config.js CHANGED
@@ -1,4 +1,46 @@
1
+ const ENV_PREFIX = "MEDPLUM_PROJECT_";
2
+ const CLIENT_ID_SUFFIX = "_CLIENT_ID";
3
+ function loadFromEnvVars() {
4
+ const projects = {};
5
+ for (const key of Object.keys(process.env)) {
6
+ if (!key.startsWith(ENV_PREFIX) || !key.endsWith(CLIENT_ID_SUFFIX)) {
7
+ continue;
8
+ }
9
+ const name = key
10
+ .slice(ENV_PREFIX.length, -CLIENT_ID_SUFFIX.length)
11
+ .toLowerCase();
12
+ if (!name)
13
+ continue;
14
+ const prefix = `${ENV_PREFIX}${key.slice(ENV_PREFIX.length, -CLIENT_ID_SUFFIX.length)}_`;
15
+ const clientId = process.env[key];
16
+ const clientSecret = process.env[`${prefix}CLIENT_SECRET`];
17
+ if (!clientSecret) {
18
+ throw new Error(`${prefix}CLIENT_SECRET is required when ${key} is set.`);
19
+ }
20
+ projects[name] = {
21
+ baseUrl: process.env[`${prefix}BASE_URL`] || "https://api.medplum.com/",
22
+ clientId: clientId,
23
+ clientSecret,
24
+ projectId: process.env[`${prefix}PROJECT_ID`],
25
+ };
26
+ }
27
+ return Object.keys(projects).length > 0 ? projects : undefined;
28
+ }
29
+ function resolveDefault(projects) {
30
+ const keys = Object.keys(projects);
31
+ const defaultProject = process.env.MEDPLUM_DEFAULT_PROJECT || keys[0];
32
+ if (!projects[defaultProject]) {
33
+ throw new Error(`MEDPLUM_DEFAULT_PROJECT "${defaultProject}" not found. Available: ${keys.join(", ")}`);
34
+ }
35
+ return { projects, defaultProject };
36
+ }
1
37
  export function loadConfig() {
38
+ // 1. Try flat environment variables
39
+ const flatProjects = loadFromEnvVars();
40
+ if (flatProjects) {
41
+ return resolveDefault(flatProjects);
42
+ }
43
+ // 2. Fall back to MEDPLUM_PROJECTS JSON
2
44
  const projectsJson = process.env.MEDPLUM_PROJECTS;
3
45
  if (projectsJson) {
4
46
  let parsed;
@@ -28,11 +70,8 @@ export function loadConfig() {
28
70
  if (keys.length === 0) {
29
71
  throw new Error("MEDPLUM_PROJECTS must contain at least one environment.");
30
72
  }
31
- const defaultProject = process.env.MEDPLUM_DEFAULT_PROJECT || keys[0];
32
- if (!projects[defaultProject]) {
33
- throw new Error(`MEDPLUM_DEFAULT_PROJECT "${defaultProject}" not found in MEDPLUM_PROJECTS. Available: ${keys.join(", ")}`);
34
- }
35
- return { projects, defaultProject };
73
+ return resolveDefault(projects);
36
74
  }
37
- throw new Error("Missing MEDPLUM_PROJECTS environment variable. Set it to a JSON object mapping environment names to project configs.");
75
+ // 3. Nothing configured
76
+ throw new Error("Missing configuration. Set MEDPLUM_PROJECT_<NAME>_CLIENT_ID environment variables, or set MEDPLUM_PROJECTS as a JSON object.");
38
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ncodeuy/medplum-mcp",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",