Skip to content

Commit 8d707ff

Browse files
author
nigel brown
committed
Add optimizer implementation files
- Add optimizer package (cmd/thv-operator/pkg/optimizer/) - Add vMCP optimizer integration (pkg/vmcp/optimizer/) - Add optimizer adapter and tests - Add optimizer example config - Add optimizer E2E tests
1 parent 42973e0 commit 8d707ff

48 files changed

Lines changed: 12081 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Integrating Optimizer with vMCP
2+
3+
## Overview
4+
5+
The optimizer package ingests MCP server and tool metadata into a searchable database with semantic embeddings. This enables intelligent tool discovery and token optimization for LLM consumption.
6+
7+
## Integration Approach
8+
9+
**Event-Driven Ingestion**: The optimizer integrates directly with vMCP's startup process. When vMCP starts and loads its configured servers, it calls the optimizer to ingest each server's metadata and tools.
10+
11+
**NOT** a separate polling service discovering backends
12+
**IS** called directly by vMCP during server initialization
13+
14+
## How It Is Integrated
15+
16+
The optimizer is already integrated into vMCP and works automatically when enabled via configuration. Here's how the integration works:
17+
18+
### Initialization
19+
20+
When vMCP starts with optimizer enabled in the configuration, it:
21+
22+
1. Initializes the optimizer database (chromem-go + SQLite FTS5)
23+
2. Configures the embedding backend (placeholder, Ollama, or vLLM)
24+
3. Sets up the ingestion service
25+
26+
### Automatic Ingestion
27+
28+
The optimizer integrates with vMCP's `OnRegisterSession` hook, which is called whenever:
29+
30+
- vMCP starts and loads configured MCP servers
31+
- A new MCP server is dynamically added
32+
- A session reconnects or refreshes
33+
34+
When this hook is triggered, the optimizer:
35+
36+
1. Retrieves the server's metadata and tools via MCP protocol
37+
2. Generates embeddings for searchable content
38+
3. Stores the data in both the vector database (chromem-go) and FTS5 database
39+
4. Makes the tools immediately available for semantic search
40+
41+
### Exposed Tools
42+
43+
When the optimizer is enabled, vMCP automatically exposes these tools to LLM clients:
44+
45+
- `optim.find_tool`: Semantic search for tools across all registered servers
46+
- `optim.call_tool`: Dynamic tool invocation after discovery
47+
48+
### Implementation Location
49+
50+
The integration code is located in:
51+
- `cmd/vmcp/optimizer.go`: Optimizer initialization and configuration
52+
- `pkg/vmcp/optimizer/optimizer.go`: Session registration hook implementation
53+
- `cmd/thv-operator/pkg/optimizer/ingestion/service.go`: Core ingestion service
54+
55+
## Configuration
56+
57+
Add optimizer configuration to vMCP's config:
58+
59+
```yaml
60+
# vMCP config
61+
optimizer:
62+
enabled: true
63+
db_path: /data/optimizer.db
64+
embedding:
65+
backend: vllm # or "ollama" for local dev, "placeholder" for testing
66+
url: http://vllm-service:8000
67+
model: sentence-transformers/all-MiniLM-L6-v2
68+
dimension: 384
69+
```
70+
71+
## Error Handling
72+
73+
**Important**: Optimizer failures should NOT break vMCP functionality:
74+
75+
- ✅ Log warnings if optimizer fails
76+
- ✅ Continue server startup even if ingestion fails
77+
- ✅ Run ingestion in goroutines to avoid blocking
78+
- ❌ Don't fail server startup if optimizer is unavailable
79+
80+
## Benefits
81+
82+
1. **Automatic**: Servers are indexed as they're added to vMCP
83+
2. **Up-to-date**: Database reflects current vMCP state
84+
3. **No polling**: Event-driven, efficient
85+
4. **Semantic search**: Enables intelligent tool discovery
86+
5. **Token optimization**: Tracks token usage for LLM efficiency
87+
88+
## Testing
89+
90+
```go
91+
func TestOptimizerIntegration(t *testing.T) {
92+
// Initialize optimizer
93+
optimizerSvc, err := ingestion.NewService(&ingestion.Config{
94+
DBConfig: &db.Config{Path: "/tmp/test-optimizer.db"},
95+
EmbeddingConfig: &embeddings.Config{
96+
BackendType: "ollama",
97+
BaseURL: "http://localhost:11434",
98+
Model: "all-minilm",
99+
Dimension: 384,
100+
Dimension: 384,
101+
},
102+
})
103+
require.NoError(t, err)
104+
defer optimizerSvc.Close()
105+
106+
// Simulate vMCP starting a server
107+
ctx := context.Background()
108+
tools := []mcp.Tool{
109+
{Name: "get_weather", Description: "Get current weather"},
110+
{Name: "get_forecast", Description: "Get weather forecast"},
111+
}
112+
113+
err = optimizerSvc.IngestServer(
114+
ctx,
115+
"weather-001",
116+
"weather-service",
117+
"http://weather.local",
118+
models.TransportSSE,
119+
ptr("Weather information service"),
120+
tools,
121+
)
122+
require.NoError(t, err)
123+
124+
// Verify ingestion
125+
server, err := optimizerSvc.GetServer(ctx, "weather-001")
126+
require.NoError(t, err)
127+
assert.Equal(t, "weather-service", server.Name)
128+
}
129+
```
130+
131+
## See Also
132+
133+
- [Optimizer Package README](./README.md) - Package overview and API
134+

0 commit comments

Comments
 (0)