mcp-caller 0.0.2 → 0.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 +17 -5
- package/index.js +84 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,16 +30,16 @@ Call a remote streamable HTTP MCP server:
|
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
npx -y mcp-caller \
|
|
33
|
-
--server-json '{"
|
|
34
|
-
--call-json '{"tool":"
|
|
33
|
+
--server-json '{"type":"streamable-http","url":"https://gitmcp.io/idosal/git-mcp"}' \
|
|
34
|
+
--call-json '{"tool":"fetch_git_mcp_documentation","params":{}}'
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
PowerShell:
|
|
38
38
|
|
|
39
39
|
```powershell
|
|
40
40
|
npx -y mcp-caller `
|
|
41
|
-
--server-json '{"
|
|
42
|
-
--call-json '{"tool":"
|
|
41
|
+
--server-json '{"type":"streamable-http","url":"https://gitmcp.io/idosal/git-mcp"}' `
|
|
42
|
+
--call-json '{"tool":"fetch_git_mcp_documentation","params":{}}'
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
Read JSON from files instead of inline values:
|
|
@@ -48,6 +48,18 @@ Read JSON from files instead of inline values:
|
|
|
48
48
|
npx -y mcp-caller --server-file server.json --call-file call.json
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
List callable tools:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx -y mcp-caller --server-file server.json --list-tools
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Inspect tools, prompts, and resources:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx -y mcp-caller --server-file server.json --inspect --pretty
|
|
61
|
+
```
|
|
62
|
+
|
|
51
63
|
## JSON Shapes
|
|
52
64
|
|
|
53
65
|
Server JSON:
|
|
@@ -87,4 +99,4 @@ Call JSON:
|
|
|
87
99
|
|
|
88
100
|
- The CLI prints text content when the tool result contains text.
|
|
89
101
|
- Use `--pretty` to format non-text JSON output.
|
|
90
|
-
- The
|
|
102
|
+
- The example probes are covered by [test/cli.examples.test.js](d:/projects/culled/mcp-caller/test/cli.examples.test.js).
|
package/index.js
CHANGED
|
@@ -7,6 +7,8 @@ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/
|
|
|
7
7
|
|
|
8
8
|
function printUsage() {
|
|
9
9
|
console.error(`Usage:
|
|
10
|
+
mcp-caller --server-json <json> --list-tools
|
|
11
|
+
mcp-caller --server-json <json> --inspect
|
|
10
12
|
mcp-caller --server-json <json> --call-json <json>
|
|
11
13
|
mcp-caller --server-file <path> --call-file <path>
|
|
12
14
|
|
|
@@ -81,6 +83,14 @@ function parseArgs(argv) {
|
|
|
81
83
|
options.callFile = argv[++i];
|
|
82
84
|
continue;
|
|
83
85
|
}
|
|
86
|
+
if (token === "--list-tools") {
|
|
87
|
+
options.listTools = true;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (token === "--inspect") {
|
|
91
|
+
options.inspect = true;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
84
94
|
if (token === "--server-name") {
|
|
85
95
|
options.serverName = argv[++i];
|
|
86
96
|
continue;
|
|
@@ -153,6 +163,31 @@ function extractText(result) {
|
|
|
153
163
|
return pieces.join("\n");
|
|
154
164
|
}
|
|
155
165
|
|
|
166
|
+
function printTools(tools) {
|
|
167
|
+
for (const tool of tools) {
|
|
168
|
+
console.log(`- ${tool.name}${tool.description ? `: ${tool.description}` : ""}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function formatInspect(serverName, tools, prompts, resources) {
|
|
173
|
+
return {
|
|
174
|
+
server: serverName,
|
|
175
|
+
tools: tools.map((tool) => ({
|
|
176
|
+
name: tool.name,
|
|
177
|
+
description: tool.description ?? ""
|
|
178
|
+
})),
|
|
179
|
+
prompts: prompts.map((prompt) => ({
|
|
180
|
+
name: prompt.name,
|
|
181
|
+
description: prompt.description ?? ""
|
|
182
|
+
})),
|
|
183
|
+
resources: resources.map((resource) => ({
|
|
184
|
+
uri: resource.uri,
|
|
185
|
+
name: resource.name ?? "",
|
|
186
|
+
description: resource.description ?? ""
|
|
187
|
+
}))
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
156
191
|
async function main() {
|
|
157
192
|
const options = parseArgs(process.argv.slice(2));
|
|
158
193
|
if (options.help) {
|
|
@@ -161,13 +196,17 @@ async function main() {
|
|
|
161
196
|
}
|
|
162
197
|
|
|
163
198
|
const serverSource = readSource(options, "serverJson", "serverFile", "--server-json/--server-file");
|
|
164
|
-
const callSource =
|
|
199
|
+
const callSource = options.listTools || options.inspect
|
|
200
|
+
? null
|
|
201
|
+
: readSource(options, "callJson", "callFile", "--call-json/--call-file");
|
|
165
202
|
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
203
|
+
if (callSource) {
|
|
204
|
+
if (typeof callSource !== "object") {
|
|
205
|
+
throw new Error("Call JSON must be an object");
|
|
206
|
+
}
|
|
207
|
+
if (typeof callSource.tool !== "string" || !callSource.tool) {
|
|
208
|
+
throw new Error('Call JSON must include a non-empty "tool" string');
|
|
209
|
+
}
|
|
171
210
|
}
|
|
172
211
|
|
|
173
212
|
const { server } = resolveServerDefinition(serverSource, options.serverName);
|
|
@@ -177,18 +216,49 @@ async function main() {
|
|
|
177
216
|
try {
|
|
178
217
|
await client.connect(transport);
|
|
179
218
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
219
|
+
if (options.listTools || options.inspect) {
|
|
220
|
+
const [toolsResult, promptsResult, resourcesResult] = await Promise.all([
|
|
221
|
+
client.listTools(),
|
|
222
|
+
options.inspect ? client.listPrompts() : Promise.resolve({ prompts: [] }),
|
|
223
|
+
options.inspect ? client.listResources() : Promise.resolve({ resources: [] })
|
|
224
|
+
]);
|
|
184
225
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
226
|
+
if (options.listTools) {
|
|
227
|
+
printTools(toolsResult.tools ?? []);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
console.log(JSON.stringify(
|
|
232
|
+
formatInspect(
|
|
233
|
+
options.serverName ?? (serverSource?.mcpServers ? Object.keys(serverSource.mcpServers)[0] : "server"),
|
|
234
|
+
toolsResult.tools ?? [],
|
|
235
|
+
promptsResult.prompts ?? [],
|
|
236
|
+
resourcesResult.resources ?? []
|
|
237
|
+
),
|
|
238
|
+
null,
|
|
239
|
+
options.pretty ? 2 : 0
|
|
240
|
+
));
|
|
188
241
|
return;
|
|
189
242
|
}
|
|
190
243
|
|
|
191
|
-
|
|
244
|
+
if (!options.listTools && !options.inspect && !callSource) {
|
|
245
|
+
throw new Error("Missing --call-json/--call-file, or use --list-tools / --inspect");
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (callSource) {
|
|
249
|
+
const result = await client.callTool({
|
|
250
|
+
name: callSource.tool,
|
|
251
|
+
arguments: callSource.params ?? callSource.arguments ?? {}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
const text = extractText(result);
|
|
255
|
+
if (text) {
|
|
256
|
+
console.log(text);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
console.log(JSON.stringify(result, null, options.pretty ? 2 : 0));
|
|
261
|
+
}
|
|
192
262
|
} finally {
|
|
193
263
|
await client.close().catch(() => {});
|
|
194
264
|
}
|