-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Description
The change_title MCP tool fails silently for all sessions (daemon-spawned and terminal-launched). The MCP HTTP server created by startHappyServer() returns HTTP 500 on every request, so the handler function never executes and session titles are never updated.
All sessions display the working directory basename (e.g., "juniper") instead of the title set by Claude.
Environment
- Happy CLI: 2.1.50 (Claude Code)
- happy-coder: 0.13.0
- MCP SDK: @modelcontextprotocol/sdk 1.26.0
- Platform: macOS Darwin 25.3.0
- Node: v22.21.1
Root Cause Analysis
1. MCP HTTP Transport returns 500
startHappyServer() creates a StreamableHTTPServerTransport with sessionIdGenerator: void 0 (stateless mode). When Claude Code sends an initialize request to this transport, it responds with HTTP 500 and an empty body:
POST http://127.0.0.1:{port}/ → 500 Internal Server Error (empty body)
The error handler in startHappyServer() catches the exception:
const server = createServer(async (req, res) => {
try {
await transport.handleRequest(req, res); // throws
} catch (error) {
logger.debug("Error handling request:", error); // never logged
if (!res.headersSent) {
res.writeHead(500).end();
}
}
});However, the logger.debug output doesn't appear in session logs, suggesting the error is thrown inside the Hono getRequestListener adapter before reaching the catch block, or the catch fires but the debug message is suppressed.
2. Handler never executes
The [happyMCP] Changing title to: debug log is absent from ALL session logs, even sessions where agentState shows change_title with status: "approved". The "approved" status only means the user approved the tool call permission — the actual MCP call fails with the 500 error.
3. Verified on live ports
Both daemon-spawned session MCP ports (confirmed via lsof) are listening but return 500:
$ lsof -i :60206 → node PID 93496 (LISTEN) ✓
$ curl -X POST http://127.0.0.1:60206/ ... → HTTP 500, 0 bytes
4. Additional issue for terminal-launched sessions
The happy-mcp-auto.sh bridge reads daemon.state.json and connects to the daemon's main HTTP port (63094), not the per-session MCP port. The daemon returns 404 since it doesn't serve MCP requests on that port.
Impact
- All sessions show working directory name as title (e.g., "Juniper")
change_titleis fundamentally broken — never executes- The
updateMetadata({summary: {text, updatedAt}})call at line 1502-1509 insendClaudeSessionMessagenever fires - iOS app falls back to
lastPathSegmentfor every session
Reproduction Steps
- Start a Happy session (daemon or terminal)
- Claude calls
mcp__happy__change_titlewith any title - Agent state shows
status: "approved"but title doesn't change - Session log has no
[happyMCP] Changing title to:entries - Direct HTTP test:
curl -X POST http://127.0.0.1:{mcp_port}/ -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"initialize",...}' → 500
Expected Behavior
change_title should update the session title visible in the iOS app.
Suggested Fix
The StreamableHTTPServerTransport with sessionIdGenerator: void 0 + MCP SDK 1.26.0 has a transport issue. Options:
- Downgrade to SSE transport or use stdio-based approach instead of HTTP
- Debug the Hono
getRequestListeneradapter failure with stateless mode - Pass
parsedBodyas the third argument totransport.handleRequest(req, res, parsedBody)— currently missing
Related Issues
- [Bug] mcp__happy__change_title tool unavailable when daemon is unstable #593 —
change_titleunavailable when daemon is unstable - feat: add session rename with swipe-left action (#290) #737 — swipe-to-rename as workaround
- feat(cli): improve session title prompt with structured triggers #762 — improved title prompt (won't help until transport is fixed)