-
Notifications
You must be signed in to change notification settings - Fork 156
feat: add --minimal-descriptions flag for token-efficient multi-connection setups #181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…ction setups Consolidates tools when multiple database connections are configured, reducing MCP tool context overhead. Instead of N tools per connection (execute_sql_prod, execute_sql_staging, etc.), registers one tool with a `database` parameter for routing. Also shortens parameter descriptions while preserving essential context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a --minimal-descriptions flag to optimize token usage when connecting to multiple databases. The feature consolidates per-database tools into single tools with a database parameter and shortens descriptions, achieving significant token savings (up to 67% with 3 databases).
Key changes:
- Adds command-line flag
--minimal-descriptionsto enable token-efficient mode - Consolidates multiple
execute_sql_<db>tools into singleexecute_sqltool with database parameter routing - Shortens parameter descriptions across execute_sql and search_objects tools
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/config/env.ts | Implements isMinimalDescriptionsMode() to check for the new CLI flag |
| src/utils/tool-metadata.ts | Modifies metadata generation to produce consolidated tool names and minimal descriptions in minimal mode; adds database parameter to schemas when multiple sources exist |
| src/tools/index.ts | Implements consolidated tool registration logic with database routing for minimal mode; maintains per-source registration for standard mode |
| src/tools/execute-sql.ts | Shortens SQL parameter description to reduce token count |
| src/tools/search-objects.ts | Compresses parameter descriptions for all search-related fields |
| function registerExecuteSql(server: McpServer, sourceIds: string[]): void { | ||
| const metadata = getExecuteSqlMetadata(sourceIds[0]); | ||
| server.registerTool( | ||
| metadata.name, | ||
| { | ||
| description: metadata.description, | ||
| inputSchema: metadata.schema, | ||
| annotations: metadata.annotations, | ||
| }, | ||
| async (args: ExecuteSqlArgs, extra: unknown) => { | ||
| const sourceId = args.database || sourceIds[0]; | ||
| return createExecuteSqlToolHandler(sourceId)(args, extra); | ||
| } | ||
| ); | ||
| console.error(` - execute_sql (consolidated, databases: ${sourceIds.join(", ")})`); | ||
| } |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The consolidated tool registration creates a logging inconsistency. When a query is executed using the database parameter (e.g., args.database = "production"), the handler created by createExecuteSqlToolHandler will log the tool name as "execute_sql_production" in the request store, but the actual registered tool name is just "execute_sql" (from metadata.name). This makes request tracking and analysis inconsistent.
Consider modifying createExecuteSqlToolHandler to accept an optional parameter indicating the actual registered tool name, or create a wrapper that corrects the tool name before logging.
| // In minimal mode, register consolidated tools once (with database parameter) | ||
| if (isMinimal) { | ||
| // Track which built-in tools have been registered | ||
| let executeSqlRegistered = false; | ||
| let searchObjectsRegistered = false; | ||
|
|
||
| // Check all sources to see which tools are enabled | ||
| for (const sourceId of sourceIds) { | ||
| const enabledTools = registry.getEnabledToolConfigs(sourceId); | ||
| const sourceConfig = ConnectorManager.getSourceConfig(sourceId)!; | ||
| const dbType = sourceConfig.type; | ||
|
|
||
| for (const toolConfig of enabledTools) { | ||
| if (toolConfig.name === BUILTIN_TOOL_EXECUTE_SQL && !executeSqlRegistered) { | ||
| registerExecuteSql(server, sourceIds); | ||
| executeSqlRegistered = true; | ||
| } else if (toolConfig.name === BUILTIN_TOOL_SEARCH_OBJECTS && !searchObjectsRegistered) { | ||
| registerSearchObjects(server, sourceIds); | ||
| searchObjectsRegistered = true; | ||
| } else if (toolConfig.name !== BUILTIN_TOOL_EXECUTE_SQL && toolConfig.name !== BUILTIN_TOOL_SEARCH_OBJECTS) { | ||
| // Custom tools are still registered per-source | ||
| registerCustomTool(server, toolConfig, dbType); | ||
| } | ||
| } | ||
| } | ||
| } else { | ||
| // Standard mode: register tools per source | ||
| for (const sourceId of sourceIds) { | ||
| const enabledTools = registry.getEnabledToolConfigs(sourceId); | ||
| const sourceConfig = ConnectorManager.getSourceConfig(sourceId)!; | ||
| const dbType = sourceConfig.type; | ||
| const isDefault = sourceIds[0] === sourceId; | ||
|
|
||
| for (const toolConfig of enabledTools) { | ||
| // Register based on tool name (built-in vs custom) | ||
| if (toolConfig.name === BUILTIN_TOOL_EXECUTE_SQL) { | ||
| registerExecuteSqlTool(server, sourceId, dbType); | ||
| } else if (toolConfig.name === BUILTIN_TOOL_SEARCH_OBJECTS) { | ||
| registerSearchObjectsTool(server, sourceId, dbType, isDefault); | ||
| } else { | ||
| // Custom tool | ||
| registerCustomTool(server, toolConfig, dbType); | ||
| } | ||
| } | ||
| } | ||
| } |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new minimal-descriptions mode functionality lacks test coverage. Given that the repository has comprehensive testing (as seen in src/tools/tests/ and src/connectors/tests/), this new feature should include tests to verify:
- Tools are correctly consolidated when --minimal-descriptions is enabled
- The database parameter is added to schemas only when there are multiple sources
- Tool routing works correctly with the database parameter
- Request logging captures the correct tool names
- Single-database setups work correctly in minimal mode (no database parameter needed)
Consider adding integration tests similar to the existing test patterns in the codebase.
|
Thanks for bringing this up. We do want to optimize token usage. I have shortened the description based on your PR at #184. Meanwhile, I want to avoid introducing an extra flag. Also I'd like to keep a single way to route the db as LLM already has trouble to route the query to the desired db properly. Will it work if you prepare separate TOML config for each db toolset and load them on-demand? FWIW, Anthropic introduced |
|
Thanks for looking at these changes :) loading on demand is not an option for me. i used https://www.pulsemcp.com/servers/modelcontextprotocol-postgres before with 4 different configs at ~500 tokens per connection. dbhub is already at 1.5k for a single connection with the two tools it exposes. Toggling MCPs is a terrible experience. Even with the outlined changes ( Honestly, i'm not sure why dbhub is registering new tools for each connection at all? Nothing really changes other than some config. The solution here works great for me atleast.
can't say this was an issue for me so far. |
f12465f to
f8c1eba
Compare
Summary
Hi, thanks for creating this repository. I wanted to use it, but realized that the MCP is using an obnoxious amount of tokens when connecting to multiple databases.
So i set out to reduce that number, mainly by reducing the duplicated tools. i also shortened the descriptions slightly. I "hid" the features behind a
--minimal-descriptionsflag, as i've only tested this for myself.Before (3 connections): ~4,500 tokens (6 tools)
After (3 connections): ~1,500 tokens (2 tools)
Changes
--minimal-descriptionsCLI flagexecute_sqland onesearch_objectswithdatabaseparameter for routingToken Savings by Connection Count