dynmcp 0.3.1 → 0.4.1
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 +39 -135
- package/dist/index.cjs +549 -145
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +549 -145
- package/dist/index.js.map +1 -1
- package/package.json +3 -5
- package/schema/mcp-config.json +0 -126
package/README.md
CHANGED
|
@@ -2,26 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
A proxy MCP that exposes meta-tools so agents can discover and call upstream MCP tools on demand, without loading every tool schema into the context window.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Full documentation:** [dynamicmcp.tools](https://dynamicmcp.tools)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Features
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- **Two meta-tools instead of N.** Wraps one or more upstream MCPs and exposes only `discover_tool` and `use_tool` to the agent. Full schemas of irrelevant tools never enter context.
|
|
10
|
+
- **Dynamic discovery of whole MCPs.** Mark MCPs with a `description` in your config and they stay disconnected until the agent calls `load_mcp` — deferring entire MCP catalogs out of context until they are actually needed.
|
|
11
|
+
- **Full-fidelity proxying.** Resources, prompts, completion, logging, notifications, cancellation, progress, and server-initiated requests (sampling, elicitation, roots) pass through unchanged.
|
|
12
|
+
- **Multiple transports for upstreams.** `stdio` child processes, `streamable-http`, and `sse` — all in one config.
|
|
13
|
+
- **JSON or YAML config** with shell-style `${VAR}` and `${VAR:-default}` environment variable interpolation.
|
|
14
|
+
- **Local-only.** Single Node.js process speaking MCP over stdio. No daemon, no remote endpoint.
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
## Getting Started
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
- **`use_tool`** — executes a tool by name, proxying the call to the upstream MCP and returning its output unchanged.
|
|
15
|
-
|
|
16
|
-
The agent workflow: scan the catalog in `discover_tool`'s description to find relevant tools, call `discover_tool` to load the full schema of the one it needs, then call `use_tool` to execute it. Full schemas of tools the agent never needs never enter the context window.
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
Requires Node.js >= 20.
|
|
21
|
-
|
|
22
|
-
### Single MCP (quick start)
|
|
23
|
-
|
|
24
|
-
Prefix any MCP invocation with `dynmcp --`:
|
|
18
|
+
### Wrap a single upstream MCP
|
|
25
19
|
|
|
26
20
|
```bash
|
|
27
21
|
# Before — tool schemas go straight into context
|
|
@@ -31,29 +25,15 @@ npx -y chrome-devtools-mcp@latest
|
|
|
31
25
|
npx dynmcp@latest -- npx -y chrome-devtools-mcp@latest
|
|
32
26
|
```
|
|
33
27
|
|
|
34
|
-
Everything after `--` is the command used to launch the upstream MCP.
|
|
35
|
-
|
|
36
|
-
### Multiple MCPs (config file)
|
|
37
|
-
|
|
38
|
-
To proxy several MCPs at once, create a config file:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
# Auto-discover mcp.json or .mcp.json in cwd
|
|
42
|
-
npx dynmcp@latest
|
|
43
|
-
|
|
44
|
-
# Or specify explicitly
|
|
45
|
-
npx dynmcp@latest --config ./my-config.json
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
When using a config file, tool names are namespaced as `<mcp-name>/<tool-name>` to avoid collisions.
|
|
28
|
+
Everything after `--` is the command used to launch the upstream MCP. In this mode tool names are exposed as-is (no namespace prefix).
|
|
49
29
|
|
|
50
|
-
|
|
30
|
+
### Proxy multiple MCPs from a config file
|
|
51
31
|
|
|
52
|
-
|
|
32
|
+
Create a `mcp.json` in your project root:
|
|
53
33
|
|
|
54
34
|
```json
|
|
55
35
|
{
|
|
56
|
-
"$schema": "https://
|
|
36
|
+
"$schema": "https://dynamicmcp.tools/config.json",
|
|
57
37
|
"mcp": {
|
|
58
38
|
"chrome-devtools": {
|
|
59
39
|
"transport": "stdio",
|
|
@@ -64,127 +44,51 @@ The config file declares upstream MCPs under a top-level `mcp` key. Three transp
|
|
|
64
44
|
"transport": "stdio",
|
|
65
45
|
"command": "npx",
|
|
66
46
|
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
67
|
-
},
|
|
68
|
-
"aws-knowledge": {
|
|
69
|
-
"transport": "streamable-http",
|
|
70
|
-
"url": "https://knowledge-mcp.global.api.aws"
|
|
71
|
-
},
|
|
72
|
-
"remote-sse": {
|
|
73
|
-
"transport": "sse",
|
|
74
|
-
"url": "https://example.com/sse",
|
|
75
|
-
"headers": {
|
|
76
|
-
"Authorization": "Bearer my-token"
|
|
77
|
-
}
|
|
78
47
|
}
|
|
79
48
|
}
|
|
80
49
|
}
|
|
81
50
|
```
|
|
82
51
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
### Transport Types
|
|
86
|
-
|
|
87
|
-
| Transport | Fields | Description |
|
|
88
|
-
|---|---|---|
|
|
89
|
-
| `stdio` | `command`, `args?`, `env?` | Spawns the MCP as a child process |
|
|
90
|
-
| `streamable-http` | `url`, `headers?` | Connects to a remote MCP over HTTP |
|
|
91
|
-
| `sse` | `url`, `headers?` | Connects to a remote MCP over Server-Sent Events |
|
|
52
|
+
Then run:
|
|
92
53
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
1. Path from `-c` / `--config` flag
|
|
98
|
-
2. `mcp.json` in the current directory
|
|
99
|
-
3. `.mcp.json` in the current directory
|
|
54
|
+
```bash
|
|
55
|
+
# Auto-discover mcp.json or .mcp.json
|
|
56
|
+
npx dynmcp@latest
|
|
100
57
|
|
|
101
|
-
|
|
58
|
+
# Or specify explicitly
|
|
59
|
+
npx dynmcp@latest --config ./my-config.json
|
|
60
|
+
```
|
|
102
61
|
|
|
103
|
-
|
|
62
|
+
In config-file mode tool names are namespaced as `<mcp-name>/<tool-name>` to avoid collisions.
|
|
104
63
|
|
|
105
|
-
##
|
|
64
|
+
## Dynamic Discovery
|
|
106
65
|
|
|
107
|
-
|
|
66
|
+
For configs with heavier MCPs you only sometimes need (Chrome DevTools, remote APIs, anything expensive to keep open), give the entry a `description`. That MCP becomes *lazy*: `dynmcp` doesn't open the connection at startup, and the agent only sees a short summary of what the MCP does. When the agent decides it actually needs that MCP, it calls `load_mcp` with the server's name and the connection opens on demand.
|
|
108
67
|
|
|
109
68
|
```json
|
|
110
69
|
{
|
|
70
|
+
"$schema": "https://dynamicmcp.tools/config.json",
|
|
111
71
|
"mcp": {
|
|
112
|
-
"
|
|
113
|
-
"transport": "
|
|
114
|
-
"
|
|
115
|
-
"
|
|
116
|
-
|
|
117
|
-
|
|
72
|
+
"filesystem": {
|
|
73
|
+
"transport": "stdio",
|
|
74
|
+
"command": "npx",
|
|
75
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
|
|
76
|
+
},
|
|
77
|
+
"chrome-devtools": {
|
|
78
|
+
"description": "Chrome browser automation and DevTools control. Navigate pages, take screenshots, inspect the DOM, run JavaScript. Use when you need to interact with or debug a live web page.",
|
|
79
|
+
"transport": "stdio",
|
|
80
|
+
"command": "npx",
|
|
81
|
+
"args": ["-y", "chrome-devtools-mcp@latest"]
|
|
118
82
|
}
|
|
119
83
|
}
|
|
120
84
|
}
|
|
121
85
|
```
|
|
122
86
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
| Form | Behavior |
|
|
126
|
-
|---|---|
|
|
127
|
-
| `${VAR}` | Replaced with the value of `VAR`. Hard error at startup if `VAR` is undefined. |
|
|
128
|
-
| `${VAR:-default}` | Replaced with `VAR` if set and non-empty, otherwise the literal `default` (may contain spaces, colons, etc.). |
|
|
129
|
-
| `$${...}` | Escape — emits a literal `${...}` with no interpolation. |
|
|
130
|
-
|
|
131
|
-
Interpolation only applies to **leaf string values** inside the `mcp` map (and nested objects/arrays within it). Map keys, the top-level `$schema` field, and the top-level `env` field are never interpolated. Partial-string interpolation works — `"Bearer ${TOKEN}"` is valid.
|
|
132
|
-
|
|
133
|
-
If any referenced variables are missing without a default, `dynmcp` exits at startup with an error listing **all** of them at once (not one at a time).
|
|
87
|
+
`filesystem` connects at startup. `chrome-devtools` stays lazy until the agent loads it. Once loaded, it behaves exactly like an eager MCP for the rest of the session.
|
|
134
88
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
A top-level `env` field controls where variables are read from:
|
|
138
|
-
|
|
139
|
-
| Value | Behavior |
|
|
140
|
-
|---|---|
|
|
141
|
-
| `"enable"` (default) | Loads `.env` file (if present) and merges with `process.env`. `.env` values take precedence over `process.env` for the same key. |
|
|
142
|
-
| `"dotenv"` | Loads from `.env` file only. `process.env` is ignored. |
|
|
143
|
-
| `"process"` | Reads from `process.env` only. No `.env` file is loaded. |
|
|
144
|
-
| `"disable"` | Disables interpolation entirely — `${VAR}` is left literal. |
|
|
145
|
-
|
|
146
|
-
```json
|
|
147
|
-
{
|
|
148
|
-
"env": "process",
|
|
149
|
-
"mcp": { /* ... */ }
|
|
150
|
-
}
|
|
151
|
-
```
|
|
89
|
+
See the [Dynamic Discovery guide](https://dynamicmcp.tools/guides/dynamic-discovery/) for the capability caveat, the retry budget, and tips on writing descriptions agents can act on.
|
|
152
90
|
|
|
153
|
-
|
|
91
|
+
---
|
|
154
92
|
|
|
155
|
-
|
|
93
|
+
Full [docs](https://dynamicmcp.tools) cover environment variable interpolation, all transport options, and the complete CLI reference.
|
|
156
94
|
|
|
157
|
-
```bash
|
|
158
|
-
dynmcp --env ./secrets.env
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
Combining `--env` with `env: "disable"` or `env: "process"` is rejected as incoherent (no `.env` would be loaded). If `--env` points to a file that does not exist, `dynmcp` exits with an error.
|
|
162
|
-
|
|
163
|
-
## CLI Reference
|
|
164
|
-
|
|
165
|
-
```
|
|
166
|
-
dynmcp [options] [-- <upstream-command> [upstream-args...]]
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
| Flag | Short | Description |
|
|
170
|
-
|---|---|---|
|
|
171
|
-
| `--version` | `-v` | Print the package version and exit |
|
|
172
|
-
| `--help` | `-h` | Print usage information and exit |
|
|
173
|
-
| `--config <path>` | `-c` | Path to config file (JSON or YAML) |
|
|
174
|
-
| `--env <path>` | `-e` | Path to a custom `.env` file for variable interpolation |
|
|
175
|
-
| `--` | | Everything after is the upstream MCP command (single-MCP mode) |
|
|
176
|
-
|
|
177
|
-
### Mode Resolution
|
|
178
|
-
|
|
179
|
-
1. If `--` is present, single-MCP mode is used (config file is ignored).
|
|
180
|
-
2. Otherwise, config file mode is used.
|
|
181
|
-
|
|
182
|
-
## Development
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
npm install
|
|
186
|
-
npm run build # Compile to dist/
|
|
187
|
-
npm run typecheck # Type-check without emitting
|
|
188
|
-
npm run check # Biome lint + format
|
|
189
|
-
npm test # Run tests
|
|
190
|
-
```
|