mcp-cli-skill 0.5.2__tar.gz → 0.5.3__tar.gz
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.
- {mcp_cli_skill-0.5.2 → mcp_cli_skill-0.5.3}/PKG-INFO +1 -1
- {mcp_cli_skill-0.5.2 → mcp_cli_skill-0.5.3}/scripts/mcp_call.py +28 -5
- {mcp_cli_skill-0.5.2 → mcp_cli_skill-0.5.3}/src/mcp_cli_skill/__init__.py +1 -1
- {mcp_cli_skill-0.5.2 → mcp_cli_skill-0.5.3}/src/mcp_cli_skill/cli.py +28 -5
- {mcp_cli_skill-0.5.2 → mcp_cli_skill-0.5.3}/README.md +0 -0
- {mcp_cli_skill-0.5.2 → mcp_cli_skill-0.5.3}/SKILL.md +0 -0
- {mcp_cli_skill-0.5.2 → mcp_cli_skill-0.5.3}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-cli-skill
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
4
4
|
Summary: Call any MCP server tool from the command line with shell composition support
|
|
5
5
|
Project-URL: Homepage, https://github.com/wise-toddler/mcp-cli-skill
|
|
6
6
|
Project-URL: Repository, https://github.com/wise-toddler/mcp-cli-skill
|
|
@@ -8,6 +8,7 @@ import sys
|
|
|
8
8
|
import tempfile
|
|
9
9
|
import re
|
|
10
10
|
import shutil
|
|
11
|
+
import urllib.parse
|
|
11
12
|
import urllib.request
|
|
12
13
|
import urllib.error
|
|
13
14
|
|
|
@@ -213,6 +214,30 @@ class HttpSession:
|
|
|
213
214
|
self.session_id = None
|
|
214
215
|
self.extra_headers = {k: _expand_env(v) for k, v in (extra_headers or {}).items()}
|
|
215
216
|
|
|
217
|
+
def _send(self, data, headers, timeout=30, max_redirects=3):
|
|
218
|
+
"""POST data and follow 307/308 redirects preserving method+body.
|
|
219
|
+
|
|
220
|
+
urllib's default HTTPRedirectHandler does NOT follow 307/308 on POST,
|
|
221
|
+
only on GET/HEAD. We handle them explicitly here.
|
|
222
|
+
"""
|
|
223
|
+
url = self.url
|
|
224
|
+
for _ in range(max_redirects + 1):
|
|
225
|
+
req = urllib.request.Request(url, data=data, headers=headers)
|
|
226
|
+
try:
|
|
227
|
+
return urllib.request.urlopen(req, timeout=timeout)
|
|
228
|
+
except urllib.error.HTTPError as e:
|
|
229
|
+
if e.code in (307, 308) and e.headers.get("Location"):
|
|
230
|
+
new_url = urllib.parse.urljoin(url, e.headers["Location"])
|
|
231
|
+
try:
|
|
232
|
+
e.close()
|
|
233
|
+
except Exception:
|
|
234
|
+
pass
|
|
235
|
+
url = new_url
|
|
236
|
+
self.url = url # cache redirected URL for subsequent calls
|
|
237
|
+
continue
|
|
238
|
+
raise
|
|
239
|
+
raise urllib.error.HTTPError(url, 308, "Too many redirects", None, None)
|
|
240
|
+
|
|
216
241
|
def rpc(self, method, params=None, msg_id=1):
|
|
217
242
|
"""Send JSON-RPC over HTTP and return response."""
|
|
218
243
|
msg = {"jsonrpc": "2.0", "method": method, "id": msg_id}
|
|
@@ -227,9 +252,8 @@ class HttpSession:
|
|
|
227
252
|
headers.update(self.extra_headers)
|
|
228
253
|
if self.session_id:
|
|
229
254
|
headers["Mcp-Session-Id"] = self.session_id
|
|
230
|
-
req = urllib.request.Request(self.url, data=data, headers=headers)
|
|
231
255
|
try:
|
|
232
|
-
with
|
|
256
|
+
with self._send(data, headers) as resp:
|
|
233
257
|
# capture session ID from response
|
|
234
258
|
sid = resp.headers.get("Mcp-Session-Id")
|
|
235
259
|
if sid:
|
|
@@ -259,13 +283,12 @@ class HttpSession:
|
|
|
259
283
|
if params:
|
|
260
284
|
msg["params"] = params
|
|
261
285
|
data = json.dumps(msg).encode()
|
|
262
|
-
headers = {"Content-Type": "application/json"}
|
|
286
|
+
headers = {"Content-Type": "application/json", "User-Agent": "mcp-cli/1.0"}
|
|
263
287
|
headers.update(self.extra_headers)
|
|
264
288
|
if self.session_id:
|
|
265
289
|
headers["Mcp-Session-Id"] = self.session_id
|
|
266
|
-
req = urllib.request.Request(self.url, data=data, headers=headers)
|
|
267
290
|
try:
|
|
268
|
-
|
|
291
|
+
self._send(data, headers, timeout=10)
|
|
269
292
|
except Exception:
|
|
270
293
|
pass
|
|
271
294
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""MCP CLI - Call any MCP server tool from the command line."""
|
|
2
|
-
__version__ = "0.5.
|
|
2
|
+
__version__ = "0.5.3"
|
|
@@ -8,6 +8,7 @@ import sys
|
|
|
8
8
|
import tempfile
|
|
9
9
|
import re
|
|
10
10
|
import shutil
|
|
11
|
+
import urllib.parse
|
|
11
12
|
import urllib.request
|
|
12
13
|
import urllib.error
|
|
13
14
|
|
|
@@ -213,6 +214,30 @@ class HttpSession:
|
|
|
213
214
|
self.session_id = None
|
|
214
215
|
self.extra_headers = {k: _expand_env(v) for k, v in (extra_headers or {}).items()}
|
|
215
216
|
|
|
217
|
+
def _send(self, data, headers, timeout=30, max_redirects=3):
|
|
218
|
+
"""POST data and follow 307/308 redirects preserving method+body.
|
|
219
|
+
|
|
220
|
+
urllib's default HTTPRedirectHandler does NOT follow 307/308 on POST,
|
|
221
|
+
only on GET/HEAD. We handle them explicitly here.
|
|
222
|
+
"""
|
|
223
|
+
url = self.url
|
|
224
|
+
for _ in range(max_redirects + 1):
|
|
225
|
+
req = urllib.request.Request(url, data=data, headers=headers)
|
|
226
|
+
try:
|
|
227
|
+
return urllib.request.urlopen(req, timeout=timeout)
|
|
228
|
+
except urllib.error.HTTPError as e:
|
|
229
|
+
if e.code in (307, 308) and e.headers.get("Location"):
|
|
230
|
+
new_url = urllib.parse.urljoin(url, e.headers["Location"])
|
|
231
|
+
try:
|
|
232
|
+
e.close()
|
|
233
|
+
except Exception:
|
|
234
|
+
pass
|
|
235
|
+
url = new_url
|
|
236
|
+
self.url = url # cache redirected URL for subsequent calls
|
|
237
|
+
continue
|
|
238
|
+
raise
|
|
239
|
+
raise urllib.error.HTTPError(url, 308, "Too many redirects", None, None)
|
|
240
|
+
|
|
216
241
|
def rpc(self, method, params=None, msg_id=1):
|
|
217
242
|
"""Send JSON-RPC over HTTP and return response."""
|
|
218
243
|
msg = {"jsonrpc": "2.0", "method": method, "id": msg_id}
|
|
@@ -227,9 +252,8 @@ class HttpSession:
|
|
|
227
252
|
headers.update(self.extra_headers)
|
|
228
253
|
if self.session_id:
|
|
229
254
|
headers["Mcp-Session-Id"] = self.session_id
|
|
230
|
-
req = urllib.request.Request(self.url, data=data, headers=headers)
|
|
231
255
|
try:
|
|
232
|
-
with
|
|
256
|
+
with self._send(data, headers) as resp:
|
|
233
257
|
# capture session ID from response
|
|
234
258
|
sid = resp.headers.get("Mcp-Session-Id")
|
|
235
259
|
if sid:
|
|
@@ -259,13 +283,12 @@ class HttpSession:
|
|
|
259
283
|
if params:
|
|
260
284
|
msg["params"] = params
|
|
261
285
|
data = json.dumps(msg).encode()
|
|
262
|
-
headers = {"Content-Type": "application/json"}
|
|
286
|
+
headers = {"Content-Type": "application/json", "User-Agent": "mcp-cli/1.0"}
|
|
263
287
|
headers.update(self.extra_headers)
|
|
264
288
|
if self.session_id:
|
|
265
289
|
headers["Mcp-Session-Id"] = self.session_id
|
|
266
|
-
req = urllib.request.Request(self.url, data=data, headers=headers)
|
|
267
290
|
try:
|
|
268
|
-
|
|
291
|
+
self._send(data, headers, timeout=10)
|
|
269
292
|
except Exception:
|
|
270
293
|
pass
|
|
271
294
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|