-
Notifications
You must be signed in to change notification settings - Fork 258
Description
Summary
Happy CLI 0.13.0 is incompatible with @modelcontextprotocol/sdk version 1.26.0. When Claude Code attempts to connect to the Happy MCP server, it receives HTTP 500 errors on the OAuth discovery endpoint, causing authentication to fail.
Environment
- Happy CLI: 0.13.0
- Claude Code: 2.1.34
- Node.js: v22.22.0
- Platform: Linux (Ubuntu)
- Working MCP SDK version: 1.25.3
- Broken MCP SDK version: 1.26.0
How Claude Code Connects to MCP Servers
When Claude Code connects to an HTTP-based MCP server, it makes multiple sequential HTTP requests:
-
OAuth Discovery -
GET /.well-known/oauth-authorization-server- Claude Code first checks if the server requires OAuth authentication (per MCP Authorization spec)
- Expects either valid OAuth metadata or HTTP 404 (not supported)
-
MCP Initialize -
POSTwith JSON-RPCinitializemethod- After OAuth check, sends the actual MCP handshake
-
Tool Discovery -
POSTwith JSON-RPCtools/listmethod- Discovers available tools like
change_title
- Discovers available tools like
-
Ongoing tool calls -
POSTwith JSON-RPC- Each tool invocation is another HTTP request
Root Cause
MCP SDK 1.26.0 introduced breaking changes (release notes):
"Stateless transport.handleRequest() throws if called more than once"
In startHappyServer.ts, a single StreamableHTTPServerTransport instance is created and reused for all incoming HTTP requests:
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined
});
await mcp.connect(transport);
const server = createServer(async (req, res) => {
try {
await transport.handleRequest(req, res); // Throws on 2nd+ call in SDK 1.26.0
} catch (error) {
res.writeHead(500).end(); // Returns 500 for any error
}
});With SDK 1.26.0, either:
- The transport throws on the OAuth discovery request (unrecognized route that it can't handle)
- Or it throws on any subsequent request (transport already used)
Either way, the catch block returns HTTP 500, which Claude Code interprets as a server error and fails authentication.
Steps to Reproduce
- Install happy-coder 0.13.0 (npm will resolve MCP SDK to 1.26.0)
- Start a Happy session:
happy - Run
/mcpin Claude Code - Attempt to authenticate with Happy MCP server
Expected Behavior
- OAuth discovery endpoint should return HTTP 404 (not supported)
- MCP connection should succeed
mcp__happy__change_titletool should be available
Actual Behavior
- OAuth discovery endpoint returns HTTP 500
- Claude Code shows:
Error: HTTP 500 trying to load OAuth metadata from http://127.0.0.1:XXXXX/.well-known/oauth-authorization-server - MCP authentication fails
- Cannot use Happy MCP tools
Diagnostic Evidence
Session MCP server (broken - SDK 1.26.0):
$ curl -v http://127.0.0.1:43527/.well-known/oauth-authorization-server
< HTTP/1.1 500 Internal Server Error
< content-type: text/plain; charset=UTF-8Daemon server (works - uses Fastify with proper route handling):
$ curl -v http://127.0.0.1:42695/.well-known/oauth-authorization-server
< HTTP/1.1 404 Not Found
< content-type: application/json; charset=utf-8
{"message":"Route GET:/.well-known/oauth-authorization-server not found","error":"Not Found","statusCode":404}Version comparison:
| MCP SDK Version | Works? |
|---|---|
| 1.25.3 | ✅ Yes |
| 1.26.0 | ❌ No |
Workaround
Downgrade MCP SDK to 1.25.3:
cd $(npm root -g)/happy-coder
sudo npm install @modelcontextprotocol/sdk@1.25.3 --save-exact
happy daemon stop && happy daemon start
# Start a new happy session to testHowever, this drops the changes in @modelcontextprotocol/sdk@1.26.0 that were made to address GHSA-345p-7cg4-v4c7
Suggested Fix
-
Short-term: Pin
@modelcontextprotocol/sdkto~1.25.3in package.json until a proper fix is implemented -
Long-term: Update
startHappyServer.tsto follow the SDK 1.26.0 patterns:- Create a new transport instance per request, OR
- Use the session-based transport pattern from the updated SDK examples
- Handle non-MCP routes (like OAuth discovery) explicitly and return 404