@evantahler/mcpcli 0.4.0 → 0.5.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/{skills → .claude/skills}/mcpcli.md +1 -0
- package/README.md +23 -13
- package/package.json +2 -2
- package/src/cli.ts +2 -0
- package/src/commands/skill.ts +70 -0
- package/src/config/loader.ts +2 -2
|
@@ -90,3 +90,4 @@ mcpcli deauth <server> # remove stored auth
|
|
|
90
90
|
| `mcpcli add <name> --command <cmd>` | Add a stdio MCP server |
|
|
91
91
|
| `mcpcli add <name> --url <url>` | Add an HTTP MCP server |
|
|
92
92
|
| `mcpcli remove <name>` | Remove an MCP server |
|
|
93
|
+
| `mcpcli skill install --claude` | Install mcpcli skill for Claude |
|
package/README.md
CHANGED
|
@@ -68,6 +68,7 @@ mcpcli search -q "manage pull requests"
|
|
|
68
68
|
| `mcpcli add <name> --command <cmd>` | Add a stdio MCP server to your config |
|
|
69
69
|
| `mcpcli add <name> --url <url>` | Add an HTTP MCP server to your config |
|
|
70
70
|
| `mcpcli remove <name>` | Remove an MCP server from your config |
|
|
71
|
+
| `mcpcli skill install --claude` | Install the mcpcli skill for Claude Code |
|
|
71
72
|
|
|
72
73
|
## Options
|
|
73
74
|
|
|
@@ -134,7 +135,7 @@ mcpcli remove my-api --dry-run
|
|
|
134
135
|
|
|
135
136
|
## Configuration
|
|
136
137
|
|
|
137
|
-
Config lives in `~/.
|
|
138
|
+
Config lives in `~/.mcpcli/` (or the current directory). Three files:
|
|
138
139
|
|
|
139
140
|
### `servers.json` — MCP Server Definitions
|
|
140
141
|
|
|
@@ -231,18 +232,18 @@ Scenarios and keywords are extracted heuristically from tool names and descripti
|
|
|
231
232
|
1. `MCP_CONFIG_PATH` environment variable
|
|
232
233
|
2. `-c / --config` flag
|
|
233
234
|
3. `./servers.json` (current directory)
|
|
234
|
-
4. `~/.
|
|
235
|
+
4. `~/.mcpcli/servers.json`
|
|
235
236
|
|
|
236
237
|
## Environment Variables
|
|
237
238
|
|
|
238
|
-
| Variable | Purpose | Default
|
|
239
|
-
| ----------------- | --------------------------- |
|
|
240
|
-
| `MCP_CONFIG_PATH` | Config directory path | `~/.
|
|
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`
|
|
239
|
+
| Variable | Purpose | Default |
|
|
240
|
+
| ----------------- | --------------------------- | ------------ |
|
|
241
|
+
| `MCP_CONFIG_PATH` | Config directory path | `~/.mcpcli/` |
|
|
242
|
+
| `MCP_DEBUG` | Enable debug output | `false` |
|
|
243
|
+
| `MCP_TIMEOUT` | Request timeout (seconds) | `1800` |
|
|
244
|
+
| `MCP_CONCURRENCY` | Parallel server connections | `5` |
|
|
245
|
+
| `MCP_MAX_RETRIES` | Retry attempts | `3` |
|
|
246
|
+
| `MCP_STRICT_ENV` | Error on missing `${VAR}` | `true` |
|
|
246
247
|
|
|
247
248
|
## OAuth Flow
|
|
248
249
|
|
|
@@ -405,11 +406,20 @@ cat params.json | mcpcli exec server tool
|
|
|
405
406
|
|
|
406
407
|
### Claude Code Skill
|
|
407
408
|
|
|
408
|
-
mcpcli ships a Claude Code skill at
|
|
409
|
+
mcpcli ships a Claude Code skill at `.claude/skills/mcpcli.md` that teaches Claude Code how to discover and use MCP tools. Install it:
|
|
409
410
|
|
|
410
411
|
```bash
|
|
411
|
-
#
|
|
412
|
-
|
|
412
|
+
# Install to the current project (.claude/skills/mcpcli.md)
|
|
413
|
+
mcpcli skill install --claude
|
|
414
|
+
|
|
415
|
+
# Install globally (~/.claude/skills/mcpcli.md)
|
|
416
|
+
mcpcli skill install --claude --global
|
|
417
|
+
|
|
418
|
+
# Install to both locations
|
|
419
|
+
mcpcli skill install --claude --global --project
|
|
420
|
+
|
|
421
|
+
# Overwrite an existing skill file
|
|
422
|
+
mcpcli skill install --claude --force
|
|
413
423
|
```
|
|
414
424
|
|
|
415
425
|
Then in any Claude Code session, the agent can use `/mcpcli` or the skill triggers automatically when the agent needs to interact with external services. The skill instructs the agent to:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evantahler/mcpcli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "A command-line interface for MCP servers. curl for MCP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"src",
|
|
11
|
-
"
|
|
11
|
+
".claude",
|
|
12
12
|
"README.md",
|
|
13
13
|
"LICENSE"
|
|
14
14
|
],
|
package/src/cli.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { registerAuthCommand, registerDeauthCommand } from "./commands/auth.ts";
|
|
|
9
9
|
import { registerIndexCommand } from "./commands/index.ts";
|
|
10
10
|
import { registerAddCommand } from "./commands/add.ts";
|
|
11
11
|
import { registerRemoveCommand } from "./commands/remove.ts";
|
|
12
|
+
import { registerSkillCommand } from "./commands/skill.ts";
|
|
12
13
|
|
|
13
14
|
declare const BUILD_VERSION: string | undefined;
|
|
14
15
|
|
|
@@ -33,5 +34,6 @@ registerDeauthCommand(program);
|
|
|
33
34
|
registerIndexCommand(program);
|
|
34
35
|
registerAddCommand(program);
|
|
35
36
|
registerRemoveCommand(program);
|
|
37
|
+
registerSkillCommand(program);
|
|
36
38
|
|
|
37
39
|
program.parse();
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { resolve, dirname, join } from "path";
|
|
3
|
+
import { readFile, mkdir, writeFile, access } from "fs/promises";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
|
|
6
|
+
export function registerSkillCommand(program: Command) {
|
|
7
|
+
const skill = program.command("skill").description("manage mcpcli skills");
|
|
8
|
+
|
|
9
|
+
skill
|
|
10
|
+
.command("install")
|
|
11
|
+
.description("install the mcpcli skill for an AI agent")
|
|
12
|
+
.requiredOption("--claude", "install for Claude Code")
|
|
13
|
+
.option("--global", "install to ~/.claude/skills/")
|
|
14
|
+
.option("--project", "install to ./.claude/skills/ (default)")
|
|
15
|
+
.option("-f, --force", "overwrite if file already exists")
|
|
16
|
+
.action(
|
|
17
|
+
async (options: {
|
|
18
|
+
claude?: boolean;
|
|
19
|
+
global?: boolean;
|
|
20
|
+
project?: boolean;
|
|
21
|
+
force?: boolean;
|
|
22
|
+
}) => {
|
|
23
|
+
// Resolve the bundled skill file
|
|
24
|
+
const skillSource = resolve(dirname(Bun.main), "..", ".claude", "skills", "mcpcli.md");
|
|
25
|
+
|
|
26
|
+
let content: string;
|
|
27
|
+
try {
|
|
28
|
+
content = await readFile(skillSource, "utf-8");
|
|
29
|
+
} catch {
|
|
30
|
+
console.error(`Could not read skill file: ${skillSource}`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Determine targets — default to project if neither flag is set
|
|
35
|
+
const targets: { label: string; dir: string }[] = [];
|
|
36
|
+
|
|
37
|
+
if (options.global) {
|
|
38
|
+
targets.push({
|
|
39
|
+
label: "global",
|
|
40
|
+
dir: join(homedir(), ".claude", "skills"),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (options.project || !options.global) {
|
|
44
|
+
targets.push({
|
|
45
|
+
label: "project",
|
|
46
|
+
dir: resolve(".claude", "skills"),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
for (const target of targets) {
|
|
51
|
+
const dest = join(target.dir, "mcpcli.md");
|
|
52
|
+
|
|
53
|
+
// Check if file already exists
|
|
54
|
+
if (!options.force) {
|
|
55
|
+
try {
|
|
56
|
+
await access(dest);
|
|
57
|
+
console.error(`${dest} already exists (use --force to overwrite)`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
} catch {
|
|
60
|
+
// File doesn't exist — good
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
await mkdir(target.dir, { recursive: true });
|
|
65
|
+
await writeFile(dest, content, "utf-8");
|
|
66
|
+
console.log(`Installed mcpcli skill (${target.label}): ${dest}`);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
);
|
|
70
|
+
}
|
package/src/config/loader.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
validateSearchIndex,
|
|
12
12
|
} from "./schemas.ts";
|
|
13
13
|
|
|
14
|
-
const DEFAULT_CONFIG_DIR = join(homedir(), ".
|
|
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 ~/.
|
|
45
|
+
// 4. Default ~/.mcpcli/
|
|
46
46
|
return DEFAULT_CONFIG_DIR;
|
|
47
47
|
}
|
|
48
48
|
|