Skip to main content
Glama
dsouza-anush

Heroku MCP Tool Search Server

by dsouza-anush
README.md
# MCP Tool Search Server

**The Problem:** When you give Claude 50+ tools, two things break:
1. **Context bloat** - Tool definitions eat 10-20K tokens, leaving less room for actual work
2. **Selection accuracy** - Claude gets confused and picks wrong tools when there are too many

**The Solution:** Instead of loading all tools upfront, Claude *searches* for tools and loads only what it needs.

```
Without Tool Search:              With Tool Search:
┌─────────────────────┐           ┌─────────────────────┐
│ Load 100 tools      │           │ Load 1 search tool  │
│ (20K tokens)        │           │ (200 tokens)        │
│                     │           │                     │
│ Claude picks wrong  │           │ Claude searches:    │
│ tool 30% of time    │           │ "weather" → 2 tools │
│                     │           │                     │
│ Context nearly full │           │ 95% context free    │
└─────────────────────┘           └─────────────────────┘
```

## How It Works

1. You register your tools with this server (via REST API)
2. Claude gets access to search tools (`tool_search_bm25`, `tool_search_semantic`, `tool_search_regex`)
3. When Claude needs a tool, it searches → gets back tool names → uses them

**Three search methods:**
- **BM25** - Keyword matching ("weather" finds `get_weather`, `get_forecast`)
- **Semantic** - Meaning-based ("send a message" finds `send_email`)
- **Regex** - Pattern matching (`get_.*` finds all getter tools)

## Deploy to Heroku

[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://www.heroku.com/deploy?template=https://github.com/dsouza-anush/mcp-tool-search)

Or manually:
```bash
heroku create my-tool-search
heroku buildpacks:set heroku/python
git push heroku main
heroku ai:models:create claude-4-sonnet --as INFERENCE
```

## Register Your Tools

```bash
curl -X POST https://your-app.herokuapp.com/tools \
  -H "Content-Type: application/json" \
  -d '{
    "name": "get_weather",
    "description": "Get current weather for a location",
    "input_schema": {
      "type": "object",
      "properties": {"location": {"type": "string"}},
      "required": ["location"]
    }
  }'
```

## Test It

```bash
export INFERENCE_KEY=$(heroku config:get INFERENCE_KEY -a my-tool-search)
export INFERENCE_URL=$(heroku config:get INFERENCE_URL -a my-tool-search)

curl -s "$INFERENCE_URL/v1/agents/heroku" \
  -H "Authorization: Bearer $INFERENCE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-4-sonnet",
    "messages": [{"role": "user", "content": "Find tools for checking weather"}],
    "tools": [{"type": "mcp", "name": "mcp-tool-search/tool_search_semantic"}]
  }'
```

## API Reference

| Endpoint | Description |
|----------|-------------|
| `POST /tools` | Register a tool |
| `GET /tools` | List all tools |
| `DELETE /tools/{name}` | Remove a tool |
| `GET /health` | Health check |

## MCP Tools

| Tool | Use Case |
|------|----------|
| `tool_search_bm25` | Find tools by keywords |
| `tool_search_semantic` | Find tools by meaning |
| `tool_search_regex` | Find tools by pattern |
| `list_all_tools` | List all registered tools |