@@ -12,24 +12,69 @@ This skill shows any agent how to call RagCode MCP directly via HTTP + Server‑
1212## 🔌 Endpoints
1313
1414```
15- GET /sse # open the event stream (keep-alive)
16- POST /messages # send JSON-RPC requests
15+ GET /sse # Opens the persistent stream
16+ POST /sse?sessionid=ID # Send JSON-RPC (exact URL from the endpoint event)
1717```
1818
19- Set the port with the ` -http-port ` flag (default ` 3000 ` ). Example URLs:
19+ ### 🔑 Session Handshake
20+ 1 . Connect to ` GET /sse ` and keep the connection open.
21+ 2 . The first SSE event is ` event: endpoint ` .
22+ 3 . Its data is the full POST URL, e.g.: ` data: /sse?sessionid=H3QCVDP32TP3RBZQ5WLMEJSRF `
23+ 4 . ** Required** : send ` initialize ` + ` notifications/initialized ` before any ` tools/call ` .
24+ 5 . All responses are delivered back on the open SSE stream.
2025
21- ```
22- SSE stream : http://localhost:3000/sse
23- Send message: http://localhost:3000/messages
26+ ### 🧾 Bash Script (Tested and working)
27+ ``` bash
28+ #! /bin/bash
29+ SSE_FILE=$( mktemp)
30+ curl -s -N -H ' Accept: text/event-stream' http://localhost:3000/sse >> " $SSE_FILE " &
31+ SSE_PID=$!
32+ sleep 1
33+
34+ # Extract the POST URL from the endpoint event
35+ ENDPOINT=$( grep ' data:' " $SSE_FILE " | head -1 | sed ' s/^data: //' | tr -d ' [:space:]' )
36+ POST_URL=" http://localhost:3000${ENDPOINT} "
37+
38+ # 1. MCP handshake - initialize
39+ curl -s -X POST " $POST_URL " -H ' Content-Type: application/json' -d ' {
40+ "jsonrpc": "2.0", "id": 1, "method": "initialize",
41+ "params": {"protocolVersion": "2024-11-05", "capabilities": {},
42+ "clientInfo": {"name": "my-agent", "version": "1.0"}}
43+ }' && sleep 1
44+
45+ # 2. MCP handshake - initialized notification
46+ curl -s -X POST " $POST_URL " -H ' Content-Type: application/json' -d ' {
47+ "jsonrpc": "2.0", "method": "notifications/initialized"
48+ }' && sleep 1
49+
50+ # 3. Tool call
51+ curl -s -X POST " $POST_URL " -H ' Content-Type: application/json' -d ' {
52+ "jsonrpc": "2.0", "id": 2, "method": "tools/call",
53+ "params": {
54+ "name": "rag_search_code",
55+ "arguments": {
56+ "query": "automatic update implementation",
57+ "file_path": "/your/project/file.go"
58+ }
59+ }
60+ }'
61+
62+ # 4. Read the response from the SSE stream
63+ sleep 12
64+ kill $SSE_PID 2> /dev/null
65+ cat " $SSE_FILE "
66+ rm " $SSE_FILE "
2467```
2568
2669---
2770
2871## 🧠 Protocol Basics
2972
30- 1 . Keep a persistent SSE connection to ` /sse ` (subscribe to events).
31- 2 . Send JSON-RPC payloads to ` /messages ` .
32- 3 . Responses arrive asynchronously on the SSE stream (matching ` id ` ).
73+ 1 . Keep a persistent SSE connection via ` GET /sse ` .
74+ 2 . Read the first ` event: endpoint ` to get the POST URL (` /sse?sessionid=ID ` ).
75+ 3 . Send ` initialize ` + ` notifications/initialized ` (MCP handshake) before any tool call.
76+ 4 . Send JSON-RPC payloads via ` POST /sse?sessionid=ID ` .
77+ 5 . Responses arrive asynchronously on the SSE stream (match by ` id ` ).
3378
3479### JSON-RPC Template
3580
@@ -55,16 +100,32 @@ Use other MCP methods such as `tools/list`, `ping`, etc.
55100
56101## 🧾 curl Quick Start
57102
58- Open a stream (terminal tab A) :
103+ Tab A — open the stream and note the POST URL :
59104
60105``` bash
61- curl -N http://localhost:3000/sse
106+ curl -N -H ' Accept: text/event-stream' http://localhost:3000/sse
107+ # First output: data: /sse?sessionid=XXXXXX <-- this is your POST_URL
62108```
63109
64- Send a message (terminal tab B ):
110+ Tab B — full sequence (replace ` XXXXXX ` with the real sessionid ):
65111
66112``` bash
67- curl -X POST http://localhost:3000/messages \
113+ POST_URL=" http://localhost:3000/sse?sessionid=XXXXXX"
114+
115+ # Step 1: initialize
116+ curl -X POST " $POST_URL " -H ' Content-Type: application/json' -d ' {
117+ "jsonrpc": "2.0", "id": 1, "method": "initialize",
118+ "params": {"protocolVersion": "2024-11-05", "capabilities": {},
119+ "clientInfo": {"name": "curl-client", "version": "1.0"}}
120+ }' && sleep 1
121+
122+ # Step 2: notifications/initialized
123+ curl -X POST " $POST_URL " -H ' Content-Type: application/json' -d ' {
124+ "jsonrpc": "2.0", "method": "notifications/initialized"
125+ }' && sleep 1
126+
127+ # Step 3: tools/call
128+ curl -X POST " $POST_URL " \
68129 -H ' Content-Type: application/json' \
69130 -d ' {
70131 "jsonrpc": "2.0",
@@ -87,25 +148,42 @@ Watch the SSE tab for the response.
87148## 🐍 Python Example
88149
89150``` python
90- import json, requests, sseclient
151+ import json, threading, requests, sseclient
91152
92- SSE_URL = " http://localhost:3000/sse"
93- MSG_URL = " http://localhost:3000/messages"
153+ BASE_URL = " http://localhost:3000"
94154
95- payload = {
96- " jsonrpc" : " 2.0" ,
97- " id" : " list-tools" ,
98- " method" : " tools/list" ,
99- " params" : {}
100- }
155+ # 1. Open SSE stream and extract POST URL
156+ resp = requests.get(f " { BASE_URL } /sse " , stream = True , headers = {" Accept" : " text/event-stream" })
157+ client = sseclient.SSEClient(resp)
101158
102- requests.post(MSG_URL , json = payload, timeout = 10 )
103- client = sseclient.SSEClient(SSE_URL )
159+ post_url = None
160+ for event in client.events():
161+ if event.event == " endpoint" :
162+ post_url = BASE_URL + event.data.strip()
163+ break
164+
165+ def post (payload ):
166+ requests.post(post_url, json = payload, timeout = 10 )
167+
168+ # 2. MCP Handshake
169+ post({" jsonrpc" : " 2.0" , " id" : 1 , " method" : " initialize" ,
170+ " params" : {" protocolVersion" : " 2024-11-05" , " capabilities" : {},
171+ " clientInfo" : {" name" : " py-agent" , " version" : " 1.0" }}})
172+ post({" jsonrpc" : " 2.0" , " method" : " notifications/initialized" })
173+
174+ # 3. Tool call
175+ post({" jsonrpc" : " 2.0" , " id" : 2 , " method" : " tools/call" ,
176+ " params" : {" name" : " rag_search_code" ,
177+ " arguments" : {" query" : " workspace registry" ,
178+ " file_path" : " /your/project/main.py" }}})
179+
180+ # 4. Read responses
104181for event in client.events():
105- print (event.data)
182+ if event.data:
183+ print (json.loads(event.data))
106184```
107185
108- Any SSE client works; just keep reading events and match IDs .
186+ Any SSE client works; keep the stream open and match responses by ` id ` .
109187
110188---
111189
@@ -128,17 +206,19 @@ Any SSE client works; just keep reading events and match IDs.
128206
129207| Symptom | Fix |
130208| --- | --- |
131- | No response | Ensure SSE connection is open; use unique ` id ` s per request. |
132- | 4xx on ` /messages ` | Check JSON validity and ` Content-Type: application/json ` . |
133- | Workspace errors | Always pass ` arguments.file_path ` for context detection. |
209+ | No response | Ensure SSE is open and MCP handshake was done; use unique ` id ` per request. |
210+ | 4xx on POST | Check JSON and ` Content-Type: application/json ` ; POST goes to ` /sse?sessionid=ID ` , not ` /messages ` . |
211+ | ` sessionid must be provided ` | Extract sessionid using ` sed 's/^data: //' ` on the ` data: ` line from the SSE stream. |
212+ | Workspace errors | Always pass an absolute path in ` arguments.file_path ` for workspace detection. |
134213
135214---
136215
137216## ✅ Summary
138217
139- - ** Endpoints** : ` GET /sse ` , ` POST /messages ` .
218+ - ** Endpoints** : ` GET /sse ` (stream), ` POST /sse?sessionid=ID ` (messages).
219+ - ** Required handshake** : ` initialize ` → ` notifications/initialized ` → ` tools/call ` .
140220- ** Protocol** : JSON-RPC 2.0 (MCP spec).
141- - ** Examples** : Provided for curl and Python.
142- - ** Tool discovery** : ` list_tools ` response .
221+ - ** Examples** : Provided for curl (bash) and Python.
222+ - ** Tool discovery** : call ` tools/list ` after handshake .
143223
144224Install this skill to teach any agent how to drive RagCode MCP over SSE immediately.
0 commit comments