cli2mcp 0.1.1__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.
@@ -0,0 +1,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .venv/
7
+ debug.log
@@ -0,0 +1,164 @@
1
+ # Debugging the MCP Server
2
+
3
+ ## MCP transports
4
+
5
+ MCP defines two standard transports:
6
+
7
+ | Transport | When to use | How it works |
8
+ |---|---|---|
9
+ | **stdio** | Local — IDE spawns the server as a child process | JSON-RPC over stdin/stdout pipes |
10
+ | **Streamable HTTP** | Remote — server is a standalone HTTP service | JSON-RPC via POST to a single `/mcp` endpoint |
11
+
12
+ **Streamable HTTP** is the easiest to debug with `curl` because it is plain
13
+ HTTP: you POST JSON-RPC messages and read the response. The server replies
14
+ with either `application/json` or an SSE stream (`text/event-stream`);
15
+ the Python MCP SDK currently always uses SSE, so we extract the `data:`
16
+ line from each response.
17
+
18
+ ---
19
+
20
+ ## Start the servers
21
+
22
+ Terminal 1 — a tiny target server so the demo is fully self-contained:
23
+
24
+ ```bash
25
+ python3 -c '
26
+ from http.server import HTTPServer, BaseHTTPRequestHandler
27
+ class H(BaseHTTPRequestHandler):
28
+ def do_GET(s): s.send_response(200); s.end_headers(); s.wfile.write(b"Hello, world!\n")
29
+ def log_message(s, *a): pass
30
+ HTTPServer(("127.0.0.1", 9000), H).serve_forever()
31
+ '
32
+ ```
33
+
34
+ Terminal 2 — the MCP server:
35
+
36
+ ```bash
37
+ uv run cli2mcp serve examples/curl.tools.json -t streamable-http
38
+ ```
39
+
40
+ Leave both running. All commands below run in a **third terminal**
41
+ (or just run the script: `./examples/debug_demo.sh`).
42
+
43
+ ## 1. Initialize a session
44
+
45
+ Every MCP conversation starts with a handshake.
46
+
47
+ `examples/requests/1_initialize.json`:
48
+
49
+ ```json
50
+ {
51
+ "jsonrpc": "2.0",
52
+ "id": 1,
53
+ "method": "initialize",
54
+ "params": {
55
+ "protocolVersion": "2025-06-18",
56
+ "capabilities": {},
57
+ "clientInfo": {
58
+ "name": "debug",
59
+ "version": "1.0"
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ Send it and capture the session ID:
66
+
67
+ ```bash
68
+ SESSION=$(curl -s -D- -X POST http://localhost:8000/mcp \
69
+ -H 'Content-Type: application/json' \
70
+ -H 'Accept: application/json, text/event-stream' \
71
+ -d @examples/requests/1_initialize.json \
72
+ | grep -i mcp-session-id | awk '{print $2}' | tr -d '\r')
73
+
74
+ echo "Session: $SESSION"
75
+ ```
76
+
77
+ ## 2. Confirm the handshake
78
+
79
+ `examples/requests/2_initialized.json`:
80
+
81
+ ```json
82
+ {
83
+ "jsonrpc": "2.0",
84
+ "method": "notifications/initialized"
85
+ }
86
+ ```
87
+
88
+ ```bash
89
+ curl -s -X POST http://localhost:8000/mcp \
90
+ -H 'Content-Type: application/json' \
91
+ -H 'Accept: application/json, text/event-stream' \
92
+ -H "Mcp-Session-Id: $SESSION" \
93
+ -d @examples/requests/2_initialized.json
94
+ ```
95
+
96
+ This is a notification (no `id` field), so the server returns an empty
97
+ HTTP 202 response.
98
+
99
+ ## 3. List available tools
100
+
101
+ `examples/requests/3_list_tools.json`:
102
+
103
+ ```json
104
+ {
105
+ "jsonrpc": "2.0",
106
+ "id": 2,
107
+ "method": "tools/list"
108
+ }
109
+ ```
110
+
111
+ ```bash
112
+ curl -s -X POST http://localhost:8000/mcp \
113
+ -H 'Content-Type: application/json' \
114
+ -H 'Accept: application/json, text/event-stream' \
115
+ -H "Mcp-Session-Id: $SESSION" \
116
+ -d @examples/requests/3_list_tools.json \
117
+ | grep '^data:' | sed 's/^data: //' | python3 -m json.tool
118
+ ```
119
+
120
+ Expected: a `tools` array with `curl` and its `inputSchema` listing
121
+ all available arguments (`data`, `output`, `url`, etc.).
122
+
123
+ ## 4. Call the tool to fetch a web page
124
+
125
+ `examples/requests/4_call_tool.json`:
126
+
127
+ ```json
128
+ {
129
+ "jsonrpc": "2.0",
130
+ "id": 3,
131
+ "method": "tools/call",
132
+ "params": {
133
+ "name": "curl",
134
+ "arguments": {
135
+ "url": "http://127.0.0.1:9000"
136
+ }
137
+ }
138
+ }
139
+ ```
140
+
141
+ ```bash
142
+ curl -s -X POST http://localhost:8000/mcp \
143
+ -H 'Content-Type: application/json' \
144
+ -H 'Accept: application/json, text/event-stream' \
145
+ -H "Mcp-Session-Id: $SESSION" \
146
+ -d @examples/requests/4_call_tool.json \
147
+ | grep '^data:' | sed 's/^data: //' | python3 -m json.tool
148
+ ```
149
+
150
+ Expected: `content[0].text` contains `Hello, world!`.
151
+
152
+ ## What just happened
153
+
154
+ ```
155
+ You (curl) ---> MCP server (:8000) ---> curl ---> hello_server (:9000)
156
+ HTTP POST reads tools.json subprocess "Hello, world!"
157
+ JSON-RPC builds command runs it returned
158
+ ```
159
+
160
+ 1. Your curl sent a JSON-RPC `tools/call` to the MCP server over **Streamable HTTP**
161
+ 2. The server looked up `curl` in `examples/curl.tools.json`
162
+ 3. It built the command: `curl http://127.0.0.1:9000`
163
+ 4. It ran it with `subprocess.run()`
164
+ 5. It returned stdout (`Hello, world!`) as MCP tool output wrapped in an SSE `data:` line