@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.
- package/README.md +33 -10
- package/dist/config.js +45 -6
- 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
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|