From a183d667632e24690f834914e1134062ec8f30bd Mon Sep 17 00:00:00 2001 From: syf2211 Date: Sun, 28 Jun 2026 03:12:15 +0000 Subject: [PATCH] feat(cli): add non-interactive list-tools command Fixes #17 Add list-tools beside call-tool for scripting and automation. Reuses the existing config-based non-interactive connection path and prints listTools() JSON to stdout. --- CHANGELOG.md | 4 ++++ README.md | 5 ++++- src/cli.js | 4 ++++ src/mcp.js | 4 +++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34fc8d8..ec22cb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.0 + +- Add `list-tools` non-interactive command to list tools from a configured MCP server + # 2.0.0 - **Breaking**: require Node.js 20 or newer diff --git a/README.md b/README.md index 978223e..c366f2d 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ npx @wong2/mcp-cli --sse http://localhost:8000/sse ### Non-interactive mode -Run a specific tool, resource, or prompt without interactive prompts: +Run a specific tool, resource, or prompt without interactive prompts, or list tools from a configured server: ```bash npx @wong2/mcp-cli [--config config.json] : [--args '{}'] @@ -71,6 +71,9 @@ Examples: # Call a tool without arguments npx @wong2/mcp-cli -c config.json call-tool filesystem:list_files +# List tools exposed by a configured server +npx @wong2/mcp-cli -c config.json list-tools filesystem + # Call a tool with arguments npx @wong2/mcp-cli -c config.json call-tool filesystem:read_file --args '{"path": "package.json"}' diff --git a/src/cli.js b/src/cli.js index 7f7b3da..6a96270 100755 --- a/src/cli.js +++ b/src/cli.js @@ -15,6 +15,7 @@ const cli = meow( $ mcp-cli --url http://localhost:8000/mcp $ mcp-cli --sse http://localhost:8000/sse $ mcp-cli purge + $ mcp-cli [--config config.json] list-tools $ mcp-cli [--config config.json] call-tool : [--args '{"key":"value"}'] $ mcp-cli [--config config.json] read-resource : $ mcp-cli [--config config.json] get-prompt : [--args '{"key":"value"}'] @@ -53,6 +54,9 @@ const options = { compact: cli.flags.compact } if (cli.input[0] === 'purge') { purge() +} else if (cli.input.length >= 2 && cli.input[0] === 'list-tools') { + const [, serverName] = cli.input + await runWithConfigNonInteractive(cli.flags.config, serverName, 'list-tools') } else if ( cli.input.length >= 2 && (cli.input[0] === 'call-tool' || cli.input[0] === 'read-resource' || cli.input[0] === 'get-prompt') diff --git a/src/mcp.js b/src/mcp.js index 81f2cac..6ac34b6 100644 --- a/src/mcp.js +++ b/src/mcp.js @@ -218,7 +218,9 @@ export async function runWithConfigNonInteractive(configPath, serverName, comman } } - if (command === 'call-tool') { + if (command === 'list-tools') { + result = await client.listTools() + } else if (command === 'call-tool') { result = await client.callTool({ name: target, arguments: args }) } else if (command === 'read-resource') { result = await client.readResource({ uri: target })