Skip to content

Commit 4b8b194

Browse files
longevitycoachclaude
andcommitted
fix: Fix empty tool schemas causing Claude.ai 'NO PROVIDED TOOLS' error
- CRITICAL FIX: All 24 tools now have proper inputSchema with properties - Root cause: Was extracting handler methods instead of tool definitions - Solution: Define tools with complete schemas explicitly - Update version to 1.0.2 - Add documentation for SSE implementation - Tested: 22/24 tools have parameters, 2 correctly have no parameters This fixes the fundamental issue preventing Claude.ai from seeing and using the tools. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 86956d1 commit 4b8b194

6 files changed

Lines changed: 617 additions & 1186 deletions

File tree

docs/MCP_SSE_IMPLEMENTATION_FIX.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# MCP SSE Implementation Fix for Claude.ai
2+
3+
## Problem Summary
4+
5+
The StrunzKnowledge MCP server shows "NO PROVIDED TOOLS" in Claude.ai despite the server reporting tools. The issue stems from fundamental implementation errors in how tools are exposed via the SSE transport.
6+
7+
## Root Causes
8+
9+
### 1. Incorrect Tool Registry Pattern
10+
11+
**Current (Wrong):**
12+
```python
13+
# Trying to extract handler methods as tools
14+
for tool_name in dir(server_instance):
15+
if tool_name.startswith('_handle_'):
16+
actual_name = tool_name.replace('_handle_', '')
17+
tool_registry[actual_name] = getattr(server_instance, tool_name)
18+
```
19+
20+
**Issue:** The MCP SDK doesn't expose tools this way. Tools are defined in the `list_tools()` decorator, not as individual handler methods.
21+
22+
### 2. Incorrect Tool Schema Generation
23+
24+
**Current (Wrong):**
25+
```python
26+
tools.append({
27+
"name": name,
28+
"description": (func.__doc__ or "").strip() or f"Tool: {name}",
29+
"inputSchema": {
30+
"type": "object",
31+
"properties": {}, # Empty properties!
32+
"additionalProperties": True
33+
}
34+
})
35+
```
36+
37+
**Issue:** Empty property schemas prevent Claude.ai from understanding how to call the tools.
38+
39+
### 3. Missing Proper SSE Message Flow
40+
41+
The current implementation doesn't properly handle the SSE initialization flow that Claude.ai expects:
42+
- POST to /sse with initialization request
43+
- Proper JSON-RPC message formatting
44+
- Correct event types and data structure
45+
46+
## Solution
47+
48+
### 1. Proper Tool Definition
49+
50+
Tools must be properly defined with complete schemas:
51+
52+
```python
53+
{
54+
"name": "knowledge_search",
55+
"description": "Search through Dr. Strunz's knowledge base",
56+
"inputSchema": {
57+
"type": "object",
58+
"properties": {
59+
"query": {
60+
"type": "string",
61+
"description": "Search query"
62+
},
63+
"limit": {
64+
"type": "integer",
65+
"description": "Number of results",
66+
"default": 10
67+
}
68+
},
69+
"required": ["query"]
70+
}
71+
}
72+
```
73+
74+
### 2. Correct SSE Implementation
75+
76+
```python
77+
@app.post("/sse")
78+
async def sse_endpoint(request: Request):
79+
# Handle POST initialization
80+
init_request = await request.json()
81+
82+
async def event_generator():
83+
if init_request.get("method") == "initialize":
84+
# Send proper initialization response
85+
yield {
86+
"event": "message",
87+
"data": json.dumps({
88+
"jsonrpc": "2.0",
89+
"id": init_request.get("id"),
90+
"result": {
91+
"protocolVersion": "2025-03-26",
92+
"capabilities": {
93+
"tools": {"listChanged": False}
94+
},
95+
"serverInfo": {
96+
"name": "Server Name",
97+
"version": "1.0.0"
98+
}
99+
}
100+
})
101+
}
102+
```
103+
104+
### 3. Proper Tool Extraction from MCP SDK
105+
106+
Instead of trying to extract handler methods, we need to:
107+
108+
1. **Call the SDK's list_tools handler directly**
109+
2. **Convert the SDK's tool format to Claude.ai's expected format**
110+
3. **Ensure all tool schemas are complete**
111+
112+
```python
113+
# Get tools from MCP SDK server
114+
async def get_sdk_tools():
115+
"""Extract tools from the MCP SDK server"""
116+
if hasattr(server_instance.server, 'list_tools'):
117+
# Call the list_tools handler
118+
tools_handler = server_instance.server._tool_list_handler
119+
if tools_handler:
120+
sdk_tools = await tools_handler()
121+
# Convert to Claude.ai format
122+
return [convert_tool_format(tool) for tool in sdk_tools]
123+
return []
124+
```
125+
126+
## Testing Steps
127+
128+
### 1. Local Testing with MCP Inspector
129+
130+
```bash
131+
# Run the test server
132+
python src/mcp/test_sse_server.py
133+
134+
# In another terminal, run the test script
135+
python src/scripts/test_mcp_inspector.py
136+
```
137+
138+
Then:
139+
1. Open https://inspector.mcp.run/
140+
2. Select "SSE" transport
141+
3. Enter URL: http://localhost:8000/sse
142+
4. Click "Connect"
143+
5. Verify tools appear
144+
145+
### 2. Claude.ai Testing
146+
147+
1. Deploy the fixed server to Railway
148+
2. Add to Claude.ai with the public URL
149+
3. Tools should now appear properly
150+
151+
## Key Differences from Working Servers
152+
153+
Working MCP servers (like bloodtest-mcp-server) follow these patterns:
154+
155+
1. **Complete tool schemas** with all properties defined
156+
2. **Proper SSE message flow** handling both GET and POST
157+
3. **Correct JSON-RPC formatting** throughout
158+
4. **Tool execution returns proper content structure**
159+
160+
## Implementation Checklist
161+
162+
- [ ] Fix tool extraction from MCP SDK
163+
- [ ] Implement proper SSE message handling
164+
- [ ] Add complete input schemas for all tools
165+
- [ ] Test with MCP Inspector
166+
- [ ] Deploy and test with Claude.ai
167+
- [ ] Verify all 20 tools appear and work
168+
169+
## References
170+
171+
- [MCP Python SDK SSE Transport](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/sse.py)
172+
- [MCP Protocol Specification](https://modelcontextprotocol.io/docs/concepts/transports)
173+
- [Working MCP Server Examples](https://github.com/modelcontextprotocol/servers)

0 commit comments

Comments
 (0)