-
Notifications
You must be signed in to change notification settings - Fork 186
Closed
Labels
apiItems related to the APIItems related to the APIenhancementNew feature or requestNew feature or requestgoPull requests that update go codePull requests that update go code
Description
Context
The current dummyOptimizer (pkg/vmcp/optimizer/dummy_optimizer.go) uses an in-memory map with simple case-insensitive substring matching. This doesn't scale to production workloads and duplicates tool state across every optimizer instance (one per MCP session).
Prototype reference: #3516 (see pkg/vmcp/optimizer/internal/db/ for prior art on SQLite + FTS5)
Requirements
- Introduce a storage interface that abstracts how tools are stored and searched. The
dummyOptimizershould depend on this interface rather than directly on SQLite. This enables:- Unit testing the optimizer with a mock/in-memory store
- Integration testing the SQLite implementation independently
- Implement the storage interface with a shared SQLite backend backed by FTS5 full-text search. The SQLite instance must be shared across all optimizer instances created by the
OptimizerFactory(pkg/vmcp/server/server.go:134), deduplicating tool storage. - Despite the shared database, each optimizer instance must only return tools for the capabilities passed at factory creation time (i.e., the
[]server.ServerToolslice passed toNewDummyOptimizer). This preserves per-session scoping. - Implement a basic BM25/FTS5-based similarity search in
FindTool, replacing the current substring matching. - The
Optimizerinterface (pkg/vmcp/optimizer/optimizer.go) should gain aClose()method so the database can be cleaned up. Update the server integration inpkg/vmcp/server/server.goto callClose()on session teardown. - The factory function signature in
server.Config.OptimizerFactorymay need to change to accept a shared storage reference. Consider a two-phase pattern: a top-level "optimizer manager" (holds the storage instance) and per-session optimizer instances.
High-Level Implementation
- Define a storage interface (e.g.,
ToolStore) inpkg/vmcp/optimizer/with methods for tool ingestion, search, and cleanup - Create an internal SQLite implementation under
pkg/vmcp/optimizer/internal/db/that satisfies the interface:- A single shared
*sql.DBconnection with FTS5 virtual table for tool search - Tool ingestion (upsert tools with name, description, input schema)
- FTS5-based search that returns ranked results
- A single shared
- Update
dummyOptimizerto accept aToolStoreand a scoping set of tool names FindToolqueries the store, filters to the scoped tool set, and returns matchesCallToolremains unchanged (direct tool handler invocation)- Update
cmd/vmcp/app/commands.goto create the shared SQLite-backed store and pass it into the factory closure
Acceptance Tests
- Storage interface unit tests: Optimizer logic tested against a mock
ToolStore— verifies search delegation, scoping, and error handling without any database - SQLite integration tests: The SQLite
ToolStoreimplementation tested independently — verifies FTS5 indexing, upsert behavior, and search ranking - Shared state: Two optimizer instances created from the same factory share the same
ToolStoreand can see each other's tools - Per-session scoping: An optimizer instance only returns tools from its own
[]server.ServerToolslice, even when the store contains tools from other sessions - FTS5 search quality:
FindToolwith a natural-language description returns relevant tools (not just substring matches) - Close cleanup: Calling
Close()on an optimizer properly releases resources - Concurrent access: Multiple goroutines can call
FindToolandCallToolon different optimizer instances simultaneously without data races - Existing adapter compatibility: The
find_toolandcall_toolMCP tools exposed viapkg/vmcp/server/adapter/optimizer_adapter.gocontinue to work unchanged
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
apiItems related to the APIItems related to the APIenhancementNew feature or requestNew feature or requestgoPull requests that update go codePull requests that update go code