diff --git a/.github/instructions/mcp-server-development.instructions.md b/.github/instructions/mcp-server-development.instructions.md index 112cf29..dcd8565 100644 --- a/.github/instructions/mcp-server-development.instructions.md +++ b/.github/instructions/mcp-server-development.instructions.md @@ -131,9 +131,86 @@ mcp-server/src/ ├── readme-knowledge-base.ts # README parsing and search ├── connection-context.ts # Project connection management ├── resources.ts # MCP resource handlers -└── prompts.ts # MCP prompt handlers +├── prompts.ts # MCP prompt handlers +└── tools/ + ├── tier-config.ts # Tier-1 command list, router name, caps + ├── cli-tools.ts # Tool definitions (tier-1, per-category, all) + ├── router-tool.ts # hana_execute router implementation + ├── discovery-tools.ts # Category/tag/recommend tools + └── content-tools.ts # Examples, presets, docs tools ``` +## Tiered Tool Architecture + +The MCP server uses progressive discovery to keep the initial tool surface small (~22 tools) while providing access to all 186 commands. + +### Configuration: `tools/tier-config.ts` + +```typescript +// Tier-1 commands are always exposed as first-class tools +export const TIER_1_COMMANDS: string[] = [ + 'querySimple', 'tables', 'inspectTable', 'views', 'status', +]; + +export const ROUTER_TOOL_NAME = 'hana_execute'; +export const MAX_DYNAMIC_TOOLS = 50; +``` + +### Tool Layers + +| Layer | Source | Registration | +| ----- | ------ | ------------ | +| Tier-1 | `tools/cli-tools.ts → getCliToolDefinitions()` | Always registered | +| Router | `tools/router-tool.ts` | Always registered; dispatches 183+ commands | +| Discovery/Content | `tools/discovery-tools.ts`, `tools/content-tools.ts` | Always registered | +| Dynamic | `tools/cli-tools.ts → getCliToolDefinitionsForCategory()` | Promoted on demand via `activateCategory()` | + +### Router Tool: `tools/router-tool.ts` + +The `hana_execute` router accepts `{ command, args }` and resolves commands via: +1. Direct name match (e.g., `"dataProfile"`) +2. Sanitized name match (camelCase to snake_case) +3. Alias lookup + +```typescript +export async function handleRouterTool(params: { command: string; args?: Record }): Promise { + const resolved = resolveCommand(params.command); + return executeCommand(resolved, params.args || {}); +} +``` + +### Dynamic Tool Promotion + +When `hana_discover_by_category` is called, the server promotes those tools to first-class MCP tools: + +```typescript +private activateCategory(category: string): void { + const tools = getCliToolDefinitionsForCategory(category); + // Filter out any tier-1 tools to avoid duplicates + const newTools = tools.filter(t => !isTier1Command(t.originalName)); + + this.dynamicTools.set(category, newTools); + this.enforceCap(); // FIFO eviction if over MAX_DYNAMIC_TOOLS + this.server.sendToolListChanged(); // Notify client to refresh +} +``` + +**Important implementation details:** +- Tier-1 tools are filtered out before adding category tools (deduplication) +- A FIFO cap of `MAX_DYNAMIC_TOOLS` (50) evicts the oldest category first +- `sendToolListChanged()` triggers an MCP `notifications/tools/list_changed` notification + +### Full Mode (`--full` flag) + +Pass `--full` to bypass tiering and register all 186 tools at startup: + +```typescript +const fullMode = process.argv.includes('--full'); +const cliTools = fullMode ? getAllCliToolDefinitions() : getCliToolDefinitions(); +``` + +Use `--full` in environments where tool count is not a concern (e.g., dedicated HANA AI agents). + ## Tool Registration Pattern ### Sanitize Tool Names diff --git a/README.md b/README.md index 0674c3c..ae41af3 100644 --- a/README.md +++ b/README.md @@ -455,29 +455,29 @@ hana-cli serve # Start the web server standalone The web UI runs on `http://localhost:3010` by default and provides access to all CLI functionality through an easy-to-use graphical interface. For complete documentation of all web applications, UI5 components, configuration, and development guides, see the [app/README.md](app/README.md) file. -### Experimental MCP (Model Context Protocol) Integration +### MCP (Model Context Protocol) Integration -The hana-cli tool now includes experimental support for the Model Context Protocol (MCP), enabling AI assistants like Claude to interact with SAP HANA databases through natural language. This integration exposes all 100+ hana-cli commands as tools that AI assistants can invoke directly. +The hana-cli tool includes a Model Context Protocol (MCP) server, enabling AI assistants like Claude to interact with SAP HANA databases through natural language. The server uses a progressive discovery model — starting with ~22 focused tools and expanding on demand to all 186 commands. ```mermaid graph LR AI["🤖 AI Assistant
Claude, etc."] - - AI -->|Natural Language
Query| MCP["MCP Server
hana-cli Integration"] - - MCP -->|Tool Invocation| Tools["100+ hana-cli
Commands as Tools"] - + + AI -->|Natural Language
Query| MCP["MCP Server
~22 Default Tools"] + + MCP -->|Router or
Direct Call| Tools["186 hana-cli
Commands"] + Tools --> DB["SAP HANA
Database"] Tools --> Cloud["BTP/Cloud
Services"] Tools --> HDI["HDI
Containers"] - + DB -->|Data & Results| Tools Cloud -->|Service Info| Tools HDI -->|Container Status| Tools - + Tools -->|Formatted
Response| MCP MCP -->|Natural Language
Result| AI - + style AI fill:#9D55F0,color:#fff style MCP fill:#0070C0,color:#fff style Tools fill:#FF6B6B,color:#fff @@ -486,17 +486,16 @@ graph LR **Key Features:** -- Natural language database queries and operations -- Full access to all hana-cli commands through AI assistants -- Seamless integration with AI development environments (Cline/Claude Dev, etc.) -- Command execution with proper parameter handling and error responses +- Progressive tool discovery — tier-1 tools always available, others via router or dynamic promotion +- Router tool (`hana_execute`) dispatches any of 183+ commands by name +- AI-guided command recommendations and smart search +- Seamless integration with Claude Desktop, VS Code, Cursor, and other MCP clients +- `--full` mode available for environments where tool count is not a concern For detailed setup instructions, configuration options, and usage examples, please refer to: -- [mcp-server/README.md](mcp-server/README.md) - Complete installation and configuration guide -- [mcp-server/TROUBLESHOOTING.md](mcp-server/TROUBLESHOOTING.md) - Common issues and solutions - -**Note:** This is an experimental feature and may be subject to changes as the MCP specification evolves. +- [docs/03-features/mcp-integration.md](docs/03-features/mcp-integration.md) - Complete MCP overview and setup guide +- [mcp-server/README.md](mcp-server/README.md) - Server installation and configuration ## Standard Parameters and Conventions diff --git a/docs/03-features/mcp-integration.md b/docs/03-features/mcp-integration.md index 02bbab4..366d4e3 100644 --- a/docs/03-features/mcp-integration.md +++ b/docs/03-features/mcp-integration.md @@ -8,7 +8,8 @@ The Model Context Protocol enables AI assistants to interact with external tools **Key Capabilities:** -- **150+ Tools** - All CLI commands accessible via MCP interface +- **Progressive Tool Discovery** - Starts with ~22 focused tools; promotes additional tools on demand (up to 186 total) +- **Router Tool** - `hana_execute` dispatches any of 183+ commands by name without pre-registration - **Discovery** - AI-guided command recommendations and smart search - **Workflows** - Pre-built multi-step task templates - **Examples** - Real-world usage scenarios and parameter presets @@ -110,20 +111,86 @@ You can also point directly to a local build: Replace the path with your actual project location. Connection credentials are read from `default-env.json` in the project root. Use `hana-cli connect` or `hana-cli serviceKey` to configure database connections. ::: +## Tool Architecture + +### Tiered Tool Exposure + +The MCP server uses a progressive discovery model to keep the initial tool surface small and focused: + +| Layer | Tools | Description | +| ----- | ----- | ----------- | +| **Tier 1** (always-on) | `hana_query_simple`, `hana_tables`, `hana_inspect_table`, `hana_views`, `hana_status` | Core database tools available immediately | +| **Router** | `hana_execute` | Dispatches any of 183+ commands by name | +| **Discovery** | `hana_discover_categories`, `hana_discover_by_category`, `hana_discover_by_tag`, `hana_recommend`, etc. | Help AI agents find the right tools | +| **Content** | `hana_examples`, `hana_parameter_presets`, `hana_get_doc`, etc. | Usage examples and documentation | +| **Dynamic** | Up to 50 additional tools | Promoted when a category is explored via `hana_discover_by_category` | + +**Default:** ~22 tools registered at startup. +**Full mode:** All 186 tools registered (use `--full` flag). + +### The Router Tool (`hana_execute`) + +For commands not in the tier-1 set, the router tool provides direct access without requiring dynamic promotion: + +```json +{ + "tool": "hana_execute", + "arguments": { + "command": "dataProfile", + "args": { "schema": "MY_SCHEMA", "table": "ORDERS" } + } +} +``` + +The router resolves commands by exact name, camelCase-to-snake_case conversion, or alias matching. + +### Dynamic Tool Promotion + +When an AI agent calls `hana_discover_by_category` (e.g., to browse "data-tools"), the server: + +1. Promotes all tools in that category to first-class MCP tools +2. Sends a `tools/list_changed` notification so the client refreshes its tool list +3. Enforces a cap of 50 dynamically-promoted tools (oldest category evicted first) + +This means frequently-used categories become directly callable without the router. + +### Full Mode + +For environments where tool count is not a concern, pass `--full` to expose all 186 tools at startup: + +```json +{ + "mcpServers": { + "hana-cli": { + "type": "stdio", + "command": "npx", + "args": ["-y", "-p", "hana-cli", "hana-cli-mcp", "--full"] + } + } +} +``` + ## Core Features ### 1. Command Tools -All CLI commands are exposed with the `hana_` prefix: +Tier-1 commands are always available with the `hana_` prefix: ```text hana_status Check database connection hana_tables List tables in a schema -hana_import Import data from CSV/Excel -hana_dataProfile Analyze data quality -hana_duplicateDetection Find duplicate rows -hana_compareSchema Compare database schemas -hana_inspectTable View table structure and metadata +hana_inspect_table View table structure and metadata +hana_views List views in a schema +hana_query_simple Execute SQL queries +``` + +All other commands (183+) are accessible via `hana_execute`: + +```text +hana_execute { command: "import", args: { ... } } +hana_execute { command: "dataProfile", args: { ... } } +hana_execute { command: "duplicateDetection", args: { ... } } +hana_execute { command: "compareSchema", args: { ... } } ``` Command aliases still work when called (e.g., `hana_s` for status, `hana_imp` for import), but they are not registered as separate tools to keep the tool list concise. diff --git a/docs/03-features/mcp/advanced-features.md b/docs/03-features/mcp/advanced-features.md index 03bd918..069fc99 100644 --- a/docs/03-features/mcp/advanced-features.md +++ b/docs/03-features/mcp/advanced-features.md @@ -2,6 +2,42 @@ Advanced capabilities and workflows for the MCP server. +## Progressive Tool Discovery + +The MCP server uses a tiered architecture to keep the initial tool surface small while providing access to all 183+ commands: + +### Using the Router Tool + +For any command not in the tier-1 set, use `hana_execute`: + +```json +{ + "tool": "hana_execute", + "arguments": { + "command": "dataProfile", + "args": { + "schema": "MY_SCHEMA", + "table": "ORDERS" + } + } +} +``` + +### Dynamic Tool Promotion + +Calling `hana_discover_by_category` promotes all tools in that category: + +```json +{ + "tool": "hana_discover_by_category", + "arguments": { "category": "data-tools" } +} +``` + +After this call, tools like `hana_import`, `hana_export`, `hana_data_profile` become directly callable. The server sends a `tools/list_changed` notification and the AI client refreshes its tool list. + +A cap of 50 dynamically-promoted tools is enforced (oldest category evicted first via FIFO). + ## Advanced Topics ### Presets & Configurations diff --git a/docs/03-features/mcp/index.md b/docs/03-features/mcp/index.md index 9e3a227..9655078 100644 --- a/docs/03-features/mcp/index.md +++ b/docs/03-features/mcp/index.md @@ -15,9 +15,11 @@ Complete documentation for the Model Context Protocol (MCP) server that enables ## Key Capabilities -**Context-Aware Commands**: Pass project directory and connection file to MCP server +**Progressive Tool Discovery**: Starts with ~22 focused tools; expands on demand via router or dynamic promotion + +**Router Tool (`hana_execute`)**: Execute any of 183+ commands by name without pre-registration -**150+ Tools Exposed**: All HANA CLI commands available to AI assistants +**Context-Aware Commands**: Pass project directory and connection file to MCP server **Structured Output**: Markdown tables and formatted responses diff --git a/docs/03-features/mcp/server-usage.md b/docs/03-features/mcp/server-usage.md index 37c71af..d2984ba 100644 --- a/docs/03-features/mcp/server-usage.md +++ b/docs/03-features/mcp/server-usage.md @@ -40,9 +40,12 @@ npm run build ### Running the Server ```bash -# Start MCP server (listens on stdio) +# Start MCP server (listens on stdio) — default: ~22 tools node build/index.js +# Full mode: all 186 tools exposed at startup +node build/index.js --full + # With debug logging DEBUG=hana-cli:* node build/index.js @@ -65,15 +68,21 @@ The MCP server: ## Available Tools -The MCP server exposes 150+ HANA CLI tools: +By default, the MCP server exposes ~22 tools at startup using a progressive discovery model: + +**Tier-1 (always available):** `hana_query_simple`, `hana_tables`, `hana_inspect_table`, `hana_views`, `hana_status` + +**Router:** `hana_execute` — dispatches any of 183+ commands by name (e.g., `{ "command": "import", "args": { ... } }`) + +**Discovery:** `hana_discover_categories`, `hana_discover_by_category`, `hana_discover_by_tag`, `hana_recommend`, `hana_search`, `hana_quickstart` -**Data Tools:** import, export, compareData, dataProfile, dataDiff, dataValidator, dataMask, dataSync, duplicateDetection, dataLineage +**Content:** `hana_examples`, `hana_parameter_presets`, `hana_get_doc`, `hana_interpret_result`, `hana_conversation_templates`, `hana_get_template` -**Schema Tools:** compareSchema, schemaClone, tableCopy, erdDiagram, generateDocs, generateTestData +**Workflows:** `hana_workflows`, `hana_workflow_by_id`, `hana_search_workflows` -**Query Tools:** querySimple, callProcedure, tables, views, functions, procedures, roles, etc +When an AI agent explores a category via `hana_discover_by_category`, those tools are dynamically promoted to first-class tools (up to 50 additional tools, oldest category evicted first). -**System Tools:** backup, replicationStatus, partitions, spatialData, and more +Use `--full` mode to expose all 186 tools at startup for environments where tool count is not a concern. ## Usage with AI Assistants diff --git a/docs/troubleshooting/mcp.md b/docs/troubleshooting/mcp.md index b97f3a8..dcbca29 100644 --- a/docs/troubleshooting/mcp.md +++ b/docs/troubleshooting/mcp.md @@ -58,6 +58,36 @@ Resolve common issues when using the Model Context Protocol (MCP) server integra ## Command Failures +### Tool Not Found + +**Problem:** AI assistant reports a tool like `hana_dataProfile` is not available + +**Cause:** The MCP server uses progressive discovery — only ~22 tools are registered at startup. Other tools must be accessed via the router or promoted dynamically. + +**Solutions:** + +1. Use the router tool directly: + + ```json + { "tool": "hana_execute", "arguments": { "command": "dataProfile", "args": { "schema": "MY_SCHEMA", "table": "ORDERS" } } } + ``` + +2. Promote the category first by calling `hana_discover_by_category`: + + ```json + { "tool": "hana_discover_by_category", "arguments": { "category": "data-tools" } } + ``` + + After this call, tools like `hana_data_profile` become directly callable. + +3. Use `--full` mode to expose all 186 tools at startup: + + ```json + { "command": "npx", "args": ["-y", "-p", "hana-cli", "hana-cli-mcp", "--full"] } + ``` + +4. Use `hana_recommend` with a natural language description to find the right tool name. + ### Command Execution Errors **Problem:** Tool call returns error from HANA CLI @@ -116,7 +146,7 @@ Resolve common issues when using the Model Context Protocol (MCP) server integra 2. Verify MCP server is running: `npm run dev` 3. Check your IDE's MCP configuration file (e.g., `claude_desktop_config.json`) 4. Ensure the correct path to the MCP executable is configured -5. Verify the MCP server is accessible on the expected port +5. Note: by default only ~22 tools are registered. Use `hana_execute` router for other commands, or start with `--full` to expose all 186 tools ### AI Returns Incorrect Results diff --git a/mcp-server/PLAN-tool-reduction.md b/mcp-server/PLAN-tool-reduction.md deleted file mode 100644 index 946fcc6..0000000 --- a/mcp-server/PLAN-tool-reduction.md +++ /dev/null @@ -1,112 +0,0 @@ -# MCP Server Tool Reduction Plan - -## Problem Statement - -The hana-cli MCP server exposes **203 tools** on `tools/list`. When an MCP client (e.g., Claude Code, Cursor, Copilot) connects, all 203 tool definitions are injected into the AI's context window, consuming ~6,000-10,000 tokens before any user interaction begins. Most MCP servers expose 5-20 tools. This is unsustainable and crowds out space for actual work. - -## Agreed Approach: Router + Tier-1 + Dynamic Registration - -Combine three strategies: - -1. **Router pattern** — a single `hana_execute` tool that can dispatch any command by name -2. **Tier-1 always-exposed** — a small set of high-value commands with full schemas -3. **Dynamic registration** — when the AI explores a category via discovery tools, register those tools and emit `listChanged` (progressive enhancement for capable clients) - -## Architecture - -### Initial `tools/list` Response (~12-15 tools) - -#### Discovery Tools (keep as-is) -- `hana_discover_categories` — browse command categories -- `hana_discover_by_category` — list commands in a category (**+ triggers dynamic registration**) -- `hana_discover_by_tag` — search by tag -- `hana_recommend` — natural-language intent → command suggestion -- `hana_search` — full-text search across docs/commands/workflows -- `hana_get_doc` — retrieve full documentation page -- `hana_examples` — usage examples for a command -- `hana_parameter_presets` — parameter templates for a command - -#### Router Tool (new) -- `hana_execute` — generic router that accepts `{command, args, __projectContext}` and dispatches to any CLI command internally - -#### Tier-1 Commands (always exposed with full schema) -- `hana_query_simple` — direct SQL execution (most common need) -- `hana_tables` — list tables in schema -- `hana_inspect_table` — table structure/metadata -- `hana_views` — list views -- `hana_status` — connection check / current user - -### Dynamic Registration (Option 2 enhancement) - -**Trigger:** When `hana_discover_by_category` is called, the server: -1. Returns the category listing (command names, descriptions, use cases) as it does today -2. Registers all tools in that category with full input schemas -3. Emits `notifications/tools/list_changed` - -**Client behavior:** -- Clients supporting `listChanged`: re-fetch `tools/list`, see newly registered tools with full schemas -- Clients not supporting `listChanged`: ignore the notification, continue using `hana_execute` router - -**Accumulation cap:** Dynamically registered tools accumulate up to ~50 tools. If the cap is hit, the oldest activated category is deregistered. (In practice, sessions focus on 1-2 categories so this is unlikely to trigger.) - -## Implementation Scope - -All changes in `mcp-server/src/`: - -### 1. New file: `tools/router-tool.ts` -- Define `hana_execute` tool with schema: `{command: string, args: object, __projectContext?}` -- Handler: validate command exists in commandsMap, delegate to existing `executeCommand()` -- Return formatted result same as current CLI tool handler - -### 2. New file: `tools/tier-config.ts` -- Export `TIER_1_COMMANDS: string[]` — the always-exposed command names -- Export `isDiscoveryTool(name)`, `isRouterTool(name)` helpers - -### 3. Modify: `tools/cli-tools.ts` -- `getCliToolDefinitions()` → only return tools for TIER_1_COMMANDS -- New export: `getDynamicCliToolDefinitions(category: string)` → returns tool definitions for a specific category -- `handleCliTool()` — unchanged (still resolves any command name) - -### 4. Modify: `tools/discovery-tools.ts` -- `handleDiscoveryTool("discover_by_category", ...)` — after returning results, call a callback/event to trigger dynamic registration - -### 5. Modify: `index.ts` -- `ListToolsRequestSchema` handler: return discovery + router + tier-1 + any dynamically registered tools -- Track `activatedCategories: Set` as server state -- When a category is activated: merge those tool definitions into the active set, emit `notifications/tools/list_changed` -- Declare `listChanged: true` in capabilities - -### 6. Existing infrastructure to leverage -- `commandMetadata.js` already categorizes all 187 commands into 15 groups -- `command-metadata.ts` already has `getCommandsInCategory()` helper -- `extractCommandInfo()` already generates full schemas from yargs builders -- Discovery tools already return category/command listings - -## Migration / Backwards Compatibility - -- **Default behavior changes** — clients will see ~12 tools instead of 203 -- Consider a `--full` CLI flag on the MCP server binary for users who want legacy behavior: `hana-cli-mcp --full` exposes all 203 tools as before -- Document the change in release notes - -## Token Budget Estimate - -| Mode | Tools exposed | Estimated tokens | -|------|--------------|-----------------| -| Current (all) | 203 | ~8,000-10,000 | -| New default (initial) | ~12-15 | ~500-700 | -| After 1 category activation | ~25-30 | ~1,200-1,500 | -| After 3 category activations | ~55-60 | ~2,500-3,000 | - -## Open Questions - -1. **Tier-1 list** — are `querySimple`, `tables`, `inspectTable`, `views`, `status` the right set? Should `schemas` or `healthCheck` be included? -2. **`hana_execute` schema richness** — should the router tool's description include a condensed list of all available command names (costs tokens but helps the AI without discovery round-trips)? -3. **Deactivation** — should there be a way to deactivate a category (shrink the tool list back)? Probably not needed in practice. -4. **`hana_recommend` integration** — when `hana_recommend` suggests a command, should it also trigger registration of that command's category? - -## Decision Log - -- 2026-05-14: Agreed on Router + Tier-1 + Dynamic Registration approach -- 2026-05-14: Dynamic registration triggered implicitly by `discover_by_category` (option A, no separate activate call) -- 2026-05-14: User configuration (profiles) deferred — most users won't know what to configure -- 2026-05-14: `--full` flag for backwards compat retained as escape hatch diff --git a/mcp-server/build/index.js b/mcp-server/build/index.js index c1bd878..b17ed3b 100644 --- a/mcp-server/build/index.js +++ b/mcp-server/build/index.js @@ -18,14 +18,19 @@ import { listPrompts, getPrompt } from './prompts.js'; import { getDiscoveryToolDefinitions, handleDiscoveryTool } from './tools/discovery-tools.js'; import { getContentToolDefinitions, handleContentTool } from './tools/content-tools.js'; import { getSearchToolDefinitions, handleSearchTool } from './tools/search-tools.js'; -import { initCliTools, getCliToolDefinitions, handleCliTool } from './tools/cli-tools.js'; +import { initCliTools, getCliToolDefinitions, getAllCliToolDefinitions, getCliToolDefinitionsForCategory, handleCliTool } from './tools/cli-tools.js'; +import { initRouterTool, getRouterToolDefinition, handleRouterTool } from './tools/router-tool.js'; +import { isRouterTool, MAX_DYNAMIC_TOOLS } from './tools/tier-config.js'; import { errorResponse } from './tools/types.js'; +const fullMode = process.argv.includes('--full'); const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'mcp-server', 'package.json'), 'utf-8')); class HanaCliMcpServer { server; commands = new Map(); + activatedCategories = []; + dynamicToolDefinitions = []; constructor() { const iconPngDataUri = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAM0SURBVFhHxZLfT5JhFMf5E/wPdCRkhWLXXXWvN93VHRVG1szNdVFtaUUta5mhVFKrtF+WAgFmzkz7AWrJfFADMU0gimyllGnLuvg2nhce3vd9rFgXb2f7jHO+5znnfAeoAKj+J5ygNJygNJygNJygNJygNJygNJygNCqN+z0yFLr4vNCVEGmJNOJcINsXz4o14VOiu+eIquBODCny0580b8/mf+rlt0d/+06ip9+JZ9V3YqSgM56nym+dRoY9XXFKpSfOtPzWGVE+jQJZLfRX06S5eE7dNkMKbszm0Z9A3RLCJe8HJJd+Qh4D4S9QtwSx6UpY0m/oT2CNLYTKzlnJ+0xMJr6h0h5BandqXm0LMQptk0R9OUyPUwNHPFH5PItHEwvQnAvgiDsi0UPxJWgtAZhuvZLo4kh+/YHyy0FoLAH6NoWmaYxorePsODXQF/jEhm48SWBbyzhqbobhHJpDuTUAzakXeD71WbI8FWXNAZiuhVjtHJ6j9XA4ybSLvXE6rz01grWnR4jmjF9ynBroHf3IBhYWV9DW/xblZ/1Yax6E1jyIsgY/64uj9VEcu2zjrD7fHYH22CBqWrOmLnRH6Y4i8xApOjHMHacGjNZRNiAO38t5bG30o74j+zU3u16zPPp+GRXnCasHg/Owemapnon6u1PQHn5KNHXeVY9TA+sO9MPY+ALj0/zXHEssUzJRZvaiZyjB6mbnNMvlsfBlBZvrnpL1hx7/9jg1oKvpRYatx7246pmR72LhG/uI6LslVovzTCx8XkFHXwxbjj4jG/Y//ONxwUBVN13U1D4J40kfqs8+l+/MKSy3Q9BVPRCo7iG66p6/HqcGDjaPyHetGs/8c4z55Hd5G5abQegqu1C8p4vo9t7P6Tg1sK/eh7HQvHwfIm8WJXnxLjdKTAInbPwf13J9AsUmDynZ7cn5ODWgN95DBmPtAHbWDtC8RKRLqHAJ8G9ISYUrT2+wl5YaHDmbUG3c4USK0hTbHUK+3ZEl3WM6rbP99CzR73TmfFRiILVEb7ALCw0CrKY9kRlRznSDg+gN9n86Tg3IBaXhBKXhBKXhBKXhBKXhBKXhBKXhBKX5BUtWC46LA416AAAAAElFTkSuQmCC'; this.server = new Server({ @@ -40,7 +45,7 @@ class HanaCliMcpServer { ], }, { capabilities: { - tools: {}, + tools: { listChanged: true }, resources: {}, prompts: {}, }, @@ -61,18 +66,37 @@ class HanaCliMcpServer { this.setupResourceHandlers(); this.setupPromptHandlers(); this.server.setRequestHandler(ListToolsRequestSchema, async () => { + if (fullMode) { + const tools = [ + ...getDiscoveryToolDefinitions(), + ...getContentToolDefinitions(), + ...getSearchToolDefinitions(), + ...getAllCliToolDefinitions(), + ]; + return { tools }; + } const tools = [ ...getDiscoveryToolDefinitions(), ...getContentToolDefinitions(), ...getSearchToolDefinitions(), + getRouterToolDefinition(), ...getCliToolDefinitions(), + ...this.dynamicToolDefinitions, ]; return { tools }; }); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; const commandName = name.startsWith('hana_') ? name.slice(5) : name; - const result = handleDiscoveryTool(commandName, args) ?? + if (isRouterTool(name)) { + const result = await handleRouterTool(args); + if (result) + return result; + } + const discoveryOptions = fullMode ? undefined : { + onCategoryActivated: (category) => this.activateCategory(category), + }; + const result = handleDiscoveryTool(commandName, args, discoveryOptions) ?? handleContentTool(commandName, args) ?? handleSearchTool(commandName, args) ?? await handleCliTool(name, args); @@ -125,6 +149,23 @@ class HanaCliMcpServer { } }); } + activateCategory(category) { + if (this.activatedCategories.includes(category)) + return; + const tier1Names = new Set(getCliToolDefinitions().map(t => t.name)); + const categoryTools = getCliToolDefinitionsForCategory(category) + .filter(t => !tier1Names.has(t.name)); + if (categoryTools.length === 0) + return; + this.activatedCategories.push(category); + this.dynamicToolDefinitions.push(...categoryTools); + // Enforce accumulation cap by removing oldest category's tools + while (this.dynamicToolDefinitions.length > MAX_DYNAMIC_TOOLS && this.activatedCategories.length > 1) { + const oldestCategory = this.activatedCategories.shift(); + this.dynamicToolDefinitions = this.dynamicToolDefinitions.filter(t => !getCliToolDefinitionsForCategory(oldestCategory).some(ct => ct.name === t.name)); + } + this.server.sendToolListChanged().catch(() => { }); + } async loadCommands() { try { const indexPath = join(__dirname, '..', '..', 'bin', 'index.js'); @@ -149,6 +190,7 @@ class HanaCliMcpServer { throw new Error('No valid commands were registered'); } initCliTools(this.commands); + initRouterTool(this.commands); } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); diff --git a/mcp-server/build/index.js.map b/mcp-server/build/index.js.map index 9d374b3..270076b 100644 --- a/mcp-server/build/index.js.map +++ b/mcp-server/build/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/mcp-server/build/tools/cli-tools.d.ts b/mcp-server/build/tools/cli-tools.d.ts index b49d8be..46d112d 100644 --- a/mcp-server/build/tools/cli-tools.d.ts +++ b/mcp-server/build/tools/cli-tools.d.ts @@ -1,5 +1,10 @@ import { ToolDefinition, ToolResponse } from './types.js'; export declare function initCliTools(commands: Map): void; +/** Returns tool definitions for tier-1 commands only (the default initial surface). */ export declare function getCliToolDefinitions(): ToolDefinition[]; +/** Returns tool definitions for ALL commands (backwards-compat / --full mode). */ +export declare function getAllCliToolDefinitions(): ToolDefinition[]; +/** Returns tool definitions for commands belonging to the specified category. */ +export declare function getCliToolDefinitionsForCategory(category: string): ToolDefinition[]; export declare function handleCliTool(toolName: string, args: Record): Promise; //# sourceMappingURL=cli-tools.d.ts.map \ No newline at end of file diff --git a/mcp-server/build/tools/cli-tools.d.ts.map b/mcp-server/build/tools/cli-tools.d.ts.map index bf9cafa..b3ced3e 100644 --- a/mcp-server/build/tools/cli-tools.d.ts.map +++ b/mcp-server/build/tools/cli-tools.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"cli-tools.d.ts","sourceRoot":"","sources":["../../src/tools/cli-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAA+B,MAAM,YAAY,CAAC;AA8BvF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAE7D;AAED,wBAAgB,qBAAqB,IAAI,cAAc,EAAE,CAqCxD;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAqC7G"} \ No newline at end of file +{"version":3,"file":"cli-tools.d.ts","sourceRoot":"","sources":["../../src/tools/cli-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAA+B,MAAM,YAAY,CAAC;AA+BvF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAE7D;AAmCD,uFAAuF;AACvF,wBAAgB,qBAAqB,IAAI,cAAc,EAAE,CASxD;AAED,kFAAkF;AAClF,wBAAgB,wBAAwB,IAAI,cAAc,EAAE,CAQ3D;AAED,iFAAiF;AACjF,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAWnF;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAqC7G"} \ No newline at end of file diff --git a/mcp-server/build/tools/cli-tools.js b/mcp-server/build/tools/cli-tools.js index d2e1c50..8ae3038 100644 --- a/mcp-server/build/tools/cli-tools.js +++ b/mcp-server/build/tools/cli-tools.js @@ -2,6 +2,7 @@ import { textResponse, errorResponse } from './types.js'; import { extractCommandInfo } from '../command-parser.js'; import { executeCommand, formatResult } from '../executor.js'; import { hasExamples, hasPresets } from '../examples-presets.js'; +import { isTier1Command } from './tier-config.js'; function sanitizeToolName(name) { return name .replace(/([a-z0-9])([A-Z])/g, '$1_$2') @@ -26,39 +27,64 @@ let commandsMap = new Map(); export function initCliTools(commands) { commandsMap = commands; } +function buildToolDefinition(name, commandModule) { + const info = extractCommandInfo(commandModule); + let fullDescription = info.description; + if (info.category) + fullDescription += ` [Category: ${info.category}]`; + if (info.tags && info.tags.length > 0) + fullDescription += ` [Tags: ${info.tags.join(', ')}]`; + if (info.useCases && info.useCases.length > 0) { + fullDescription += `\n\nCommon Use Cases:\n${info.useCases.map((uc) => `- ${uc}`).join('\n')}`; + } + if (info.relatedCommands && info.relatedCommands.length > 0) { + fullDescription += `\n\nRelated Commands: ${info.relatedCommands.map((rc) => `hana_${rc}`).join(', ')}`; + } + if (hasExamples(name)) { + fullDescription += `\n\nTip: Use hana_examples with command="${name}" to see usage examples.`; + } + if (hasPresets(name)) { + fullDescription += `\nTip: Use hana_parameter_presets with command="${name}" to see parameter templates.`; + } + return { + name: `hana_${sanitizeToolName(name)}`, + description: fullDescription, + inputSchema: { + type: 'object', + ...info.schema, + properties: { + ...(info.schema.properties || {}), + __projectContext: PROJECT_CONTEXT_SCHEMA, + }, + }, + }; +} +/** Returns tool definitions for tier-1 commands only (the default initial surface). */ export function getCliToolDefinitions() { + const tools = []; + for (const [name, commandModule] of commandsMap) { + if (!isTier1Command(name)) + continue; + tools.push(buildToolDefinition(name, commandModule)); + } + return tools; +} +/** Returns tool definitions for ALL commands (backwards-compat / --full mode). */ +export function getAllCliToolDefinitions() { + const tools = []; + for (const [name, commandModule] of commandsMap) { + tools.push(buildToolDefinition(name, commandModule)); + } + return tools; +} +/** Returns tool definitions for commands belonging to the specified category. */ +export function getCliToolDefinitionsForCategory(category) { const tools = []; for (const [name, commandModule] of commandsMap) { const info = extractCommandInfo(commandModule); - let fullDescription = info.description; - if (info.category) - fullDescription += ` [Category: ${info.category}]`; - if (info.tags && info.tags.length > 0) - fullDescription += ` [Tags: ${info.tags.join(', ')}]`; - if (info.useCases && info.useCases.length > 0) { - fullDescription += `\n\nCommon Use Cases:\n${info.useCases.map(uc => `- ${uc}`).join('\n')}`; - } - if (info.relatedCommands && info.relatedCommands.length > 0) { - fullDescription += `\n\nRelated Commands: ${info.relatedCommands.map(rc => `hana_${rc}`).join(', ')}`; - } - if (hasExamples(name)) { - fullDescription += `\n\nTip: Use hana_examples with command="${name}" to see usage examples.`; + if (info.category === category) { + tools.push(buildToolDefinition(name, commandModule)); } - if (hasPresets(name)) { - fullDescription += `\nTip: Use hana_parameter_presets with command="${name}" to see parameter templates.`; - } - tools.push({ - name: `hana_${sanitizeToolName(name)}`, - description: fullDescription, - inputSchema: { - type: 'object', - ...info.schema, - properties: { - ...(info.schema.properties || {}), - __projectContext: PROJECT_CONTEXT_SCHEMA, - }, - }, - }); } return tools; } diff --git a/mcp-server/build/tools/cli-tools.js.map b/mcp-server/build/tools/cli-tools.js.map index 960d21f..1e73424 100644 --- a/mcp-server/build/tools/cli-tools.js.map +++ b/mcp-server/build/tools/cli-tools.js.map @@ -1 +1 @@ -{"version":3,"file":"cli-tools.js","sourceRoot":"","sources":["../../src/tools/cli-tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"cli-tools.js","sourceRoot":"","sources":["../../src/tools/cli-tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/mcp-server/build/tools/discovery-tools.d.ts b/mcp-server/build/tools/discovery-tools.d.ts index 7972cef..a7437cc 100644 --- a/mcp-server/build/tools/discovery-tools.d.ts +++ b/mcp-server/build/tools/discovery-tools.d.ts @@ -1,4 +1,7 @@ import { ToolDefinition, ToolResponse } from './types.js'; export declare function getDiscoveryToolDefinitions(): ToolDefinition[]; -export declare function handleDiscoveryTool(commandName: string, args: Record): ToolResponse | null; +export interface DiscoveryToolOptions { + onCategoryActivated?: (category: string) => void; +} +export declare function handleDiscoveryTool(commandName: string, args: Record, options?: DiscoveryToolOptions): ToolResponse | null; //# sourceMappingURL=discovery-tools.d.ts.map \ No newline at end of file diff --git a/mcp-server/build/tools/discovery-tools.d.ts.map b/mcp-server/build/tools/discovery-tools.d.ts.map index 2b339fc..5fcfc58 100644 --- a/mcp-server/build/tools/discovery-tools.d.ts.map +++ b/mcp-server/build/tools/discovery-tools.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"discovery-tools.d.ts","sourceRoot":"","sources":["../../src/tools/discovery-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAA+B,MAAM,YAAY,CAAC;AAUvF,wBAAgB,2BAA2B,IAAI,cAAc,EAAE,CAqE9D;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,YAAY,GAAG,IAAI,CA2GvG"} \ No newline at end of file +{"version":3,"file":"discovery-tools.d.ts","sourceRoot":"","sources":["../../src/tools/discovery-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAA+B,MAAM,YAAY,CAAC;AAUvF,wBAAgB,2BAA2B,IAAI,cAAc,EAAE,CAqE9D;AAED,MAAM,WAAW,oBAAoB;IACnC,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,YAAY,GAAG,IAAI,CA+GvI"} \ No newline at end of file diff --git a/mcp-server/build/tools/discovery-tools.js b/mcp-server/build/tools/discovery-tools.js index 6ba015b..9bb87a7 100644 --- a/mcp-server/build/tools/discovery-tools.js +++ b/mcp-server/build/tools/discovery-tools.js @@ -70,7 +70,7 @@ export function getDiscoveryToolDefinitions() { }, ]; } -export function handleDiscoveryTool(commandName, args) { +export function handleDiscoveryTool(commandName, args, options) { if (commandName === 'discover_categories') { const categoryList = Object.entries(CATEGORIES).map(([key, value]) => ({ id: key, @@ -95,6 +95,9 @@ export function handleDiscoveryTool(commandName, args) { tip: 'Use hana_discover_categories to see available categories', }); } + if (options?.onCategoryActivated) { + options.onCategoryActivated(category); + } return jsonResponse({ category, categoryInfo: CATEGORIES[category], diff --git a/mcp-server/build/tools/discovery-tools.js.map b/mcp-server/build/tools/discovery-tools.js.map index 0f925e7..6a029cb 100644 --- a/mcp-server/build/tools/discovery-tools.js.map +++ b/mcp-server/build/tools/discovery-tools.js.map @@ -1 +1 @@ -{"version":3,"file":"discovery-tools.js","sourceRoot":"","sources":["../../src/tools/discovery-tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"discovery-tools.js","sourceRoot":"","sources":["../../src/tools/discovery-tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/mcp-server/build/tools/router-tool.d.ts b/mcp-server/build/tools/router-tool.d.ts new file mode 100644 index 0000000..ab88b4e --- /dev/null +++ b/mcp-server/build/tools/router-tool.d.ts @@ -0,0 +1,5 @@ +import { ToolDefinition, ToolResponse } from './types.js'; +export declare function initRouterTool(commands: Map): void; +export declare function getRouterToolDefinition(): ToolDefinition; +export declare function handleRouterTool(args: Record): Promise; +//# sourceMappingURL=router-tool.d.ts.map \ No newline at end of file diff --git a/mcp-server/build/tools/router-tool.d.ts.map b/mcp-server/build/tools/router-tool.d.ts.map new file mode 100644 index 0000000..a3a6429 --- /dev/null +++ b/mcp-server/build/tools/router-tool.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"router-tool.d.ts","sourceRoot":"","sources":["../../src/tools/router-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAA+B,MAAM,YAAY,CAAC;AA6BvF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAE/D;AAED,wBAAgB,uBAAuB,IAAI,cAAc,CAuBxD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAiD9F"} \ No newline at end of file diff --git a/mcp-server/build/tools/router-tool.js b/mcp-server/build/tools/router-tool.js new file mode 100644 index 0000000..6b33885 --- /dev/null +++ b/mcp-server/build/tools/router-tool.js @@ -0,0 +1,96 @@ +import { textResponse, errorResponse } from './types.js'; +import { executeCommand, formatResult } from '../executor.js'; +import { ROUTER_TOOL_NAME } from './tier-config.js'; +function sanitizeToolName(name) { + return name + .replace(/([a-z0-9])([A-Z])/g, '$1_$2') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') + .toLowerCase() + .replace(/[^a-z0-9_-]/g, '_'); +} +const PROJECT_CONTEXT_SCHEMA = { + type: 'object', + description: 'Project-specific connection context (optional). Use this to connect to a project-specific database instead of the default.', + properties: { + connectionFile: { type: 'string', description: 'Connection file name relative to projectPath (e.g., ".env", "default-env.json").' }, + database: { type: 'string', description: 'Database name (default "SYSTEMDB").' }, + host: { type: 'string', description: 'Database host (for direct connection).' }, + password: { type: 'string', description: 'Database password. SECURITY WARNING: Prefer connection files instead.' }, + port: { type: 'number', description: 'Database port (default 30013).' }, + projectPath: { type: 'string', description: 'Absolute path to the project directory.' }, + user: { type: 'string', description: 'Database user.' }, + }, +}; +let commandsMap = new Map(); +export function initRouterTool(commands) { + commandsMap = commands; +} +export function getRouterToolDefinition() { + return { + name: ROUTER_TOOL_NAME, + description: 'Execute any hana-cli command by name. Use hana_discover_categories, hana_discover_by_category, or hana_recommend to find available commands before calling this tool.', + inputSchema: { + type: 'object', + properties: { + command: { + type: 'string', + description: 'The command name to execute (e.g., "tables", "inspectTable", "querySimple").', + }, + args: { + type: 'object', + description: 'Command-specific arguments to pass to the command.', + properties: {}, + additionalProperties: true, + }, + __projectContext: PROJECT_CONTEXT_SCHEMA, + }, + required: ['command'], + }, + }; +} +export async function handleRouterTool(args) { + const { command, args: commandArgs = {}, __projectContext } = args; + if (!command || typeof command !== 'string') { + return errorResponse('Missing required parameter: command. Use hana_discover_categories or hana_recommend to find available commands.'); + } + // Resolve the actual command name: direct match first + let actualCommandName; + if (commandsMap.has(command)) { + actualCommandName = command; + } + else { + // Try sanitized match or alias match (same logic as cli-tools.ts) + const sanitized = sanitizeToolName(command); + for (const [cmdName, cmdModule] of commandsMap) { + if (sanitizeToolName(cmdName) === sanitized) { + actualCommandName = cmdName; + break; + } + if (cmdModule.aliases) { + for (const alias of cmdModule.aliases) { + if (sanitizeToolName(String(alias)) === sanitized) { + actualCommandName = cmdName; + break; + } + } + if (actualCommandName !== undefined) + break; + } + } + } + if (actualCommandName === undefined) { + return errorResponse(`Unknown command: "${command}". Use hana_discover_categories, hana_discover_by_category, or hana_recommend to find available commands.`); + } + try { + const context = __projectContext; + const cleanArgs = { ...commandArgs }; + delete cleanArgs.__projectContext; + const result = await executeCommand(actualCommandName, cleanArgs, context); + const formattedOutput = formatResult(result); + return textResponse(formattedOutput); + } + catch (error) { + return errorResponse(`Error executing command "${actualCommandName}": ${error instanceof Error ? error.message : String(error)}`); + } +} +//# sourceMappingURL=router-tool.js.map \ No newline at end of file diff --git a/mcp-server/build/tools/router-tool.js.map b/mcp-server/build/tools/router-tool.js.map new file mode 100644 index 0000000..6271770 --- /dev/null +++ b/mcp-server/build/tools/router-tool.js.map @@ -0,0 +1 @@ +{"version":3,"file":"router-tool.js","sourceRoot":"","sources":["../../src/tools/router-tool.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/mcp-server/build/tools/tier-config.d.ts b/mcp-server/build/tools/tier-config.d.ts new file mode 100644 index 0000000..dcd27a3 --- /dev/null +++ b/mcp-server/build/tools/tier-config.d.ts @@ -0,0 +1,6 @@ +export declare const TIER_1_COMMANDS: string[]; +export declare const ROUTER_TOOL_NAME = "hana_execute"; +export declare const MAX_DYNAMIC_TOOLS = 50; +export declare function isTier1Command(name: string): boolean; +export declare function isRouterTool(name: string): boolean; +//# sourceMappingURL=tier-config.d.ts.map \ No newline at end of file diff --git a/mcp-server/build/tools/tier-config.d.ts.map b/mcp-server/build/tools/tier-config.d.ts.map new file mode 100644 index 0000000..feed109 --- /dev/null +++ b/mcp-server/build/tools/tier-config.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"tier-config.d.ts","sourceRoot":"","sources":["../../src/tools/tier-config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,EAAE,MAAM,EAMnC,CAAC;AAEF,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD"} \ No newline at end of file diff --git a/mcp-server/build/tools/tier-config.js b/mcp-server/build/tools/tier-config.js new file mode 100644 index 0000000..e87a2b5 --- /dev/null +++ b/mcp-server/build/tools/tier-config.js @@ -0,0 +1,16 @@ +export const TIER_1_COMMANDS = [ + 'querySimple', + 'tables', + 'inspectTable', + 'views', + 'status', +]; +export const ROUTER_TOOL_NAME = 'hana_execute'; +export const MAX_DYNAMIC_TOOLS = 50; +export function isTier1Command(name) { + return TIER_1_COMMANDS.includes(name); +} +export function isRouterTool(name) { + return name === ROUTER_TOOL_NAME; +} +//# sourceMappingURL=tier-config.js.map \ No newline at end of file diff --git a/mcp-server/build/tools/tier-config.js.map b/mcp-server/build/tools/tier-config.js.map new file mode 100644 index 0000000..652ec39 --- /dev/null +++ b/mcp-server/build/tools/tier-config.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tier-config.js","sourceRoot":"","sources":["../../src/tools/tier-config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,aAAa;IACb,QAAQ;IACR,cAAc;IACd,OAAO;IACP,QAAQ;CACT,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAE/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAEpC,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,KAAK,gBAAgB,CAAC;AACnC,CAAC"} \ No newline at end of file diff --git a/mcp-server/src/index.ts b/mcp-server/src/index.ts index f040822..fe3d0ea 100644 --- a/mcp-server/src/index.ts +++ b/mcp-server/src/index.ts @@ -27,8 +27,13 @@ import { listPrompts, getPrompt } from './prompts.js'; import { getDiscoveryToolDefinitions, handleDiscoveryTool } from './tools/discovery-tools.js'; import { getContentToolDefinitions, handleContentTool } from './tools/content-tools.js'; import { getSearchToolDefinitions, handleSearchTool } from './tools/search-tools.js'; -import { initCliTools, getCliToolDefinitions, handleCliTool } from './tools/cli-tools.js'; +import { initCliTools, getCliToolDefinitions, getAllCliToolDefinitions, getCliToolDefinitionsForCategory, handleCliTool } from './tools/cli-tools.js'; +import { initRouterTool, getRouterToolDefinition, handleRouterTool } from './tools/router-tool.js'; +import { isRouterTool, MAX_DYNAMIC_TOOLS } from './tools/tier-config.js'; import { errorResponse } from './tools/types.js'; +import type { ToolDefinition } from './tools/types.js'; + +const fullMode = process.argv.includes('--full'); const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -40,6 +45,8 @@ const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'mcp-server', 'p class HanaCliMcpServer { private server: Server; private commands: Map = new Map(); + private activatedCategories: string[] = []; + private dynamicToolDefinitions: ToolDefinition[] = []; constructor() { const iconPngDataUri = @@ -59,7 +66,7 @@ class HanaCliMcpServer { }, { capabilities: { - tools: {}, + tools: { listChanged: true }, resources: {}, prompts: {}, }, @@ -86,11 +93,23 @@ class HanaCliMcpServer { this.setupPromptHandlers(); this.server.setRequestHandler(ListToolsRequestSchema, async () => { + if (fullMode) { + const tools = [ + ...getDiscoveryToolDefinitions(), + ...getContentToolDefinitions(), + ...getSearchToolDefinitions(), + ...getAllCliToolDefinitions(), + ]; + return { tools }; + } + const tools = [ ...getDiscoveryToolDefinitions(), ...getContentToolDefinitions(), ...getSearchToolDefinitions(), + getRouterToolDefinition(), ...getCliToolDefinitions(), + ...this.dynamicToolDefinitions, ]; return { tools }; }); @@ -99,8 +118,17 @@ class HanaCliMcpServer { const { name, arguments: args } = request.params; const commandName = name.startsWith('hana_') ? name.slice(5) : name; + if (isRouterTool(name)) { + const result = await handleRouterTool(args as Record); + if (result) return result; + } + + const discoveryOptions = fullMode ? undefined : { + onCategoryActivated: (category: string) => this.activateCategory(category), + }; + const result = - handleDiscoveryTool(commandName, args as Record) ?? + handleDiscoveryTool(commandName, args as Record, discoveryOptions) ?? handleContentTool(commandName, args as Record) ?? handleSearchTool(commandName, args as Record) ?? await handleCliTool(name, args as Record); @@ -155,6 +183,28 @@ class HanaCliMcpServer { }); } + private activateCategory(category: string): void { + if (this.activatedCategories.includes(category)) return; + + const tier1Names = new Set(getCliToolDefinitions().map(t => t.name)); + const categoryTools = getCliToolDefinitionsForCategory(category) + .filter(t => !tier1Names.has(t.name)); + if (categoryTools.length === 0) return; + + this.activatedCategories.push(category); + this.dynamicToolDefinitions.push(...categoryTools); + + // Enforce accumulation cap by removing oldest category's tools + while (this.dynamicToolDefinitions.length > MAX_DYNAMIC_TOOLS && this.activatedCategories.length > 1) { + const oldestCategory = this.activatedCategories.shift()!; + this.dynamicToolDefinitions = this.dynamicToolDefinitions.filter( + t => !getCliToolDefinitionsForCategory(oldestCategory).some(ct => ct.name === t.name) + ); + } + + this.server.sendToolListChanged().catch(() => {}); + } + async loadCommands(): Promise { try { const indexPath = join(__dirname, '..', '..', 'bin', 'index.js'); @@ -187,6 +237,7 @@ class HanaCliMcpServer { } initCliTools(this.commands); + initRouterTool(this.commands); } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); console.error(`[MCP] Failed to load commands: ${errorMsg}`); diff --git a/mcp-server/src/tools/cli-tools.ts b/mcp-server/src/tools/cli-tools.ts index b331456..2b2ae99 100644 --- a/mcp-server/src/tools/cli-tools.ts +++ b/mcp-server/src/tools/cli-tools.ts @@ -3,6 +3,7 @@ import { extractCommandInfo } from '../command-parser.js'; import { executeCommand, formatResult } from '../executor.js'; import { ConnectionContext } from '../connection-context.js'; import { hasExamples, hasPresets } from '../examples-presets.js'; +import { isTier1Command } from './tier-config.js'; function sanitizeToolName(name: string): string { return name @@ -32,40 +33,71 @@ export function initCliTools(commands: Map): void { commandsMap = commands; } +function buildToolDefinition(name: string, commandModule: any): ToolDefinition { + const info = extractCommandInfo(commandModule); + + let fullDescription = info.description; + if (info.category) fullDescription += ` [Category: ${info.category}]`; + if (info.tags && info.tags.length > 0) fullDescription += ` [Tags: ${info.tags.join(', ')}]`; + if (info.useCases && info.useCases.length > 0) { + fullDescription += `\n\nCommon Use Cases:\n${info.useCases.map((uc: string) => `- ${uc}`).join('\n')}`; + } + if (info.relatedCommands && info.relatedCommands.length > 0) { + fullDescription += `\n\nRelated Commands: ${info.relatedCommands.map((rc: string) => `hana_${rc}`).join(', ')}`; + } + if (hasExamples(name)) { + fullDescription += `\n\nTip: Use hana_examples with command="${name}" to see usage examples.`; + } + if (hasPresets(name)) { + fullDescription += `\nTip: Use hana_parameter_presets with command="${name}" to see parameter templates.`; + } + + return { + name: `hana_${sanitizeToolName(name)}`, + description: fullDescription, + inputSchema: { + type: 'object', + ...info.schema, + properties: { + ...(info.schema.properties || {}), + __projectContext: PROJECT_CONTEXT_SCHEMA, + }, + }, + }; +} + +/** Returns tool definitions for tier-1 commands only (the default initial surface). */ export function getCliToolDefinitions(): ToolDefinition[] { const tools: ToolDefinition[] = []; for (const [name, commandModule] of commandsMap) { - const info = extractCommandInfo(commandModule); + if (!isTier1Command(name)) continue; + tools.push(buildToolDefinition(name, commandModule)); + } - let fullDescription = info.description; - if (info.category) fullDescription += ` [Category: ${info.category}]`; - if (info.tags && info.tags.length > 0) fullDescription += ` [Tags: ${info.tags.join(', ')}]`; - if (info.useCases && info.useCases.length > 0) { - fullDescription += `\n\nCommon Use Cases:\n${info.useCases.map(uc => `- ${uc}`).join('\n')}`; - } - if (info.relatedCommands && info.relatedCommands.length > 0) { - fullDescription += `\n\nRelated Commands: ${info.relatedCommands.map(rc => `hana_${rc}`).join(', ')}`; - } - if (hasExamples(name)) { - fullDescription += `\n\nTip: Use hana_examples with command="${name}" to see usage examples.`; - } - if (hasPresets(name)) { - fullDescription += `\nTip: Use hana_parameter_presets with command="${name}" to see parameter templates.`; - } + return tools; +} - tools.push({ - name: `hana_${sanitizeToolName(name)}`, - description: fullDescription, - inputSchema: { - type: 'object', - ...info.schema, - properties: { - ...(info.schema.properties || {}), - __projectContext: PROJECT_CONTEXT_SCHEMA, - }, - }, - }); +/** Returns tool definitions for ALL commands (backwards-compat / --full mode). */ +export function getAllCliToolDefinitions(): ToolDefinition[] { + const tools: ToolDefinition[] = []; + + for (const [name, commandModule] of commandsMap) { + tools.push(buildToolDefinition(name, commandModule)); + } + + return tools; +} + +/** Returns tool definitions for commands belonging to the specified category. */ +export function getCliToolDefinitionsForCategory(category: string): ToolDefinition[] { + const tools: ToolDefinition[] = []; + + for (const [name, commandModule] of commandsMap) { + const info = extractCommandInfo(commandModule); + if (info.category === category) { + tools.push(buildToolDefinition(name, commandModule)); + } } return tools; diff --git a/mcp-server/src/tools/discovery-tools.ts b/mcp-server/src/tools/discovery-tools.ts index 9b05056..31561e7 100644 --- a/mcp-server/src/tools/discovery-tools.ts +++ b/mcp-server/src/tools/discovery-tools.ts @@ -79,7 +79,11 @@ export function getDiscoveryToolDefinitions(): ToolDefinition[] { ]; } -export function handleDiscoveryTool(commandName: string, args: Record): ToolResponse | null { +export interface DiscoveryToolOptions { + onCategoryActivated?: (category: string) => void; +} + +export function handleDiscoveryTool(commandName: string, args: Record, options?: DiscoveryToolOptions): ToolResponse | null { if (commandName === 'discover_categories') { const categoryList = Object.entries(CATEGORIES).map(([key, value]) => ({ id: key, @@ -105,6 +109,10 @@ export function handleDiscoveryTool(commandName: string, args: Record = new Map(); + +export function initRouterTool(commands: Map): void { + commandsMap = commands; +} + +export function getRouterToolDefinition(): ToolDefinition { + return { + name: ROUTER_TOOL_NAME, + description: + 'Execute any hana-cli command by name. Use hana_discover_categories, hana_discover_by_category, or hana_recommend to find available commands before calling this tool.', + inputSchema: { + type: 'object', + properties: { + command: { + type: 'string', + description: 'The command name to execute (e.g., "tables", "inspectTable", "querySimple").', + }, + args: { + type: 'object', + description: 'Command-specific arguments to pass to the command.', + properties: {}, + additionalProperties: true, + }, + __projectContext: PROJECT_CONTEXT_SCHEMA, + }, + required: ['command'], + }, + }; +} + +export async function handleRouterTool(args: Record): Promise { + const { command, args: commandArgs = {}, __projectContext } = args; + + if (!command || typeof command !== 'string') { + return errorResponse('Missing required parameter: command. Use hana_discover_categories or hana_recommend to find available commands.'); + } + + // Resolve the actual command name: direct match first + let actualCommandName: string | undefined; + + if (commandsMap.has(command)) { + actualCommandName = command; + } else { + // Try sanitized match or alias match (same logic as cli-tools.ts) + const sanitized = sanitizeToolName(command); + for (const [cmdName, cmdModule] of commandsMap) { + if (sanitizeToolName(cmdName) === sanitized) { + actualCommandName = cmdName; + break; + } + if (cmdModule.aliases) { + for (const alias of cmdModule.aliases) { + if (sanitizeToolName(String(alias)) === sanitized) { + actualCommandName = cmdName; + break; + } + } + if (actualCommandName !== undefined) break; + } + } + } + + if (actualCommandName === undefined) { + return errorResponse( + `Unknown command: "${command}". Use hana_discover_categories, hana_discover_by_category, or hana_recommend to find available commands.` + ); + } + + try { + const context = __projectContext as ConnectionContext | undefined; + const cleanArgs = { ...(commandArgs as Record) }; + delete cleanArgs.__projectContext; + + const result = await executeCommand(actualCommandName, cleanArgs, context); + const formattedOutput = formatResult(result); + return textResponse(formattedOutput); + } catch (error) { + return errorResponse(`Error executing command "${actualCommandName}": ${error instanceof Error ? error.message : String(error)}`); + } +} diff --git a/mcp-server/src/tools/tier-config.ts b/mcp-server/src/tools/tier-config.ts new file mode 100644 index 0000000..0830219 --- /dev/null +++ b/mcp-server/src/tools/tier-config.ts @@ -0,0 +1,19 @@ +export const TIER_1_COMMANDS: string[] = [ + 'querySimple', + 'tables', + 'inspectTable', + 'views', + 'status', +]; + +export const ROUTER_TOOL_NAME = 'hana_execute'; + +export const MAX_DYNAMIC_TOOLS = 50; + +export function isTier1Command(name: string): boolean { + return TIER_1_COMMANDS.includes(name); +} + +export function isRouterTool(name: string): boolean { + return name === ROUTER_TOOL_NAME; +}