@evantahler/mcpcli 0.3.6 → 0.5.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 CHANGED
@@ -34,8 +34,8 @@ mcpcli info github
34
34
  # Inspect a specific tool
35
35
  mcpcli info github search_repositories
36
36
 
37
- # Call a tool
38
- mcpcli call github search_repositories '{"query": "mcp server"}'
37
+ # Execute a tool
38
+ mcpcli exec github search_repositories '{"query": "mcp server"}'
39
39
 
40
40
  # Search tools — combines keyword and semantic matching
41
41
  mcpcli search "post a ticket to linear"
@@ -59,8 +59,8 @@ mcpcli search -q "manage pull requests"
59
59
  | `mcpcli search -q <query>` | Semantic search only |
60
60
  | `mcpcli index` | Build/rebuild the search index |
61
61
  | `mcpcli index -i` | Show index status |
62
- | `mcpcli call <server> <tool> [json]` | Validate inputs locally, then execute tool |
63
- | `mcpcli call <server>` | List available tools for a server |
62
+ | `mcpcli exec <server> <tool> [json]` | Validate inputs locally, then execute tool |
63
+ | `mcpcli exec <server>` | List available tools for a server |
64
64
  | `mcpcli auth <server>` | Authenticate with an HTTP MCP server (OAuth) |
65
65
  | `mcpcli auth <server> -s` | Check auth status and token TTL |
66
66
  | `mcpcli auth <server> -r` | Force token refresh |
@@ -134,7 +134,7 @@ mcpcli remove my-api --dry-run
134
134
 
135
135
  ## Configuration
136
136
 
137
- Config lives in `~/.config/mcpcli/` (or the current directory). Three files:
137
+ Config lives in `~/.mcpcli/` (or the current directory). Three files:
138
138
 
139
139
  ### `servers.json` — MCP Server Definitions
140
140
 
@@ -193,7 +193,7 @@ Stores OAuth tokens for HTTP MCP servers. You don't edit this directly — manag
193
193
  }
194
194
  ```
195
195
 
196
- Tokens are automatically refreshed when expired (if a refresh token is available). Any command that connects to a server (`call`, `info`, `search`, listing) will refresh tokens transparently. `mcpcli auth <server> --status` shows current token state and TTL.
196
+ Tokens are automatically refreshed when expired (if a refresh token is available). Any command that connects to a server (`exec`, `info`, `search`, listing) will refresh tokens transparently. `mcpcli auth <server> --status` shows current token state and TTL.
197
197
 
198
198
  ### `search.json` — Semantic Search Index (managed automatically)
199
199
 
@@ -231,18 +231,18 @@ Scenarios and keywords are extracted heuristically from tool names and descripti
231
231
  1. `MCP_CONFIG_PATH` environment variable
232
232
  2. `-c / --config` flag
233
233
  3. `./servers.json` (current directory)
234
- 4. `~/.config/mcpcli/servers.json`
234
+ 4. `~/.mcpcli/servers.json`
235
235
 
236
236
  ## Environment Variables
237
237
 
238
- | Variable | Purpose | Default |
239
- | ----------------- | --------------------------- | ------------------- |
240
- | `MCP_CONFIG_PATH` | Config directory path | `~/.config/mcpcli/` |
241
- | `MCP_DEBUG` | Enable debug output | `false` |
242
- | `MCP_TIMEOUT` | Request timeout (seconds) | `1800` |
243
- | `MCP_CONCURRENCY` | Parallel server connections | `5` |
244
- | `MCP_MAX_RETRIES` | Retry attempts | `3` |
245
- | `MCP_STRICT_ENV` | Error on missing `${VAR}` | `true` |
238
+ | Variable | Purpose | Default |
239
+ | ----------------- | --------------------------- | ------------ |
240
+ | `MCP_CONFIG_PATH` | Config directory path | `~/.mcpcli/` |
241
+ | `MCP_DEBUG` | Enable debug output | `false` |
242
+ | `MCP_TIMEOUT` | Request timeout (seconds) | `1800` |
243
+ | `MCP_CONCURRENCY` | Parallel server connections | `5` |
244
+ | `MCP_MAX_RETRIES` | Retry attempts | `3` |
245
+ | `MCP_STRICT_ENV` | Error on missing `${VAR}` | `true` |
246
246
 
247
247
  ## OAuth Flow
248
248
 
@@ -308,7 +308,7 @@ The index updates incrementally — only new or changed tools are re-indexed. Th
308
308
 
309
309
  ```bash
310
310
  # See full HTTP traffic
311
- mcpcli -v call arcade Gmail_WhoAmI
311
+ mcpcli -v exec arcade Gmail_WhoAmI
312
312
 
313
313
  # > POST https://api.arcade.dev/mcp/evan-coding
314
314
  # > authorization: Bearer eyJhbGci...
@@ -329,7 +329,7 @@ mcpcli -v call arcade Gmail_WhoAmI
329
329
  # { "content": [ ... ] }
330
330
 
331
331
  # Debug on stderr, clean JSON on stdout
332
- mcpcli -v call arcade Gmail_WhoAmI | jq .
332
+ mcpcli -v exec arcade Gmail_WhoAmI | jq .
333
333
 
334
334
  # Show full auth tokens (unmasked)
335
335
  mcpcli -v -S call arcade Gmail_WhoAmI
@@ -339,19 +339,19 @@ The `>` / `<` convention matches curl — `>` for request, `<` for response. The
339
339
 
340
340
  ## Input Validation
341
341
 
342
- `mcpcli call` validates tool arguments locally before sending them to the server. MCP tools advertise a JSON Schema for their inputs — mcpcli uses this to catch errors fast, without a round-trip.
342
+ `mcpcli exec` validates tool arguments locally before sending them to the server. MCP tools advertise a JSON Schema for their inputs — mcpcli uses this to catch errors fast, without a round-trip.
343
343
 
344
344
  ```bash
345
345
  # Missing required field — caught locally
346
- mcpcli call github create_issue '{"title": "bug"}'
346
+ mcpcli exec github create_issue '{"title": "bug"}'
347
347
  # => error: missing required field "repo" (github/create_issue)
348
348
 
349
349
  # Wrong type — caught locally
350
- mcpcli call github create_issue '{"repo": "foo", "title": 123}'
350
+ mcpcli exec github create_issue '{"repo": "foo", "title": 123}'
351
351
  # => error: "title" must be a string, got number (github/create_issue)
352
352
 
353
353
  # Valid — sent to server
354
- mcpcli call github create_issue '{"repo": "foo", "title": "bug"}'
354
+ mcpcli exec github create_issue '{"repo": "foo", "title": "bug"}'
355
355
  # => { ... }
356
356
  ```
357
357
 
@@ -362,7 +362,7 @@ Validation covers:
362
362
  - **Enum values** — rejects values not in the allowed set
363
363
  - **Nested objects** — validates recursively
364
364
 
365
- If a tool's `inputSchema` is unavailable (some servers don't provide one), the call proceeds without local validation.
365
+ If a tool's `inputSchema` is unavailable (some servers don't provide one), execution proceeds without local validation.
366
366
 
367
367
  ## Shell Output & Piping
368
368
 
@@ -379,26 +379,26 @@ mcpcli info github | jq '.tools[].name'
379
379
  mcpcli info github --json
380
380
  ```
381
381
 
382
- Tool call results are always JSON, designed for chaining:
382
+ Tool results are always JSON, designed for chaining:
383
383
 
384
384
  ```bash
385
385
  # Search repos and read the first result
386
- mcpcli call github search_repositories '{"query":"mcp"}' \
386
+ mcpcli exec github search_repositories '{"query":"mcp"}' \
387
387
  | jq -r '.content[0].text | fromjson | .items[0].full_name' \
388
- | xargs -I {} mcpcli call github get_file_contents '{"owner":"{}","path":"README.md"}'
388
+ | xargs -I {} mcpcli exec github get_file_contents '{"owner":"{}","path":"README.md"}'
389
389
 
390
390
  # Conditional execution
391
- mcpcli call filesystem list_directory '{"path":"."}' \
391
+ mcpcli exec filesystem list_directory '{"path":"."}' \
392
392
  | jq -e '.content[0].text | contains("package.json")' \
393
- && mcpcli call filesystem read_file '{"path":"./package.json"}'
393
+ && mcpcli exec filesystem read_file '{"path":"./package.json"}'
394
394
  ```
395
395
 
396
396
  Stdin works for tool arguments:
397
397
 
398
398
  ```bash
399
- echo '{"path":"./README.md"}' | mcpcli call filesystem read_file
399
+ echo '{"path":"./README.md"}' | mcpcli exec filesystem read_file
400
400
 
401
- cat params.json | mcpcli call server tool
401
+ cat params.json | mcpcli exec server tool
402
402
  ```
403
403
 
404
404
  ## Agent Integration
@@ -416,7 +416,7 @@ Then in any Claude Code session, the agent can use `/mcpcli` or the skill trigge
416
416
 
417
417
  1. **Search first** — `mcpcli search "<intent>"` to find relevant tools
418
418
  2. **Inspect** — `mcpcli info <server> <tool>` to get the schema before calling
419
- 3. **Call** — `mcpcli call <server> <tool> '<json>'` to execute
419
+ 3. **Execute** — `mcpcli exec <server> <tool> '<json>'` to execute
420
420
 
421
421
  This keeps tool schemas out of the system prompt entirely. The agent discovers what it needs on-demand, saving tokens and context window space.
422
422
 
@@ -432,10 +432,10 @@ To discover tools:
432
432
  mcpcli search -k "<pattern>" # keyword/glob only
433
433
  mcpcli info <server> <tool> # tool schema
434
434
 
435
- To call tools:
436
- mcpcli call <server> <tool> '<json args>'
435
+ To execute tools:
436
+ mcpcli exec <server> <tool> '<json args>'
437
437
 
438
- Always search before calling — don't assume tool names.
438
+ Always search before executing — don't assume tool names.
439
439
  ```
440
440
 
441
441
  ## Development
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evantahler/mcpcli",
3
- "version": "0.3.6",
3
+ "version": "0.5.0",
4
4
  "description": "A command-line interface for MCP servers. curl for MCP.",
5
5
  "type": "module",
6
6
  "bin": {
package/skills/mcpcli.md CHANGED
@@ -22,19 +22,19 @@ mcpcli info <server> <tool>
22
22
 
23
23
  This shows parameters, types, required fields, and the full JSON Schema.
24
24
 
25
- ## 3. Call the tool
25
+ ## 3. Execute the tool
26
26
 
27
27
  ```bash
28
- mcpcli call <server> <tool> '<json args>'
28
+ mcpcli exec <server> <tool> '<json args>'
29
29
  ```
30
30
 
31
31
  ## Rules
32
32
 
33
- - Always search before calling — don't assume tool names exist
34
- - Always inspect the schema before calling — validate you have the right arguments
33
+ - Always search before executing — don't assume tool names exist
34
+ - Always inspect the schema before executing — validate you have the right arguments
35
35
  - Use `mcpcli search -k` for exact name matching
36
36
  - Pipe results through `jq` when you need to extract specific fields
37
- - Use `-v` for verbose HTTP debugging if a call fails unexpectedly
37
+ - Use `-v` for verbose HTTP debugging if an exec fails unexpectedly
38
38
 
39
39
  ## Examples
40
40
 
@@ -46,15 +46,15 @@ mcpcli search "send a message"
46
46
  mcpcli info arcade Slack_SendMessage
47
47
 
48
48
  # Send a message
49
- mcpcli call arcade Slack_SendMessage '{"channel":"#general","message":"hello"}'
49
+ mcpcli exec arcade Slack_SendMessage '{"channel":"#general","message":"hello"}'
50
50
 
51
51
  # Chain commands — search repos and read the first result
52
- mcpcli call github search_repositories '{"query":"mcp"}' \
52
+ mcpcli exec github search_repositories '{"query":"mcp"}' \
53
53
  | jq -r '.content[0].text | fromjson | .items[0].full_name' \
54
- | xargs -I {} mcpcli call github get_file_contents '{"owner":"{}","path":"README.md"}'
54
+ | xargs -I {} mcpcli exec github get_file_contents '{"owner":"{}","path":"README.md"}'
55
55
 
56
56
  # Read args from stdin
57
- echo '{"path":"./README.md"}' | mcpcli call filesystem read_file
57
+ echo '{"path":"./README.md"}' | mcpcli exec filesystem read_file
58
58
  ```
59
59
 
60
60
  ## Authentication
@@ -76,8 +76,8 @@ mcpcli deauth <server> # remove stored auth
76
76
  | `mcpcli -d` | List with descriptions |
77
77
  | `mcpcli info <server>` | Show tools for a server |
78
78
  | `mcpcli info <server> <tool>` | Show tool schema |
79
- | `mcpcli call <server>` | List tools for a server |
80
- | `mcpcli call <server> <tool> '<json>'` | Execute a tool |
79
+ | `mcpcli exec <server>` | List tools for a server |
80
+ | `mcpcli exec <server> <tool> '<json>'` | Execute a tool |
81
81
  | `mcpcli search "<query>"` | Search tools (keyword + semantic) |
82
82
  | `mcpcli search -k "<pattern>"` | Keyword/glob search only |
83
83
  | `mcpcli search -q "<query>"` | Semantic search only |
package/src/cli.ts CHANGED
@@ -4,7 +4,7 @@ import { program } from "commander";
4
4
  import { registerListCommand } from "./commands/list.ts";
5
5
  import { registerInfoCommand } from "./commands/info.ts";
6
6
  import { registerSearchCommand } from "./commands/search.ts";
7
- import { registerCallCommand } from "./commands/call.ts";
7
+ import { registerExecCommand } from "./commands/exec.ts";
8
8
  import { registerAuthCommand, registerDeauthCommand } from "./commands/auth.ts";
9
9
  import { registerIndexCommand } from "./commands/index.ts";
10
10
  import { registerAddCommand } from "./commands/add.ts";
@@ -27,7 +27,7 @@ program
27
27
  registerListCommand(program);
28
28
  registerInfoCommand(program);
29
29
  registerSearchCommand(program);
30
- registerCallCommand(program);
30
+ registerExecCommand(program);
31
31
  registerAuthCommand(program);
32
32
  registerDeauthCommand(program);
33
33
  registerIndexCommand(program);
@@ -9,9 +9,9 @@ import {
9
9
  import { logger } from "../output/logger.ts";
10
10
  import { validateToolInput } from "../validation/schema.ts";
11
11
 
12
- export function registerCallCommand(program: Command) {
12
+ export function registerExecCommand(program: Command) {
13
13
  program
14
- .command("call <server> [tool] [args]")
14
+ .command("exec <server> [tool] [args]")
15
15
  .description("execute a tool (omit tool name to list available tools)")
16
16
  .action(async (server: string, tool: string | undefined, argsStr: string | undefined) => {
17
17
  const { manager, formatOptions } = await getContext(program);
@@ -52,7 +52,7 @@ export function registerCallCommand(program: Command) {
52
52
  }
53
53
  }
54
54
 
55
- const spinner = logger.startSpinner(`Calling ${server}/${tool}...`, formatOptions);
55
+ const spinner = logger.startSpinner(`Executing ${server}/${tool}...`, formatOptions);
56
56
  const result = await manager.callTool(server, tool, args);
57
57
  spinner.stop();
58
58
  console.log(formatCallResult(result, formatOptions));
@@ -11,7 +11,7 @@ import {
11
11
  validateSearchIndex,
12
12
  } from "./schemas.ts";
13
13
 
14
- const DEFAULT_CONFIG_DIR = join(homedir(), ".config", "mcpcli");
14
+ const DEFAULT_CONFIG_DIR = join(homedir(), ".mcpcli");
15
15
 
16
16
  const EMPTY_SERVERS: ServersFile = { mcpServers: {} };
17
17
  const EMPTY_AUTH: AuthFile = {};
@@ -42,7 +42,7 @@ function resolveConfigDir(configFlag?: string): string {
42
42
  // 3. ./servers.json exists in cwd → use cwd
43
43
  // (checked at load time, not here — we return the candidate dir)
44
44
 
45
- // 4. Default ~/.config/mcpcli/
45
+ // 4. Default ~/.mcpcli/
46
46
  return DEFAULT_CONFIG_DIR;
47
47
  }
48
48