@evantahler/mcpx 0.15.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.
Files changed (106) hide show
  1. package/.claude/settings.local.json +18 -0
  2. package/.claude/skills/mcpx.md +165 -0
  3. package/.claude/worktrees/elastic-jennings/.claude/settings.local.json +18 -0
  4. package/.claude/worktrees/elastic-jennings/.claude/skills/mcpcli.md +93 -0
  5. package/.claude/worktrees/elastic-jennings/.github/workflows/auto-release.yml +117 -0
  6. package/.claude/worktrees/elastic-jennings/.github/workflows/ci.yml +18 -0
  7. package/.claude/worktrees/elastic-jennings/.prettierignore +4 -0
  8. package/.claude/worktrees/elastic-jennings/.prettierrc +7 -0
  9. package/.claude/worktrees/elastic-jennings/CLAUDE.md +19 -0
  10. package/.claude/worktrees/elastic-jennings/LICENSE +21 -0
  11. package/.claude/worktrees/elastic-jennings/README.md +487 -0
  12. package/.claude/worktrees/elastic-jennings/bun.lock +381 -0
  13. package/.claude/worktrees/elastic-jennings/install.sh +55 -0
  14. package/.claude/worktrees/elastic-jennings/package.json +56 -0
  15. package/.claude/worktrees/elastic-jennings/src/cli.ts +39 -0
  16. package/.claude/worktrees/elastic-jennings/src/client/http.ts +100 -0
  17. package/.claude/worktrees/elastic-jennings/src/client/manager.ts +266 -0
  18. package/.claude/worktrees/elastic-jennings/src/client/oauth.ts +299 -0
  19. package/.claude/worktrees/elastic-jennings/src/client/stdio.ts +12 -0
  20. package/.claude/worktrees/elastic-jennings/src/commands/add.ts +155 -0
  21. package/.claude/worktrees/elastic-jennings/src/commands/auth.ts +114 -0
  22. package/.claude/worktrees/elastic-jennings/src/commands/exec.ts +91 -0
  23. package/.claude/worktrees/elastic-jennings/src/commands/index.ts +62 -0
  24. package/.claude/worktrees/elastic-jennings/src/commands/info.ts +38 -0
  25. package/.claude/worktrees/elastic-jennings/src/commands/list.ts +30 -0
  26. package/.claude/worktrees/elastic-jennings/src/commands/remove.ts +67 -0
  27. package/.claude/worktrees/elastic-jennings/src/commands/search.ts +45 -0
  28. package/.claude/worktrees/elastic-jennings/src/commands/skill.ts +70 -0
  29. package/.claude/worktrees/elastic-jennings/src/config/env.ts +41 -0
  30. package/.claude/worktrees/elastic-jennings/src/config/loader.ts +156 -0
  31. package/.claude/worktrees/elastic-jennings/src/config/schemas.ts +137 -0
  32. package/.claude/worktrees/elastic-jennings/src/context.ts +53 -0
  33. package/.claude/worktrees/elastic-jennings/src/output/formatter.ts +316 -0
  34. package/.claude/worktrees/elastic-jennings/src/output/logger.ts +114 -0
  35. package/.claude/worktrees/elastic-jennings/src/search/index.ts +69 -0
  36. package/.claude/worktrees/elastic-jennings/src/search/indexer.ts +92 -0
  37. package/.claude/worktrees/elastic-jennings/src/search/keyword.ts +86 -0
  38. package/.claude/worktrees/elastic-jennings/src/search/semantic.ts +75 -0
  39. package/.claude/worktrees/elastic-jennings/src/search/staleness.ts +8 -0
  40. package/.claude/worktrees/elastic-jennings/src/validation/schema.ts +77 -0
  41. package/.claude/worktrees/elastic-jennings/test/cli.test.ts +51 -0
  42. package/.claude/worktrees/elastic-jennings/test/client/manager.test.ts +249 -0
  43. package/.claude/worktrees/elastic-jennings/test/client/oauth.test.ts +328 -0
  44. package/.claude/worktrees/elastic-jennings/test/commands/add-remove.test.ts +253 -0
  45. package/.claude/worktrees/elastic-jennings/test/commands/exec.test.ts +105 -0
  46. package/.claude/worktrees/elastic-jennings/test/commands/info.test.ts +48 -0
  47. package/.claude/worktrees/elastic-jennings/test/commands/list.test.ts +39 -0
  48. package/.claude/worktrees/elastic-jennings/test/commands/skill.test.ts +98 -0
  49. package/.claude/worktrees/elastic-jennings/test/config/env.test.ts +61 -0
  50. package/.claude/worktrees/elastic-jennings/test/config/loader.test.ts +139 -0
  51. package/.claude/worktrees/elastic-jennings/test/fixtures/.keep +0 -0
  52. package/.claude/worktrees/elastic-jennings/test/fixtures/auth.json +10 -0
  53. package/.claude/worktrees/elastic-jennings/test/fixtures/mock-config/.keep +0 -0
  54. package/.claude/worktrees/elastic-jennings/test/fixtures/mock-config/servers.json +8 -0
  55. package/.claude/worktrees/elastic-jennings/test/fixtures/mock-server.ts +113 -0
  56. package/.claude/worktrees/elastic-jennings/test/fixtures/search.json +15 -0
  57. package/.claude/worktrees/elastic-jennings/test/fixtures/servers.json +18 -0
  58. package/.claude/worktrees/elastic-jennings/test/integration/stdio-server.test.ts +149 -0
  59. package/.claude/worktrees/elastic-jennings/test/output/formatter.test.ts +54 -0
  60. package/.claude/worktrees/elastic-jennings/test/output/logger.test.ts +89 -0
  61. package/.claude/worktrees/elastic-jennings/test/search/indexer.test.ts +32 -0
  62. package/.claude/worktrees/elastic-jennings/test/search/keyword.test.ts +80 -0
  63. package/.claude/worktrees/elastic-jennings/test/search/semantic.test.ts +32 -0
  64. package/.claude/worktrees/elastic-jennings/test/validation/schema.test.ts +113 -0
  65. package/.claude/worktrees/elastic-jennings/tsconfig.json +29 -0
  66. package/.cursor/rules/mcpx.mdc +165 -0
  67. package/LICENSE +21 -0
  68. package/README.md +627 -0
  69. package/package.json +58 -0
  70. package/src/cli.ts +72 -0
  71. package/src/client/browser.ts +24 -0
  72. package/src/client/debug-fetch.ts +81 -0
  73. package/src/client/elicitation.ts +368 -0
  74. package/src/client/http.ts +25 -0
  75. package/src/client/manager.ts +566 -0
  76. package/src/client/oauth.ts +314 -0
  77. package/src/client/sse.ts +17 -0
  78. package/src/client/stdio.ts +12 -0
  79. package/src/client/trace.ts +184 -0
  80. package/src/commands/add.ts +179 -0
  81. package/src/commands/auth.ts +114 -0
  82. package/src/commands/exec.ts +156 -0
  83. package/src/commands/index.ts +62 -0
  84. package/src/commands/info.ts +63 -0
  85. package/src/commands/list.ts +64 -0
  86. package/src/commands/ping.ts +69 -0
  87. package/src/commands/prompt.ts +60 -0
  88. package/src/commands/remove.ts +67 -0
  89. package/src/commands/resource.ts +46 -0
  90. package/src/commands/search.ts +49 -0
  91. package/src/commands/servers.ts +66 -0
  92. package/src/commands/skill.ts +112 -0
  93. package/src/commands/task.ts +82 -0
  94. package/src/config/env.ts +41 -0
  95. package/src/config/loader.ts +156 -0
  96. package/src/config/schemas.ts +152 -0
  97. package/src/context.ts +62 -0
  98. package/src/lib/input.ts +36 -0
  99. package/src/output/formatter.ts +884 -0
  100. package/src/output/logger.ts +173 -0
  101. package/src/search/index.ts +69 -0
  102. package/src/search/indexer.ts +92 -0
  103. package/src/search/keyword.ts +86 -0
  104. package/src/search/semantic.ts +75 -0
  105. package/src/search/staleness.ts +8 -0
  106. package/src/validation/schema.ts +103 -0
@@ -0,0 +1,18 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebFetch(domain:github.com)",
5
+ "Bash(bun lint:*)",
6
+ "Bash(bun:*)",
7
+ "WebFetch(domain:docs.arcade.dev)",
8
+ "Bash(grep:*)",
9
+ "WebSearch",
10
+ "Bash(wc:*)",
11
+ "Bash(gh release:*)",
12
+ "Bash(gh run:*)",
13
+ "Bash(mcpcli search:*)",
14
+ "Bash(mcpcli call:*)",
15
+ "Bash(mcpcli:*)"
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,165 @@
1
+ ---
2
+ name: mcpx
3
+ description: Discover and use MCP tools via the mcpx CLI
4
+ trigger: when the user wants to interact with external services, APIs, or MCP tools
5
+ ---
6
+
7
+ # mcpx — MCP Tool Discovery and Execution
8
+
9
+ You have access to external tools via `mcpx`. Use this workflow:
10
+
11
+ ## 1. Search for tools
12
+
13
+ ```bash
14
+ mcpx search "<what you want to do>"
15
+ ```
16
+
17
+ ## 2. Inspect the tool schema
18
+
19
+ ```bash
20
+ mcpx info <server> <tool>
21
+ ```
22
+
23
+ This shows parameters, types, required fields, and the full JSON Schema.
24
+
25
+ ## 3. Execute the tool
26
+
27
+ ```bash
28
+ mcpx exec <server> <tool> '<json args>'
29
+ mcpx exec <server> <tool> -f params.json
30
+ ```
31
+
32
+ ## Rules
33
+
34
+ - Always search before executing — don't assume tool names exist
35
+ - Always inspect the schema before executing — validate you have the right arguments
36
+ - Use `mcpx search -k` for exact name matching
37
+ - Pipe results through `jq` when you need to extract specific fields
38
+ - Use `-v` for verbose debugging (HTTP details + JSON-RPC protocol messages) if an exec fails unexpectedly
39
+ - Use `-l debug` to see all server log messages, or `-l error` for errors only
40
+
41
+ ## Examples
42
+
43
+ ```bash
44
+ # Find tools related to sending messages
45
+ mcpx search "send a message"
46
+
47
+ # See what parameters Slack_SendMessage needs
48
+ mcpx info arcade Slack_SendMessage
49
+
50
+ # Send a message
51
+ mcpx exec arcade Slack_SendMessage '{"channel":"#general","message":"hello"}'
52
+
53
+ # Chain commands — search repos and read the first result
54
+ mcpx exec github search_repositories '{"query":"mcp"}' \
55
+ | jq -r '.content[0].text | fromjson | .items[0].full_name' \
56
+ | xargs -I {} mcpx exec github get_file_contents '{"owner":"{}","path":"README.md"}'
57
+
58
+ # Read args from stdin
59
+ echo '{"path":"./README.md"}' | mcpx exec filesystem read_file
60
+
61
+ # Pipe from a file
62
+ cat params.json | mcpx exec server tool
63
+
64
+ # Read args from a file with --file flag
65
+ mcpx exec filesystem read_file -f params.json
66
+ ```
67
+
68
+ ## 4. Long-running tools (Tasks)
69
+
70
+ Some tools support async execution via MCP Tasks. mcpx auto-detects this and uses task-augmented execution when available.
71
+
72
+ ```bash
73
+ # Default: waits for the task to complete, showing progress
74
+ mcpx exec my-server long_running_tool '{"input": "data"}'
75
+
76
+ # Return immediately with a task handle (for scripting/polling)
77
+ mcpx exec my-server long_running_tool '{"input": "data"}' --no-wait
78
+
79
+ # Check task status
80
+ mcpx task get my-server <taskId>
81
+
82
+ # Retrieve the result once complete
83
+ mcpx task result my-server <taskId>
84
+
85
+ # List all tasks on a server
86
+ mcpx task list my-server
87
+
88
+ # Cancel a running task
89
+ mcpx task cancel my-server <taskId>
90
+ ```
91
+
92
+ For tools that don't support tasks, `exec` works exactly as before.
93
+
94
+ ## 5. Elicitation (Server-Requested Input)
95
+
96
+ Some servers request user input mid-operation (e.g., confirmations, auth flows). mcpx handles this automatically:
97
+
98
+ ```bash
99
+ # Interactive — prompts appear in the terminal
100
+ mcpx exec my-server deploy_tool '{"target": "staging"}'
101
+ # Server requests input: Confirm deployment
102
+ # *Confirm [y/n]: y
103
+
104
+ # Non-interactive — decline all elicitation (for scripts/CI)
105
+ mcpx exec my-server deploy_tool '{"target": "staging"}' --no-interactive
106
+
107
+ # JSON mode — read/write elicitation as JSON via stdin/stdout
108
+ echo '{"action":"accept","content":{"confirm":true}}' | \
109
+ mcpx exec my-server deploy_tool '{"target": "staging"}' --json
110
+ ```
111
+
112
+ ## Authentication
113
+
114
+ Some HTTP servers require OAuth. If you see an "Not authenticated" error:
115
+
116
+ ```bash
117
+ mcpx auth <server> # authenticate via browser
118
+ mcpx auth <server> -s # check token status and TTL
119
+ mcpx auth <server> -r # force token refresh
120
+ mcpx deauth <server> # remove stored auth
121
+ ```
122
+
123
+ ## Available commands
124
+
125
+ | Command | Purpose |
126
+ | -------------------------------------- | --------------------------------- |
127
+ | `mcpx` | List all servers and tools |
128
+ | `mcpx servers` | List servers (name, type, detail) |
129
+ | `mcpx -d` | List with descriptions |
130
+ | `mcpx info <server>` | Server overview (version, capabilities, tools) |
131
+ | `mcpx info <server> <tool>` | Show tool schema |
132
+ | `mcpx exec <server>` | List tools for a server |
133
+ | `mcpx exec <server> <tool> '<json>'` | Execute a tool |
134
+ | `mcpx exec <server> <tool> -f file` | Execute with args from file |
135
+ | `mcpx search "<query>"` | Search tools (keyword + semantic) |
136
+ | `mcpx search -k "<pattern>"` | Keyword/glob search only |
137
+ | `mcpx search -q "<query>"` | Semantic search only |
138
+ | `mcpx search -n <number> "<query>"` | Limit number of results (default: 10) |
139
+ | `mcpx index` | Build/rebuild search index |
140
+ | `mcpx index -i` | Show index status |
141
+ | `mcpx auth <server>` | Authenticate with OAuth |
142
+ | `mcpx auth <server> -s` | Check token status and TTL |
143
+ | `mcpx auth <server> -r` | Force token refresh |
144
+ | `mcpx deauth <server>` | Remove stored authentication |
145
+ | `mcpx ping` | Check connectivity to all servers |
146
+ | `mcpx ping <server> [server2...]` | Check specific server(s) |
147
+ | `mcpx add <name> --command <cmd>` | Add a stdio MCP server |
148
+ | `mcpx add <name> --url <url>` | Add an HTTP MCP server |
149
+ | `mcpx add <name> --url <url> --transport sse` | Add a legacy SSE server |
150
+ | `mcpx remove <name>` | Remove an MCP server |
151
+ | `mcpx skill install --claude` | Install mcpx skill for Claude |
152
+ | `mcpx skill install --cursor` | Install mcpx rule for Cursor |
153
+ | `mcpx resource` | List all resources across servers |
154
+ | `mcpx resource <server>` | List resources for a server |
155
+ | `mcpx resource <server> <uri>` | Read a specific resource |
156
+ | `mcpx prompt` | List all prompts across servers |
157
+ | `mcpx prompt <server>` | List prompts for a server |
158
+ | `mcpx prompt <server> <name> '<json>'` | Get a specific prompt |
159
+ | `mcpx exec <server> <tool> --no-wait` | Execute as async task, return handle |
160
+ | `mcpx exec <server> <tool> --ttl <ms>` | Set task TTL (default: 60000) |
161
+ | `mcpx -N exec <server> <tool> ...` | Decline elicitation (non-interactive) |
162
+ | `mcpx task list <server>` | List tasks on a server |
163
+ | `mcpx task get <server> <taskId>` | Get task status |
164
+ | `mcpx task result <server> <taskId>` | Retrieve completed task result |
165
+ | `mcpx task cancel <server> <taskId>` | Cancel a running task |
@@ -0,0 +1,18 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebFetch(domain:github.com)",
5
+ "Bash(bun lint:*)",
6
+ "Bash(bun:*)",
7
+ "WebFetch(domain:docs.arcade.dev)",
8
+ "Bash(grep:*)",
9
+ "WebSearch",
10
+ "Bash(wc:*)",
11
+ "Bash(gh release:*)",
12
+ "Bash(gh run:*)",
13
+ "Bash(mcpcli search:*)",
14
+ "Bash(mcpcli call:*)",
15
+ "Bash(mcpcli:*)"
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: mcpcli
3
+ description: Discover and use MCP tools via the mcpcli CLI
4
+ trigger: when the user wants to interact with external services, APIs, or MCP tools
5
+ ---
6
+
7
+ # mcpcli — MCP Tool Discovery and Execution
8
+
9
+ You have access to external tools via `mcpcli`. Use this workflow:
10
+
11
+ ## 1. Search for tools
12
+
13
+ ```bash
14
+ mcpcli search "<what you want to do>"
15
+ ```
16
+
17
+ ## 2. Inspect the tool schema
18
+
19
+ ```bash
20
+ mcpcli info <server> <tool>
21
+ ```
22
+
23
+ This shows parameters, types, required fields, and the full JSON Schema.
24
+
25
+ ## 3. Execute the tool
26
+
27
+ ```bash
28
+ mcpcli exec <server> <tool> '<json args>'
29
+ ```
30
+
31
+ ## Rules
32
+
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
+ - Use `mcpcli search -k` for exact name matching
36
+ - Pipe results through `jq` when you need to extract specific fields
37
+ - Use `-v` for verbose HTTP debugging if an exec fails unexpectedly
38
+
39
+ ## Examples
40
+
41
+ ```bash
42
+ # Find tools related to sending messages
43
+ mcpcli search "send a message"
44
+
45
+ # See what parameters Slack_SendMessage needs
46
+ mcpcli info arcade Slack_SendMessage
47
+
48
+ # Send a message
49
+ mcpcli exec arcade Slack_SendMessage '{"channel":"#general","message":"hello"}'
50
+
51
+ # Chain commands — search repos and read the first result
52
+ mcpcli exec github search_repositories '{"query":"mcp"}' \
53
+ | jq -r '.content[0].text | fromjson | .items[0].full_name' \
54
+ | xargs -I {} mcpcli exec github get_file_contents '{"owner":"{}","path":"README.md"}'
55
+
56
+ # Read args from stdin
57
+ echo '{"path":"./README.md"}' | mcpcli exec filesystem read_file
58
+ ```
59
+
60
+ ## Authentication
61
+
62
+ Some HTTP servers require OAuth. If you see an "Not authenticated" error:
63
+
64
+ ```bash
65
+ mcpcli auth <server> # authenticate via browser
66
+ mcpcli auth <server> -s # check token status and TTL
67
+ mcpcli auth <server> -r # force token refresh
68
+ mcpcli deauth <server> # remove stored auth
69
+ ```
70
+
71
+ ## Available commands
72
+
73
+ | Command | Purpose |
74
+ | -------------------------------------- | --------------------------------- |
75
+ | `mcpcli` | List all servers and tools |
76
+ | `mcpcli -d` | List with descriptions |
77
+ | `mcpcli info <server>` | Show tools for a server |
78
+ | `mcpcli info <server> <tool>` | Show tool schema |
79
+ | `mcpcli exec <server>` | List tools for a server |
80
+ | `mcpcli exec <server> <tool> '<json>'` | Execute a tool |
81
+ | `mcpcli search "<query>"` | Search tools (keyword + semantic) |
82
+ | `mcpcli search -k "<pattern>"` | Keyword/glob search only |
83
+ | `mcpcli search -q "<query>"` | Semantic search only |
84
+ | `mcpcli index` | Build/rebuild search index |
85
+ | `mcpcli index -i` | Show index status |
86
+ | `mcpcli auth <server>` | Authenticate with OAuth |
87
+ | `mcpcli auth <server> -s` | Check token status and TTL |
88
+ | `mcpcli auth <server> -r` | Force token refresh |
89
+ | `mcpcli deauth <server>` | Remove stored authentication |
90
+ | `mcpcli add <name> --command <cmd>` | Add a stdio MCP server |
91
+ | `mcpcli add <name> --url <url>` | Add an HTTP MCP server |
92
+ | `mcpcli remove <name>` | Remove an MCP server |
93
+ | `mcpcli skill install --claude` | Install mcpcli skill for Claude |
@@ -0,0 +1,117 @@
1
+ name: Auto Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ check-version:
14
+ runs-on: ubuntu-latest
15
+ outputs:
16
+ should_release: ${{ steps.check.outputs.should_release }}
17
+ tag: ${{ steps.version.outputs.tag }}
18
+ version: ${{ steps.version.outputs.version }}
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+
22
+ - name: Get version from package.json
23
+ id: version
24
+ run: |
25
+ VERSION=$(jq -r .version package.json)
26
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
27
+ echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
28
+
29
+ - name: Check if release exists
30
+ id: check
31
+ run: |
32
+ if gh release view "${{ steps.version.outputs.tag }}" &>/dev/null; then
33
+ echo "should_release=false" >> "$GITHUB_OUTPUT"
34
+ else
35
+ echo "should_release=true" >> "$GITHUB_OUTPUT"
36
+ fi
37
+ env:
38
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39
+
40
+ create-release:
41
+ needs: check-version
42
+ if: needs.check-version.outputs.should_release == 'true'
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+ - name: Create release
47
+ run: |
48
+ gh release create "${{ needs.check-version.outputs.tag }}" \
49
+ --title "${{ needs.check-version.outputs.tag }}" \
50
+ --generate-notes
51
+ env:
52
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53
+
54
+ ci:
55
+ needs: [check-version, create-release]
56
+ if: needs.check-version.outputs.should_release == 'true'
57
+ runs-on: ubuntu-latest
58
+ steps:
59
+ - uses: actions/checkout@v4
60
+ - uses: oven-sh/setup-bun@v2
61
+ with:
62
+ bun-version: latest
63
+ - run: bun install --frozen-lockfile
64
+ - run: bun lint
65
+ - run: bun test
66
+
67
+ publish-npm:
68
+ needs: [check-version, ci]
69
+ if: needs.check-version.outputs.should_release == 'true'
70
+ runs-on: ubuntu-latest
71
+ permissions:
72
+ contents: read
73
+ id-token: write
74
+ steps:
75
+ - uses: actions/checkout@v4
76
+ - uses: oven-sh/setup-bun@v2
77
+ with:
78
+ bun-version: latest
79
+ - uses: actions/setup-node@v4
80
+ with:
81
+ node-version: 22
82
+ registry-url: https://registry.npmjs.org
83
+ - run: npm install -g npm@latest
84
+ - run: bun install --frozen-lockfile
85
+ - run: npm publish --provenance --access public
86
+
87
+ build-binaries:
88
+ needs: [check-version, ci]
89
+ if: needs.check-version.outputs.should_release == 'true'
90
+ runs-on: ubuntu-latest
91
+ strategy:
92
+ matrix:
93
+ include:
94
+ - target: bun-darwin-arm64
95
+ artifact: mcpcli-darwin-arm64
96
+ - target: bun-darwin-x64
97
+ artifact: mcpcli-darwin-x64
98
+ - target: bun-linux-arm64
99
+ artifact: mcpcli-linux-arm64
100
+ - target: bun-linux-x64
101
+ artifact: mcpcli-linux-x64
102
+ steps:
103
+ - uses: actions/checkout@v4
104
+ - uses: oven-sh/setup-bun@v2
105
+ with:
106
+ bun-version: latest
107
+ - run: bun install --frozen-lockfile
108
+ - name: Build binary
109
+ run: |
110
+ bun build --compile --minify --sourcemap \
111
+ --target=${{ matrix.target }} \
112
+ --define BUILD_VERSION="'\"${{ needs.check-version.outputs.version }}\"'" \
113
+ ./src/cli.ts --outfile dist/${{ matrix.artifact }}
114
+ - name: Upload to release
115
+ run: gh release upload "${{ needs.check-version.outputs.tag }}" dist/${{ matrix.artifact }} --clobber
116
+ env:
117
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,18 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ check:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: oven-sh/setup-bun@v2
14
+ with:
15
+ bun-version: latest
16
+ - run: bun install --frozen-lockfile
17
+ - run: bun lint
18
+ - run: bun test
@@ -0,0 +1,4 @@
1
+ node_modules
2
+ dist
3
+ bun.lock
4
+ .claude
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": false,
4
+ "trailingComma": "all",
5
+ "printWidth": 100,
6
+ "tabWidth": 2
7
+ }
@@ -0,0 +1,19 @@
1
+ # CLAUDE.md
2
+
3
+ ## Project
4
+
5
+ mcpcli — A CLI for MCP servers. "curl for MCP."
6
+
7
+ ## Commands
8
+
9
+ - `bun run dev` — Run in development mode
10
+ - `bun test` — Run tests
11
+ - `bun lint` — Check formatting (prettier)
12
+ - `bun format` — Auto-fix formatting
13
+ - `bun run build` — Build single binary
14
+
15
+ ## Rules
16
+
17
+ - **Always bump the patch version in `package.json`** when making any code changes (source, tests, config). Use semver: patch for fixes/small changes, minor for new features, major for breaking changes.
18
+ - **Always keep `README.md` and `.claude/skills/mcpcli.md` in sync** with any CLI changes (commands, flags, syntax, examples). The skill file includes workflow steps, code examples, and a command table that must all reflect the current CLI surface.
19
+ - **Always run `bun run format`** before committing to fix prettier formatting issues.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Evan Tahler
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.