Skip to content

Commit 1750e34

Browse files
committed
fix: Route hooks through MCP HTTP transport, not direct API
session-capture.sh and session-summarize.sh now POST JSON-RPC to localhost:4545/mcp (the MCP HTTP transport) instead of directly to the API. The MCP client already has SERIALMEMORY_ENDPOINT and SERIALMEMORY_API_KEY configured — hooks only need MCP_HTTP_TOKEN if bearer auth is enabled on the local transport. Removes need for SERIALMEMORY_ENDPOINT/SERIALMEMORY_API_KEY in the shell environment entirely. https://claude.ai/code/session_01M5GUmiM8WehUBUvKWiWgcJ
1 parent f66aba7 commit 1750e34

2 files changed

Lines changed: 55 additions & 47 deletions

File tree

ops/session-capture.sh

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#!/usr/bin/env bash
2-
# session-capture.sh - POST tool activity to SerialMemory API over HTTP
2+
# session-capture.sh - POST tool activity through MCP HTTP transport
33
# Called from PostToolUse hooks for Write/Edit/Bash
4-
# Reads tool result JSON from stdin, POSTs to /api/captures/entry
5-
# Designed for <100ms execution time — single HTTP POST, no MCP calls
4+
# Reads tool result JSON from stdin, sends JSON-RPC to MCP at localhost:4545
5+
# The MCP client already has the API key — no extra env vars needed
6+
# Designed for <100ms execution time — single HTTP POST, fire-and-forget
67
set -euo pipefail
78

8-
# SerialMemory API endpoint (set via env or default to localhost)
9-
API_URL="${SERIALMEMORY_ENDPOINT:-http://localhost:5000}"
10-
API_KEY="${SERIALMEMORY_API_KEY:-}"
9+
# MCP HTTP transport (always localhost, started alongside stdio)
10+
MCP_URL="${MCP_HTTP_URL:-http://localhost:4545}/mcp"
11+
MCP_TOKEN="${MCP_HTTP_TOKEN:-}"
1112

1213
# Session ID from Claude Code env var, fallback to date-based
1314
SESSION_ID="${CLAUDE_SESSION_ID:-$(date +%Y%m%d)}"
@@ -38,38 +39,42 @@ else
3839
RESULT=""
3940
fi
4041

41-
# Timestamp in ISO 8601
42-
TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
43-
44-
# Build JSON payload
42+
# Build JSON-RPC payload for MCP tools/call
4543
if command -v jq &>/dev/null; then
4644
PAYLOAD=$(jq -nc \
4745
--arg sid "$SESSION_ID" \
48-
--arg ts "$TS" \
4946
--arg tool "$TOOL_NAME" \
5047
--arg file "$FILE_PATH" \
5148
--arg result "$RESULT" \
52-
'{session_id: $sid, ts: $ts, tool: $tool, file: $file, result: $result}')
49+
'{
50+
jsonrpc: "2.0",
51+
id: 1,
52+
method: "tools/call",
53+
params: {
54+
name: "capture_entry",
55+
arguments: {
56+
session_id: $sid,
57+
tool: $tool,
58+
file: $file,
59+
result: $result
60+
}
61+
}
62+
}')
5363
else
54-
PAYLOAD="{\"session_id\":\"$SESSION_ID\",\"ts\":\"$TS\",\"tool\":\"$TOOL_NAME\",\"file\":\"$FILE_PATH\",\"result\":\"\"}"
55-
fi
56-
57-
# POST to API (fire-and-forget with timeout)
58-
AUTH_HEADER=""
59-
if [ -n "$API_KEY" ]; then
60-
AUTH_HEADER="-H \"Authorization: Bearer $API_KEY\""
64+
PAYLOAD="{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"capture_entry\",\"arguments\":{\"session_id\":\"$SESSION_ID\",\"tool\":\"$TOOL_NAME\",\"file\":\"$FILE_PATH\",\"result\":\"\"}}}"
6165
fi
6266

67+
# POST to MCP HTTP transport (fire-and-forget with 2s timeout)
6368
if command -v curl &>/dev/null; then
64-
curl -s -m 2 -X POST "${API_URL}/api/captures/entry" \
69+
curl -s -m 2 -X POST "$MCP_URL" \
6570
-H "Content-Type: application/json" \
66-
${API_KEY:+-H "Authorization: Bearer $API_KEY"} \
71+
${MCP_TOKEN:+-H "Authorization: Bearer $MCP_TOKEN"} \
6772
-d "$PAYLOAD" > /dev/null 2>&1 || true
6873
elif command -v wget &>/dev/null; then
69-
echo "$PAYLOAD" | wget -q -O /dev/null --timeout=2 \
74+
wget -q -O /dev/null --timeout=2 \
7075
--header="Content-Type: application/json" \
71-
${API_KEY:+--header="Authorization: Bearer $API_KEY"} \
72-
--post-data="$PAYLOAD" "${API_URL}/api/captures/entry" 2>/dev/null || true
76+
${MCP_TOKEN:+--header="Authorization: Bearer $MCP_TOKEN"} \
77+
--post-data="$PAYLOAD" "$MCP_URL" 2>/dev/null || true
7378
fi
7479

7580
echo "Activity captured"

ops/session-summarize.sh

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,43 @@
11
#!/usr/bin/env bash
2-
# session-summarize.sh - Summarize session activity via SerialMemory HTTP API
3-
# Reads capture status from API and outputs structured summary text
2+
# session-summarize.sh - Query capture status through MCP HTTP transport
3+
# Sends JSON-RPC to MCP at localhost:4545, which forwards to the API
4+
# The MCP client already has the API key — no extra env vars needed
45
# Usage: bash ops/session-summarize.sh <precompact|session_end>
56
set -euo pipefail
67

78
TRIGGER="${1:-session_end}"
89

9-
# SerialMemory API endpoint
10-
API_URL="${SERIALMEMORY_ENDPOINT:-http://localhost:5000}"
11-
API_KEY="${SERIALMEMORY_API_KEY:-}"
10+
# MCP HTTP transport (always localhost, started alongside stdio)
11+
MCP_URL="${MCP_HTTP_URL:-http://localhost:4545}/mcp"
12+
MCP_TOKEN="${MCP_HTTP_TOKEN:-}"
1213

13-
# Build auth header
14-
AUTH_OPTS=""
15-
if [ -n "$API_KEY" ]; then
16-
AUTH_OPTS="-H \"Authorization: Bearer $API_KEY\""
17-
fi
14+
# JSON-RPC payload for capture_status tool
15+
JSONRPC='{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"capture_status","arguments":{}}}'
1816

19-
# Fetch capture status from API
20-
STATUS=""
17+
# Call MCP HTTP transport
18+
RESPONSE=""
2119
if command -v curl &>/dev/null; then
22-
STATUS=$(curl -s -m 5 "${API_URL}/api/captures/status" \
23-
-H "Accept: application/json" \
24-
${API_KEY:+-H "Authorization: Bearer $API_KEY"} 2>/dev/null || echo "")
20+
RESPONSE=$(curl -s -m 5 -X POST "$MCP_URL" \
21+
-H "Content-Type: application/json" \
22+
${MCP_TOKEN:+-H "Authorization: Bearer $MCP_TOKEN"} \
23+
-d "$JSONRPC" 2>/dev/null || echo "")
2524
elif command -v wget &>/dev/null; then
26-
STATUS=$(wget -q -O - --timeout=5 \
27-
--header="Accept: application/json" \
28-
${API_KEY:+--header="Authorization: Bearer $API_KEY"} \
29-
"${API_URL}/api/captures/status" 2>/dev/null || echo "")
25+
RESPONSE=$(wget -q -O - --timeout=5 \
26+
--header="Content-Type: application/json" \
27+
${MCP_TOKEN:+--header="Authorization: Bearer $MCP_TOKEN"} \
28+
--post-data="$JSONRPC" "$MCP_URL" 2>/dev/null || echo "")
3029
fi
3130

32-
# Parse capture status
31+
# Parse the MCP response — result.content[0].text contains the API response
3332
TOTAL_UNDRAINED=0
3433
SESSION_COUNT=0
35-
if [ -n "$STATUS" ] && command -v jq &>/dev/null; then
36-
TOTAL_UNDRAINED=$(echo "$STATUS" | jq -r '.totalUndrained // 0' 2>/dev/null || echo "0")
37-
SESSION_COUNT=$(echo "$STATUS" | jq -r '.sessions | length // 0' 2>/dev/null || echo "0")
34+
if [ -n "$RESPONSE" ] && command -v jq &>/dev/null; then
35+
# Extract the text payload from MCP JSON-RPC response
36+
STATUS=$(echo "$RESPONSE" | jq -r '.result.content[0].text // ""' 2>/dev/null || echo "")
37+
if [ -n "$STATUS" ]; then
38+
TOTAL_UNDRAINED=$(echo "$STATUS" | jq -r '.totalUndrained // 0' 2>/dev/null || echo "0")
39+
SESSION_COUNT=$(echo "$STATUS" | jq -r '.sessions | length // 0' 2>/dev/null || echo "0")
40+
fi
3841
fi
3942

4043
echo ""

0 commit comments

Comments
 (0)