diff --git a/.github/workflows/release-hana-cli.yml b/.github/workflows/release-hana-cli.yml index 83c2774e..85b59a05 100644 --- a/.github/workflows/release-hana-cli.yml +++ b/.github/workflows/release-hana-cli.yml @@ -15,14 +15,15 @@ on: required: false type: string default: '[]' - publish_mcp_server: - description: 'Also publish hana-cli-mcp-server to npm?' + publish_mcp_registry: + description: 'Also publish to MCP Registry?' required: false type: boolean default: true permissions: contents: write + id-token: write concurrency: group: release-hana-cli @@ -107,7 +108,7 @@ jobs: - name: Commit version bump and changelog run: | - git add package.json npm-shrinkwrap.json mcp-server/package.json mcp-server/npm-shrinkwrap.json CHANGELOG.json CHANGELOG.md + git add package.json npm-shrinkwrap.json server.json mcp-server/package.json mcp-server/npm-shrinkwrap.json CHANGELOG.json CHANGELOG.md git diff --cached --quiet && echo "No changes to commit" && exit 0 git commit -m "chore: release v${{ steps.calc.outputs.version }} [skip ci]" @@ -200,14 +201,17 @@ jobs: draft: false prerelease: ${{ contains(steps.ver.outputs.version, '-') }} - publish-mcp-server: - name: Publish MCP Server to npm + publish-mcp-registry: + name: Publish to MCP Registry needs: [publish, prepare, resolve-version] if: | always() && needs.publish.result == 'success' && - (github.event_name == 'push' || inputs.publish_mcp_server == true) + (github.event_name == 'push' || inputs.publish_mcp_registry == true) runs-on: ubuntu-latest + permissions: + id-token: write + contents: read steps: - name: Determine version id: ver @@ -223,21 +227,12 @@ jobs: with: ref: "v${{ steps.ver.outputs.version }}" - - name: Setup Node.js with npm registry - uses: actions/setup-node@v4 - with: - node-version: '20' - registry-url: 'https://registry.npmjs.org' - cache: 'npm' - - - name: Install and build MCP server - working-directory: mcp-server + - name: Install mcp-publisher run: | - npm ci - npm run build + curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher - - name: Publish mcp-server to npm - working-directory: mcp-server - run: npm publish - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Authenticate to MCP Registry + run: ./mcp-publisher login github-oidc + + - name: Publish server to MCP Registry + run: ./mcp-publisher publish diff --git a/CHANGELOG.json b/CHANGELOG.json index 3a8bd97b..39df5960 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -2,8 +2,22 @@ { "date": "2026-04-23", "version": "4.202604.0", + "Added": [ + "New mcpServerInstall command (hana-cli mcp) for one-command MCP server configuration in Claude Desktop, Claude Code, Cursor, Windsurf, Cline, VS Code, Continue, and Zed", + "New mcpServerStatus command (hana-cli mcp-status) to check MCP server installation status across all 8 supported AI assistant clients", + "MCP resources for knowledge base content and documentation index metadata" + ], "Changed": [ - "Release version 4.202604.0" + "Major MCP server refactor: modular architecture replacing monolithic 1,700-line index.ts", + "Reduced MCP tool count by removing alias registrations and consolidating search tools", + "Updated MCP SDK from 1.27.1 to 1.29.0", + "Fixed MCP server version to read dynamically from package.json", + "Fixed fragile command name matching in output formatter", + "Added isError signaling to all MCP error response paths" + ], + "Removed": [ + "Removed simulated workflow execution tools (LLMs orchestrate multi-step tasks more effectively)", + "Removed no-op validateEnvironment function and low-value metadata tools" ] }, { diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dbf50e1..2fefa1d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,29 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). ## [4.202604.0] - 2026-04-23 +**Added** + +- New `mcpServerInstall` command (`hana-cli mcp`) — one-command setup for MCP server configuration in Claude Desktop, Claude Code, Cursor, Windsurf, Cline, VS Code, Continue, and Zed +- New `mcpServerStatus` command (`hana-cli mcp-status`) — check MCP server installation status across all 8 supported AI assistant clients +- MCP resources for knowledge base content (connection guide, security guide, best practices, project structure, parameter guides) +- MCP documentation index metadata resources (statistics, categories) + **Changed** -- Release version 4.202604.0 +- Major MCP server refactor: rewrote monolithic index.ts (1,700 lines) into modular architecture (~200 line bootstrap + 5 handler modules) +- Reduced MCP tool count by removing alias tool registrations (aliases still resolve at call time) +- Consolidated 3 search tools (`hana_search_docs`, `hana_smart_search`, `hana_docs_search`) into single `hana_search` with scope parameter +- Moved 6 static knowledge tools to MCP resources for reduced LLM context usage +- Updated MCP SDK from 1.27.1 to 1.29.0 +- Fixed MCP server version to read dynamically from package.json instead of hardcoded value +- Fixed fragile command name matching in output formatter (exact-match map instead of substring includes) +- Added `isError: true` signaling to all MCP error response paths + +**Removed** + +- Removed simulated workflow execution tools (`hana_execute_workflow`, `hana_preview_workflow`) — LLMs orchestrate multi-step tasks more effectively +- Removed no-op `validateEnvironment` function from MCP executor +- Removed low-value `hana_commands_with_examples`, `hana_docs_stats`, `hana_list_doc_categories` tools ## [4.202603.2] - 2026-03-13 diff --git a/_i18n/messages.properties b/_i18n/messages.properties index df152929..4041c151 100644 --- a/_i18n/messages.properties +++ b/_i18n/messages.properties @@ -1602,4 +1602,40 @@ didYouMeanSingle=\n\nDid you mean this?\n {0} didYouMeanMultiple=\n\nDid you mean one of these?\n {0} # Option Suggestions (Did You Mean for options) didYouMeanOption=Did you mean --{0}? + +# MCP Server Install Command +mcpServerInstall=Install the MCP server configuration into AI assistant clients (Claude Desktop, Claude Code, Cursor, Windsurf, Cline, VS Code, Continue, Zed) +mcpServerInstallClient=Target client to configure (claude-desktop, claude-code, cursor, windsurf, cline, vscode, continue, zed, or auto to detect) +mcpServerInstallName=Server name in the MCP configuration +mcpServerInstallDryRun=Show what would be written without making changes +mcpServerInstallGlobal=Install globally (user-level) instead of project-level +mcpServerInstallExample1=Install MCP server for Claude Desktop +mcpServerInstallExample2=Preview the configuration without writing +mcpServerInstallExample3=Install globally for Claude Code +mcpServerInstallNotBuilt=MCP server has not been built yet. Run: +mcpServerInstallHeader=SAP HANA CLI - MCP Server Installation +mcpServerInstallServerPath=Server path: +mcpServerInstallServerName=Server name: +mcpServerInstallDryRunHeader=Dry run - configuration that would be written: +mcpServerInstallConfigPath=Config: +mcpServerInstallConfigExists=Exists: +mcpServerInstallSkipped=skipped (config file not found, use --client to target) +mcpServerInstallSuccess=configured successfully +mcpServerInstallFailed=failed to configure: +mcpServerInstallComplete=MCP server configured in {0} client(s). +mcpServerInstallRestart=Restart the client application to activate the MCP server. +mcpServerInstallNone=No clients were configured. +mcpServerInstallNoneHint=Use --client to specify a target, or create the config file first. + +# MCP Server Status Command +mcpServerStatus=Check MCP server installation status across all supported AI assistant clients +mcpServerStatusExample=hana-cli mcpServerStatus +mcpServerStatusHeader=SAP HANA CLI - MCP Server Status +mcpServerStatusServerPath=Server path: +mcpServerStatusBuilt=Built: +mcpServerStatusClients=Client Configuration Status: +mcpServerStatusConfigured=configured +mcpServerStatusNotConfigured=config exists, not configured +mcpServerStatusNotFound=config not found +mcpServerStatusBuildHint=MCP server is not built. Build it first: didYouMeanMultipleOptions=Did you mean one of these?\n --{0} \ No newline at end of file diff --git a/bin/commandMap.js b/bin/commandMap.js index c28a42d9..99aeea34 100644 --- a/bin/commandMap.js +++ b/bin/commandMap.js @@ -249,6 +249,13 @@ export const commandMap = { 'massUpd': './massUpdate.js', 'massupd': './massUpdate.js', 'massUsers': './massUsers.js', + 'mcpServerInstall': './mcpServerInstall.js', + 'mcp': './mcpServerInstall.js', + 'mcpInstall': './mcpServerInstall.js', + 'mcp-install': './mcpServerInstall.js', + 'mcpServerStatus': './mcpServerStatus.js', + 'mcp-status': './mcpServerStatus.js', + 'mcpStatus': './mcpServerStatus.js', 'memoryAnalysis': './memoryAnalysis.js', 'memoryLeaks': './memoryLeaks.js', 'memleak': './memoryLeaks.js', diff --git a/bin/commandMetadata.js b/bin/commandMetadata.js index 22582f8d..20dcc116 100644 --- a/bin/commandMetadata.js +++ b/bin/commandMetadata.js @@ -209,6 +209,8 @@ export const commandMetadata = { openDBExplorer: { category: 'schema-tools', relatedCommands: ['tables', 'schemas', 'objects'] }, openBAS: { category: 'developer-tools', relatedCommands: ['cds', 'activateHDI'] }, issue: { category: 'developer-tools', relatedCommands: ['diagnose', 'helpDocu'] }, + mcpServerInstall: { category: 'developer-tools', relatedCommands: ['mcpServerStatus', 'helpDocu'] }, + mcpServerStatus: { category: 'developer-tools', relatedCommands: ['mcpServerInstall', 'helpDocu'] }, // UI Feature Flags features: { category: 'system-tools', relatedCommands: ['featuresUI', 'systemInfo'] }, diff --git a/bin/mcpServerInstall.js b/bin/mcpServerInstall.js new file mode 100644 index 00000000..c14cb120 --- /dev/null +++ b/bin/mcpServerInstall.js @@ -0,0 +1,265 @@ +// @ts-check +import * as baseLite from '../utils/base-lite.js' +import { buildDocEpilogue } from '../utils/doc-linker.js' +import { fileURLToPath } from 'url' +import { dirname, join, resolve } from 'path' +import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs' +import { homedir, platform } from 'os' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) + +const ALL_CLIENT_IDS = ['claude-desktop', 'claude-code', 'cursor', 'windsurf', 'cline', 'vscode', 'continue', 'zed'] + +/** + * Client descriptor: declares config file path(s) per OS and the JSON key used for MCP servers. + * Most clients use { "mcpServers": { name: config } }. + * VS Code uses { "servers": { name: config } } in a dedicated mcp.json. + * Zed uses { "context_servers": { name: config } } inside settings.json. + */ +function getClientDescriptors(useGlobal) { + const home = homedir() + const os = platform() + const appData = process.env.APPDATA || join(home, 'AppData', 'Roaming') + + function perOS(win, mac, linux) { + if (os === 'win32') return win + if (os === 'darwin') return mac + return linux + } + + return { + 'claude-desktop': { + label: 'Claude Desktop', + configKey: 'mcpServers', + path: perOS( + join(appData, 'Claude', 'claude_desktop_config.json'), + join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'), + join(home, '.config', 'Claude', 'claude_desktop_config.json') + ), + }, + 'claude-code': { + label: useGlobal ? 'Claude Code (user)' : 'Claude Code (project)', + configKey: 'mcpServers', + path: useGlobal + ? join(home, '.claude.json') + : join(process.cwd(), '.mcp.json'), + }, + 'cursor': { + label: 'Cursor', + configKey: 'mcpServers', + path: perOS( + join(appData, 'Cursor', 'User', 'globalStorage', 'cursor.mcp', 'settings.json'), + join(home, 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'cursor.mcp', 'settings.json'), + join(home, '.config', 'Cursor', 'User', 'globalStorage', 'cursor.mcp', 'settings.json') + ), + }, + 'windsurf': { + label: 'Windsurf', + configKey: 'mcpServers', + path: join(home, '.codeium', 'windsurf', 'mcp_config.json'), + }, + 'cline': { + label: 'Cline (VS Code)', + configKey: 'mcpServers', + path: perOS( + join(appData, 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json'), + join(home, 'Library', 'Application Support', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json'), + join(home, '.config', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json') + ), + }, + 'vscode': { + label: useGlobal ? 'VS Code (user)' : 'VS Code (workspace)', + configKey: 'servers', + path: useGlobal + ? perOS( + join(appData, 'Code', 'User', 'mcp.json'), + join(home, 'Library', 'Application Support', 'Code', 'User', 'mcp.json'), + join(home, '.config', 'Code', 'User', 'mcp.json') + ) + : join(process.cwd(), '.vscode', 'mcp.json'), + }, + 'continue': { + label: 'Continue', + configKey: 'mcpServers', + path: join(home, '.continue', 'config.json'), + }, + 'zed': { + label: 'Zed', + configKey: 'context_servers', + path: perOS( + join(appData, 'Zed', 'settings.json'), + join(home, '.config', 'zed', 'settings.json'), + join(home, '.config', 'zed', 'settings.json') + ), + }, + } +} + +export const command = 'mcpServerInstall' +export const aliases = ['mcp', 'mcpInstall', 'mcp-install'] +export const describe = baseLite.bundle.getText("mcpServerInstall") +export const builder = (yargs) => yargs.options(baseLite.getBuilder({ + client: { + alias: ['c'], + type: 'string', + choices: [...ALL_CLIENT_IDS, 'auto'], + default: 'auto', + describe: baseLite.bundle.getText("mcpServerInstallClient") + }, + name: { + alias: ['n'], + type: 'string', + default: 'hana-cli', + describe: baseLite.bundle.getText("mcpServerInstallName") + }, + dryRun: { + alias: ['dr'], + type: 'boolean', + default: false, + describe: baseLite.bundle.getText("mcpServerInstallDryRun") + }, + global: { + alias: ['g'], + type: 'boolean', + default: false, + describe: baseLite.bundle.getText("mcpServerInstallGlobal") + } +}, false, false)).wrap(160).example( + 'hana-cli mcpServerInstall --client claude-desktop', + baseLite.bundle.getText("mcpServerInstallExample1") +).example( + 'hana-cli mcp --dry-run', + baseLite.bundle.getText("mcpServerInstallExample2") +).example( + 'hana-cli mcp --client claude-code --global', + baseLite.bundle.getText("mcpServerInstallExample3") +).epilog(buildDocEpilogue('mcpServerInstall', 'developer-tools', ['mcpServerStatus'])) + +export async function handler(argv) { + const base = await import('../utils/base.js') + base.promptHandler(argv, mcpInstall, { + client: argv.client, + name: argv.name, + dryRun: argv.dryRun, + global: argv.global, + }, false) +} + +function getMcpServerPath() { + return resolve(__dirname, '..', 'mcp-server', 'build', 'index.js') +} + +function buildMcpConfig() { + return { + type: 'stdio', + command: process.execPath, + args: [getMcpServerPath()], + } +} + +function getTargetClients(client, useGlobal) { + const descriptors = getClientDescriptors(useGlobal) + if (client === 'auto') { + return ALL_CLIENT_IDS.map(id => ({ id, ...descriptors[id] })) + } + const desc = descriptors[client] + return desc ? [{ id: client, ...desc }] : [] +} + +function mergeConfig(existingContent, serverName, mcpConfig, configKey) { + let config = {} + if (existingContent) { + try { + config = JSON.parse(existingContent) + } catch { + config = {} + } + } + + if (!config[configKey]) config[configKey] = {} + config[configKey][serverName] = mcpConfig + + return JSON.stringify(config, null, 2) +} + +export async function mcpInstall(prompts) { + const base = await import('../utils/base.js') + base.debug('mcpInstall') + + const colors = baseLite.colors + const client = prompts.client || 'auto' + const serverName = prompts.name || 'hana-cli' + const dryRun = prompts.dryRun || false + const useGlobal = prompts.global || false + + const mcpServerPath = getMcpServerPath() + if (!existsSync(mcpServerPath)) { + console.error(colors.red(baseLite.bundle.getText("mcpServerInstallNotBuilt"))) + console.error(colors.yellow(` cd mcp-server && npm run build`)) + return base.end() + } + + const mcpConfig = buildMcpConfig() + const targets = getTargetClients(client, useGlobal) + + console.log(colors.bold(baseLite.bundle.getText("mcpServerInstallHeader"))) + console.log() + console.log(` ${colors.cyan(baseLite.bundle.getText("mcpServerInstallServerPath"))} ${mcpServerPath}`) + console.log(` ${colors.cyan(baseLite.bundle.getText("mcpServerInstallServerName"))} ${serverName}`) + console.log() + + if (dryRun) { + console.log(colors.yellow(baseLite.bundle.getText("mcpServerInstallDryRunHeader"))) + console.log() + + for (const target of targets) { + const preview = { [target.configKey]: { [serverName]: mcpConfig } } + console.log(` ${colors.cyan(target.label)} ${colors.dim(`(${target.configKey})`)}:`) + console.log(` ${baseLite.bundle.getText("mcpServerInstallConfigPath")} ${target.path}`) + console.log(` ${baseLite.bundle.getText("mcpServerInstallConfigExists")} ${existsSync(target.path) ? colors.green('yes') : colors.dim('no')}`) + console.log(colors.dim(JSON.stringify(preview, null, 2).split('\n').map(l => ' ' + l).join('\n'))) + console.log() + } + return base.end() + } + + let installedCount = 0 + for (const target of targets) { + try { + let existingContent = null + if (existsSync(target.path)) { + existingContent = readFileSync(target.path, 'utf-8') + } + + if (client === 'auto' && !existingContent) { + console.log(colors.dim(` ${target.label}: ${baseLite.bundle.getText("mcpServerInstallSkipped")}`)) + continue + } + + const configDir = dirname(target.path) + if (!existsSync(configDir)) { + mkdirSync(configDir, { recursive: true }) + } + + const newContent = mergeConfig(existingContent, serverName, mcpConfig, target.configKey) + writeFileSync(target.path, newContent, 'utf-8') + console.log(colors.green(` ${target.label}: ${baseLite.bundle.getText("mcpServerInstallSuccess")}`)) + console.log(colors.dim(` ${target.path}`)) + installedCount++ + } catch (err) { + console.error(colors.red(` ${target.label}: ${baseLite.bundle.getText("mcpServerInstallFailed")} ${err.message}`)) + } + } + + console.log() + if (installedCount > 0) { + console.log(colors.green(baseLite.bundle.getText("mcpServerInstallComplete", [installedCount]))) + console.log(colors.dim(baseLite.bundle.getText("mcpServerInstallRestart"))) + } else { + console.log(colors.yellow(baseLite.bundle.getText("mcpServerInstallNone"))) + console.log(colors.dim(baseLite.bundle.getText("mcpServerInstallNoneHint"))) + } + + return base.end() +} diff --git a/bin/mcpServerStatus.js b/bin/mcpServerStatus.js new file mode 100644 index 00000000..93a0bcf8 --- /dev/null +++ b/bin/mcpServerStatus.js @@ -0,0 +1,182 @@ +// @ts-check +import * as baseLite from '../utils/base-lite.js' +import { buildDocEpilogue } from '../utils/doc-linker.js' +import { fileURLToPath } from 'url' +import { dirname, join, resolve } from 'path' +import { readFileSync, existsSync } from 'fs' +import { homedir, platform } from 'os' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) + +export const command = 'mcpServerStatus' +export const aliases = ['mcp-status', 'mcpStatus'] +export const describe = baseLite.bundle.getText("mcpServerStatus") +export const builder = (yargs) => yargs.options(baseLite.getBuilder({}, false, false)).wrap(160).example( + 'hana-cli mcpServerStatus', + baseLite.bundle.getText("mcpServerStatusExample") +).epilog(buildDocEpilogue('mcpServerStatus', 'developer-tools', ['mcpServerInstall'])) + +export async function handler(argv) { + const base = await import('../utils/base.js') + base.promptHandler(argv, mcpStatus, {}, false) +} + +function getClientTargets() { + const home = homedir() + const os = platform() + const appData = process.env.APPDATA || join(home, 'AppData', 'Roaming') + + function perOS(win, mac, linux) { + if (os === 'win32') return win + if (os === 'darwin') return mac + return linux + } + + return [ + { + name: 'Claude Desktop', + configKey: 'mcpServers', + path: perOS( + join(appData, 'Claude', 'claude_desktop_config.json'), + join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'), + join(home, '.config', 'Claude', 'claude_desktop_config.json') + ), + }, + { + name: 'Claude Code (user)', + configKey: 'mcpServers', + path: join(home, '.claude.json'), + }, + { + name: 'Claude Code (project)', + configKey: 'mcpServers', + path: join(process.cwd(), '.mcp.json'), + }, + { + name: 'Cursor', + configKey: 'mcpServers', + path: perOS( + join(appData, 'Cursor', 'User', 'globalStorage', 'cursor.mcp', 'settings.json'), + join(home, 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'cursor.mcp', 'settings.json'), + join(home, '.config', 'Cursor', 'User', 'globalStorage', 'cursor.mcp', 'settings.json') + ), + }, + { + name: 'Windsurf', + configKey: 'mcpServers', + path: join(home, '.codeium', 'windsurf', 'mcp_config.json'), + }, + { + name: 'Cline (VS Code)', + configKey: 'mcpServers', + path: perOS( + join(appData, 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json'), + join(home, 'Library', 'Application Support', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json'), + join(home, '.config', 'Code', 'User', 'globalStorage', 'saoudrizwan.claude-dev', 'settings', 'cline_mcp_settings.json') + ), + }, + { + name: 'VS Code (user)', + configKey: 'servers', + path: perOS( + join(appData, 'Code', 'User', 'mcp.json'), + join(home, 'Library', 'Application Support', 'Code', 'User', 'mcp.json'), + join(home, '.config', 'Code', 'User', 'mcp.json') + ), + }, + { + name: 'VS Code (workspace)', + configKey: 'servers', + path: join(process.cwd(), '.vscode', 'mcp.json'), + }, + { + name: 'Continue', + configKey: 'mcpServers', + path: join(home, '.continue', 'config.json'), + }, + { + name: 'Zed', + configKey: 'context_servers', + path: perOS( + join(appData, 'Zed', 'settings.json'), + join(home, '.config', 'zed', 'settings.json'), + join(home, '.config', 'zed', 'settings.json') + ), + }, + ] +} + +function detectHanaCli(serverConfig) { + const cfg = /** @type {any} */ (serverConfig) + if (!cfg) return false + const args = cfg.args || cfg.arguments || [] + if (Array.isArray(args)) { + return args.some(a => String(a).includes('hana-cli-mcp-server') || String(a).includes('mcp-server')) + } + const cmd = cfg.command || cfg.path || '' + return String(cmd).includes('hana-cli-mcp-server') || String(cmd).includes('mcp-server') +} + +export async function mcpStatus() { + const base = await import('../utils/base.js') + base.debug('mcpStatus') + + const colors = baseLite.colors + + const mcpServerPath = resolve(__dirname, '..', 'mcp-server', 'build', 'index.js') + const mcpBuilt = existsSync(mcpServerPath) + + console.log(colors.bold(baseLite.bundle.getText("mcpServerStatusHeader"))) + console.log() + console.log(` ${colors.cyan(baseLite.bundle.getText("mcpServerStatusServerPath"))} ${mcpServerPath}`) + console.log(` ${colors.cyan(baseLite.bundle.getText("mcpServerStatusBuilt"))} ${mcpBuilt ? colors.green('yes') : colors.red('no')}`) + console.log() + + const targets = getClientTargets() + + console.log(colors.bold(baseLite.bundle.getText("mcpServerStatusClients"))) + console.log() + + for (const target of targets) { + const exists = existsSync(target.path) + let configured = false + let configuredName = null + + if (exists) { + try { + const content = JSON.parse(readFileSync(target.path, 'utf-8')) + const serversObj = content[target.configKey] + if (serversObj && typeof serversObj === 'object') { + for (const [serverName, serverConfig] of Object.entries(serversObj)) { + if (detectHanaCli(serverConfig)) { + configured = true + configuredName = serverName + break + } + } + } + } catch { + // Parse error + } + } + + const statusIcon = configured ? colors.green('●') : (exists ? colors.dim('○') : colors.dim('–')) + const statusText = configured + ? colors.green(`${baseLite.bundle.getText("mcpServerStatusConfigured")} (${configuredName})`) + : (exists ? colors.dim(baseLite.bundle.getText("mcpServerStatusNotConfigured")) : colors.dim(baseLite.bundle.getText("mcpServerStatusNotFound"))) + + console.log(` ${statusIcon} ${colors.cyan(target.name)}`) + console.log(` ${statusText}`) + console.log(` ${colors.dim(target.path)}`) + console.log() + } + + if (!mcpBuilt) { + console.log(colors.yellow(baseLite.bundle.getText("mcpServerStatusBuildHint"))) + console.log(colors.dim(' cd mcp-server && npm run build')) + console.log() + } + + return base.end() +} diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index af759ad5..83f27a9f 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -182,6 +182,8 @@ export default withMermaid( { text: 'Help Documentation', link: '/02-commands/developer-tools/help-docu' }, { text: 'HDBSQL', link: '/02-commands/developer-tools/hdbsql' }, { text: 'Issue', link: '/02-commands/developer-tools/issue' }, + { text: 'MCP Server Install', link: '/02-commands/developer-tools/mcp-server-install' }, + { text: 'MCP Server Status', link: '/02-commands/developer-tools/mcp-server-status' }, { text: 'Open Change Log', link: '/02-commands/developer-tools/open-change-log' }, { text: 'Open README', link: '/02-commands/developer-tools/open-read-me' }, { text: 'Query Simple', link: '/02-commands/developer-tools/query-simple' }, diff --git a/docs/02-commands/developer-tools/mcp-server-install.md b/docs/02-commands/developer-tools/mcp-server-install.md new file mode 100644 index 00000000..7ced25be --- /dev/null +++ b/docs/02-commands/developer-tools/mcp-server-install.md @@ -0,0 +1,207 @@ +# mcpServerInstall + +> Command: `mcpServerInstall` +> Category: **Developer Tools** +> Status: Production Ready + +## Description + +Install the hana-cli MCP server configuration into AI assistant clients. This command writes the necessary JSON configuration so that Claude Desktop, Claude Code, Cursor, Windsurf, Cline, VS Code, Continue, Zed, or other MCP-compatible tools can discover and use all hana-cli commands as MCP tools. + +The command resolves the absolute path to the MCP server entry point and your Node.js executable, then merges the configuration into the target client's settings file. + +## Syntax + +```bash +hana-cli mcpServerInstall [options] +``` + +## Aliases + +- `mcp` +- `mcpInstall` +- `mcp-install` + +## Command Diagram + +```mermaid +graph TD + Start([hana-cli mcp]) --> CheckBuild{MCP Server Built?} + CheckBuild -->|No| Error([Error: Run npm run build]) + CheckBuild -->|Yes| ResolvePath[Resolve Server Path] + ResolvePath --> DetectClient{Client Mode} + DetectClient -->|auto| ScanAll[Scan All Config Paths] + DetectClient -->|specific| TargetOne[Target Specific Client] + ScanAll --> DryRun{Dry Run?} + TargetOne --> DryRun + DryRun -->|Yes| ShowConfig[Display Configuration] + DryRun -->|No| WriteConfig[Write Config Files] + WriteConfig --> Complete([Done - Restart Client]) + ShowConfig --> Complete + + style Start fill:#0092d1 + style Complete fill:#2ecc71 + style Error fill:#e74c3c +``` + +## Parameters + +| Option | Alias | Type | Default | Description | +|--------|-------|------|---------|-------------| +| `--client` | `-c` | string | `auto` | Target client: `claude-desktop`, `claude-code`, `cursor`, `windsurf`, `cline`, `vscode`, `continue`, `zed`, or `auto` | +| `--name` | `-n` | string | `hana-cli` | Server name in the MCP configuration | +| `--dryRun` | `--dr` | boolean | `false` | Show what would be written without making changes | +| `--global` | `-g` | boolean | `false` | Install globally (user-level) instead of project-level | + +### Client Configuration Paths + +| Client | Config Key | Windows | macOS | Linux | +| ------ | ---------- | ------- | ----- | ----- | +| Claude Desktop | `mcpServers` | `%APPDATA%/Claude/claude_desktop_config.json` | `~/Library/Application Support/Claude/claude_desktop_config.json` | `~/.config/Claude/claude_desktop_config.json` | +| Claude Code (project) | `mcpServers` | `.mcp.json` | `.mcp.json` | `.mcp.json` | +| Claude Code (user) | `mcpServers` | `~/.claude.json` | `~/.claude.json` | `~/.claude.json` | +| Cursor | `mcpServers` | `%APPDATA%/Cursor/User/globalStorage/cursor.mcp/settings.json` | `~/Library/Application Support/Cursor/User/globalStorage/cursor.mcp/settings.json` | `~/.config/Cursor/User/globalStorage/cursor.mcp/settings.json` | +| Windsurf | `mcpServers` | `~/.codeium/windsurf/mcp_config.json` | `~/.codeium/windsurf/mcp_config.json` | `~/.codeium/windsurf/mcp_config.json` | +| Cline (VS Code) | `mcpServers` | `%APPDATA%/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` | `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` | `~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json` | +| VS Code (workspace) | `servers` | `.vscode/mcp.json` | `.vscode/mcp.json` | `.vscode/mcp.json` | +| VS Code (user) | `servers` | `%APPDATA%/Code/User/mcp.json` | `~/Library/Application Support/Code/User/mcp.json` | `~/.config/Code/User/mcp.json` | +| Continue | `mcpServers` | `~/.continue/config.json` | `~/.continue/config.json` | `~/.continue/config.json` | +| Zed | `context_servers` | `%APPDATA%/Zed/settings.json` | `~/.config/zed/settings.json` | `~/.config/zed/settings.json` | + +::: tip Config Key Differences +Most clients use the `mcpServers` key. VS Code uses `servers` in a dedicated `mcp.json` file. Zed uses `context_servers` in its `settings.json`. The install command handles these differences automatically. +::: + +### Auto Mode Behavior + +When `--client` is `auto` (the default), the command scans all known config paths but only writes to files that already exist. This prevents creating config files for tools the user hasn't installed. Use `--client` to explicitly target a specific client. + +## Examples + +### Preview Configuration + +```bash +hana-cli mcp --dry-run +``` + +Shows the JSON configuration that would be written and which client config files exist on your system. + +### Install for Claude Desktop + +```bash +hana-cli mcp --client claude-desktop +``` + +Writes the MCP server entry into the Claude Desktop configuration file. + +### Install Globally for Claude Code + +```bash +hana-cli mcp --client claude-code --global +``` + +Writes to `~/.claude/settings.json` so the MCP server is available in all projects. + +### Install with Custom Server Name + +```bash +hana-cli mcp --client claude-code --name my-hana-server +``` + +Uses `my-hana-server` as the key in the `mcpServers` configuration instead of the default `hana-cli`. + +### Install for Windsurf + +```bash +hana-cli mcp --client windsurf +``` + +Writes the MCP server entry into Windsurf's configuration file. + +### Install for VS Code + +```bash +hana-cli mcp --client vscode +``` + +Writes the MCP server entry into the workspace-level `.vscode/mcp.json`. Use `--global` to write to the user-level VS Code config instead. + +### Install for Zed + +```bash +hana-cli mcp --client zed +``` + +Writes using Zed's `context_servers` key in its settings file. + +## Prerequisites + +The MCP server must be built before installation: + +```bash +cd mcp-server +npm install +npm run build +``` + +## What Gets Written + +The command adds/updates a single entry in the client's MCP configuration. All entries include `"type": "stdio"` for broad client compatibility. Most clients use the `mcpServers` key: + +```json +{ + "mcpServers": { + "hana-cli": { + "type": "stdio", + "command": "/path/to/node", + "args": ["/path/to/mcp-server/build/index.js"] + } + } +} +``` + +VS Code uses the `servers` key in a dedicated `mcp.json`: + +```json +{ + "servers": { + "hana-cli": { + "type": "stdio", + "command": "/path/to/node", + "args": ["/path/to/mcp-server/build/index.js"] + } + } +} +``` + +Zed uses `context_servers` in its `settings.json`: + +```json +{ + "context_servers": { + "hana-cli": { + "type": "stdio", + "command": "/path/to/node", + "args": ["/path/to/mcp-server/build/index.js"] + } + } +} +``` + +::: info Claude Code File Locations +Claude Code reads MCP servers from `.mcp.json` (project root, team-shared) or `~/.claude.json` (user scope), **not** from `.claude/settings.json`. The install command writes to the correct location automatically. +::: + +Existing entries in the configuration are preserved — only the `hana-cli` key is added or updated. + +## Related Commands + +See the [Commands Reference](../all-commands.md) for other commands in this category. + +## See Also + +- [Category: Developer Tools](..) +- [All Commands A-Z](../all-commands.md) +- [mcpServerStatus](./mcp-server-status.md) - Check MCP server installation status +- [MCP Integration Guide](../../03-features/mcp-integration.md) - Full MCP feature documentation +- [helpDocu](./help-docu.md) - Open documentation in browser diff --git a/docs/02-commands/developer-tools/mcp-server-status.md b/docs/02-commands/developer-tools/mcp-server-status.md new file mode 100644 index 00000000..bc7c58b9 --- /dev/null +++ b/docs/02-commands/developer-tools/mcp-server-status.md @@ -0,0 +1,139 @@ +# mcpServerStatus + +> Command: `mcpServerStatus` +> Category: **Developer Tools** +> Status: Production Ready + +## Description + +Check the MCP server installation status across all supported AI assistant clients. This command scans known configuration paths for Claude Desktop, Claude Code, Cursor, Windsurf, Cline, VS Code, Continue, and Zed to report whether the hana-cli MCP server is configured in each. + +## Syntax + +```bash +hana-cli mcpServerStatus +``` + +## Aliases + +- `mcp-status` +- `mcpStatus` + +## Command Diagram + +```mermaid +graph TD + Start([hana-cli mcp-status]) --> CheckBuild{MCP Server Built?} + CheckBuild --> ScanClients[Scan All Client Configs] + ScanClients --> Claude[Claude Desktop] + ScanClients --> CodeUser[Claude Code - User] + ScanClients --> CodeProject[Claude Code - Project] + ScanClients --> Cursor[Cursor] + ScanClients --> Windsurf[Windsurf] + ScanClients --> Cline[Cline] + ScanClients --> VSCode[VS Code] + ScanClients --> Continue[Continue] + ScanClients --> Zed[Zed] + Claude --> Report[Display Status Report] + CodeUser --> Report + CodeProject --> Report + Cursor --> Report + Windsurf --> Report + Cline --> Report + VSCode --> Report + Continue --> Report + Zed --> Report + Report --> Complete([Complete]) + + style Start fill:#0092d1 + style Complete fill:#2ecc71 +``` + +## Parameters + +This command does not accept any command-specific parameters beyond the standard troubleshooting options. + +### Troubleshooting + +| Option | Alias | Type | Default | Description | +|--------|-------|------|---------|-------------| +| `--disableVerbose` | `--quiet` | boolean | `false` | Disable verbose output | +| `--debug` | `-d` | boolean | `false` | Debug hana-cli itself | + +## Examples + +### Basic Usage + +```bash +hana-cli mcp-status +``` + +Outputs a status report like: + +``` +SAP HANA CLI - MCP Server Status + + Server path: /path/to/mcp-server/build/index.js + Built: yes + +Client Configuration Status: + + ● Claude Code (project) + configured (hana-cli) + /project/.mcp.json + + ○ Claude Code (user) + config exists, not configured + ~/.claude.json + + – Claude Desktop + config not found + ~/.config/Claude/claude_desktop_config.json + + – Cursor + config not found + ~/.config/Cursor/User/globalStorage/cursor.mcp/settings.json + + – Windsurf + config not found + ~/.codeium/windsurf/mcp_config.json + + – Cline (VS Code) + config not found + ~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json + + ● VS Code (workspace) + configured (hana-cli) + /project/.vscode/mcp.json + + – VS Code (user) + config not found + ~/.config/Code/User/mcp.json + + – Continue + config not found + ~/.continue/config.json + + – Zed + config not found + ~/.config/zed/settings.json +``` + +### Status Icons + +| Icon | Meaning | +|------|---------| +| `●` (green) | Configured — MCP server entry found | +| `○` (dim) | Config file exists but MCP server not configured | +| `–` (dim) | Config file not found (client likely not installed) | + +## Related Commands + +See the [Commands Reference](../all-commands.md) for other commands in this category. + +## See Also + +- [Category: Developer Tools](..) +- [All Commands A-Z](../all-commands.md) +- [mcpServerInstall](./mcp-server-install.md) - Install MCP server configuration +- [MCP Integration Guide](../../03-features/mcp-integration.md) - Full MCP feature documentation diff --git a/docs/03-features/mcp-integration.md b/docs/03-features/mcp-integration.md index 42f7ad14..fbd3f07b 100644 --- a/docs/03-features/mcp-integration.md +++ b/docs/03-features/mcp-integration.md @@ -18,29 +18,67 @@ The Model Context Protocol enables AI assistants to interact with external tools ## Quick Start -### Installation +### Option 1: Auto-Configure (Recommended) + +If you already have `hana-cli` installed, use the built-in install command: + +```bash +# Auto-detect installed clients and configure them +hana-cli mcp + +# Preview what would be written without making changes +hana-cli mcp --dry-run + +# Target a specific client +hana-cli mcp --client claude-desktop +hana-cli mcp --client claude-code --global +hana-cli mcp --client cursor + +# Check configuration status across all clients +hana-cli mcp-status +``` + +See [mcpServerInstall](../02-commands/developer-tools/mcp-server-install.md) for full documentation. + +### Option 2: npx (No Installation) + +Run the MCP server directly via npx without installing anything: ```bash -cd mcp-server -npm install -npm run build +npx -y -p hana-cli hana-cli-mcp +``` + +Use this in your IDE's MCP configuration: + +```json +{ + "mcpServers": { + "hana-cli": { + "type": "stdio", + "command": "npx", + "args": ["-y", "-p", "hana-cli", "hana-cli-mcp"] + } + } +} ``` -### Configuration +### Option 3: MCP Registry + +The MCP server is published to the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.SAP-samples/hana-cli`. AI clients and aggregators that support the MCP Registry can discover and install it automatically. -Add to your IDE's MCP settings: +### Manual Configuration -**VS Code with Claude Dev or Cline:** +You can also point directly to a local build: ```json { "mcpServers": { "hana-cli": { + "type": "stdio", "command": "node", "args": [ - "D:/projects/hana-developer-cli-tool-example/mcp-server/build/index.js" - ], - "env": {} + "/absolute/path/to/mcp-server/build/index.js" + ] } } } @@ -66,7 +104,7 @@ hana_compareSchema Compare database schemas hana_inspectTable View table structure and metadata ``` -Command aliases are also available (e.g., `hana_s` for status, `hana_imp` for import). +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. ### 2. Discovery Tools @@ -79,7 +117,7 @@ Input: "find duplicate rows in my customer table" Output: Top 5 matching commands with confidence scores and parameter templates ``` -**`hana_smart_search`** - Search across commands, workflows, examples, and presets: +**`hana_search`** - Search across commands, workflows, examples, presets, and documentation: ```text Input: "csv import" @@ -106,7 +144,7 @@ Output: Recommended parameters for comprehensive analysis ### 4. Workflows -**`hana_execute_workflow`** - Run pre-built multi-step workflows: +**`hana_workflows`** - List available multi-step workflow templates: ```text Available workflows: @@ -118,9 +156,11 @@ Available workflows: ... and 15+ more ``` +**`hana_workflow_by_id`** - Get detailed steps for a specific workflow. + ### 5. Documentation Access -**`hana_search_docs`** - Full-text search across all documentation: +**`hana_get_doc`** - Retrieve full content of a documentation page found via search: ```text Input: "import csv with errors" @@ -129,8 +169,6 @@ Output: Top 10 relevant documentation pages with excerpts **`hana_get_doc`** - Retrieve complete documentation page content. -**`hana_list_doc_categories`** - Browse documentation by category. - ## Use Cases ### Database Exploration @@ -181,22 +219,25 @@ The AI will: ## Advanced Features -### Workflow Execution +### Workflow Templates -Run complex multi-step workflows: +Browse and use pre-built multi-step workflows: ```text -hana_preview_workflow - Preview workflow steps before execution -hana_execute_workflow - Execute complete workflow with automated steps +hana_workflows - List available workflow templates +hana_workflow_by_id - Get detailed steps for a specific workflow +hana_search_workflows - Search workflows by tag or purpose ``` +The AI agent orchestrates the individual steps — workflow templates provide the sequence and recommended parameters, while the LLM handles execution and decision-making between steps. + ### Result Interpretation `hana_interpret_result` - AI-friendly analysis and insights from command output, automatically providing context-aware explanations. ### Conversation Templates -`hana_get_conversation_template` - Pre-built dialogue flows for guided troubleshooting and task completion. +`hana_conversation_templates` / `hana_get_template` - Pre-built dialogue flows for guided troubleshooting and task completion. ## Connection Management diff --git a/docs/03-features/mcp/server-usage.md b/docs/03-features/mcp/server-usage.md index f2ae2e8e..37c71af9 100644 --- a/docs/03-features/mcp/server-usage.md +++ b/docs/03-features/mcp/server-usage.md @@ -4,7 +4,27 @@ How to run and use the MCP (Model Context Protocol) server with HANA CLI. ## Quick Start -### Installation +### Easiest: Auto-Configure + +```bash +# Auto-detect installed AI clients and configure them +hana-cli mcp + +# Or target a specific client +hana-cli mcp --client claude-desktop +hana-cli mcp --client claude-code --global +hana-cli mcp --client cursor +``` + +### Via npx (No Local Install) + +Run the MCP server via npx — no global install or build step needed: + +```bash +npx -y -p hana-cli hana-cli-mcp +``` + +### From Source (Development) ```bash # Navigate to mcp-server directory @@ -30,6 +50,10 @@ DEBUG=hana-cli:* node build/index.js NODE_OPTIONS="--max-old-space-size=4096" node build/index.js ``` +### MCP Registry + +The server is published to the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.SAP-samples/hana-cli`. AI clients that support the MCP Registry can discover and install it automatically. + ## How It Works The MCP server: @@ -61,49 +85,46 @@ The MCP server exposes 150+ HANA CLI tools: { "mcpServers": { "hana-cli": { - "command": "node", - "args": ["/path/to/mcp-server/build/index.js"], - "env": { - "DEBUG": "hana-cli:*" - } + "command": "npx", + "args": ["-y", "-p", "hana-cli", "hana-cli-mcp"] } } } ``` +Or run `hana-cli mcp --client claude-desktop` to configure automatically. + 1. Restart Claude Desktop 1. Ask Claude questions about your HANA database ### With VSCode (GitHub Copilot) -1. **Build the MCP Server** - - ```bash - cd mcp-server - npm install - npm run build - ``` - -1. **Build the Documentation Index** +1. **Configure VSCode MCP Settings** - The MCP server includes documentation search tools. Build the index so they work: + Edit your VSCode MCP configuration at `~/.config/Code/User/mcp.json` (or find it in your User settings): - ```bash - npm run build:docs-index + ```json + { + "servers": { + "io.github.SAP-samples/hana-cli": { + "type": "stdio", + "command": "npx", + "args": ["-y", "-p", "hana-cli", "hana-cli-mcp"] + } + } + } ``` -1. **Configure VSCode MCP Settings** - - Edit your VSCode MCP configuration at `~/.config/Code/User/mcp.json` (or find it in your User settings): + Or if you have a local build, point directly to it: ```json { "servers": { - "io.github.SAP-samples/hana-cli-mcp-server": { + "io.github.SAP-samples/hana-cli": { "type": "stdio", "command": "node", "args": [ - "D:/projects/hana-developer-cli-tool-example/mcp-server/build/index.js" + "/absolute/path/to/mcp-server/build/index.js" ] } } @@ -112,10 +133,8 @@ The MCP server exposes 150+ HANA CLI tools: **Important Notes:** - - Replace `D:/projects/hana-developer-cli-tool-example` with your actual project path - - Use absolute paths (not relative paths) + - Use absolute paths when pointing to a local build - Use forward slashes `/` even on Windows - - The server name `io.github.SAP-samples/hana-cli-mcp-server` is the standard naming convention and ensures proper tool discovery 1. **Restart VSCode** @@ -142,7 +161,7 @@ The MCP server exposes 150+ HANA CLI tools: - "Compare data between two tables" - Copilot will use the `hana_*` tools to answer -**Tip:** Use `hana_search_docs` tool to search the full documentation for answers to complex questions. +**Tip:** Use `hana_search` tool to search the full documentation for answers to complex questions. ### With Custom AI Agents diff --git a/docs/05-development/mcp-server/advanced-features.md b/docs/05-development/mcp-server/advanced-features.md index 59b91023..c326374e 100644 --- a/docs/05-development/mcp-server/advanced-features.md +++ b/docs/05-development/mcp-server/advanced-features.md @@ -2,14 +2,12 @@ Sophisticated capabilities for complex workflows and understanding results. -## Workflow Execution System +## Workflow Templates -Automated execution of multi-step workflows with parameter substitution and result tracking. +Pre-built sequences of commands that work together to accomplish a goal. The AI agent orchestrates execution — workflow templates provide the sequence and recommended parameters, while the LLM handles execution and decision-making between steps. ### What Are Workflows? -Pre-built sequences of commands that work together to accomplish a goal. - **Example Workflow - Data Quality Check:** ```bash @@ -24,48 +22,36 @@ Pre-built sequences of commands that work together to accomplish a goal. 5. Generate report ``` -### Executing a Workflow +### Browsing Workflows + +**MCP Tool:** `hana_workflows` + +Returns a list of all available workflow templates with descriptions and step counts. -**MCP Tool:** `hana_execute_workflow` +**MCP Tool:** `hana_workflow_by_id` ```json { - "workflowId": "data-quality-check", - "parameters": { - "schema": "SALES", - "table": "CUSTOMERS", - "stopOnError": false - } + "id": "data-quality-check" } ``` -**Output includes:** - -- Results from each step -- Execution time per step -- Any errors encountered -- Summary and recommendations +**Returns:** -### Previewing Before Execution +- All steps in order with commands and parameters +- Parameter templates using `` substitution +- Expected outcomes per step +- Tips and best practices -**MCP Tool:** `hana_preview_workflow` +**MCP Tool:** `hana_search_workflows` ```json { - "workflowId": "data-quality-check", - "parameters": { - "schema": "SALES", - "table": "CUSTOMERS" - } + "tag": "performance" } ``` -**Shows:** - -- All steps in order -- Parameters for each step -- Expected execution -- No actual commands run +Search workflows by tag (e.g., `data-quality`, `performance`, `security`, `backup`, `migration`). ### Built-In Workflows @@ -139,7 +125,7 @@ The MCP Server includes 20+ professional workflows: ### Parameter Substitution -Workflows support parameter templates using ``: +Workflow templates use parameter placeholders with `` syntax. When the AI agent executes each step, it substitutes the actual values: ```json { @@ -176,54 +162,11 @@ When executing, provide actual values: } ``` -Parameters are automatically substituted in each step. +The AI agent substitutes actual values when calling each tool in sequence. ### Error Handling in Workflows -Control how workflows handle errors: - -**Continue on errors:** - -```json -{ - "workflowId": "data-quality-check", - "parameters": { ... }, - "stopOnError": false -} -``` - -**Stop on first error:** - -```json -{ - "workflowId": "data-quality-check", - "parameters": { ... }, - "stopOnError": true -} -``` - -**Output shows:** - -```json -{ - "steps": [ - { - "step": 1, - "command": "dataProfile", - "status": "success", - "duration": 2.5 - }, - { - "step": 2, - "command": "duplicateDetection", - "status": "success", - "duration": 1.8 - } - ], - "totalDuration": 4.3, - "errors": [] -} -``` +The AI agent decides how to handle errors between steps — it can skip failed steps, retry with different parameters, or stop and report issues. Workflow templates include guidance on which steps are critical vs. optional. ## Result Interpretation (`hana_interpret_result`) @@ -405,11 +348,12 @@ Access all 279 project documentation pages directly from MCP. ### Searching Documentation -**MCP Tool:** `hana_search_docs` +**MCP Tool:** `hana_search` ```json { "query": "import CSV data", + "scope": "docs", "category": "commands", "docType": "command", "limit": 5 @@ -454,13 +398,9 @@ Access all 279 project documentation pages directly from MCP. ### Finding Documentation by Category -**MCP Tool:** `hana_list_doc_categories` +**MCP Resource:** `hana://docs/categories` -Returns: - -- All 9+ categories -- Number of documents per category -- Sample documents from each +Documentation categories are available as an MCP resource (not a tool), keeping the tool list concise while still providing browsable metadata. **Categories:** @@ -477,7 +417,7 @@ Returns: ```bash 1. User: "How do I import a CSV file?" ↓ -2. System: Calls hana_search_docs +2. System: Calls hana_search ↓ 3. Returns: Top 5 import-related docs ↓ @@ -495,10 +435,10 @@ Returns: ### Scenario 1: Complete Data Migration ```bash -1. Preview: hana_preview_workflow("schema-migration") +1. Browse: hana_workflow_by_id("schema-migration") ↓ -2. Execute: hana_execute_workflow("schema-migration") - - Validate source +2. Execute steps guided by the workflow template: + - Validate source schema - Generate DDL - Test migration - Compare schemas @@ -511,19 +451,19 @@ Returns: ### Scenario 2: Performance Optimization ```bash -1. Get baseline: hana_execute_workflow("performance-baseline") +1. Get workflow: hana_workflow_by_id("performance-baseline") ↓ -2. Analyze: hana_interpret_result("memoryAnalysis", baseline) +2. Execute baseline steps: hana_healthCheck, hana_memoryAnalysis, etc. ↓ -3. Find issues: hana_execute_workflow("performance-diagnosis") +3. Analyze: hana_interpret_result("memoryAnalysis", baseline) ↓ -4. Get recommendations: from diagnosed issues +4. Get diagnosis workflow: hana_workflow_by_id("performance-diagnosis") ↓ -5. Implement optimizations +5. Execute diagnosis steps and get recommendations ↓ -6. Re-run baseline: hana_execute_workflow("performance-baseline") +6. Implement optimizations ↓ -7. Compare: baseline before vs. after +7. Re-run baseline steps and compare before vs. after ``` ### Scenario 3: Data Quality Assurance @@ -535,40 +475,33 @@ Returns: ↓ 3. Find issues: recommendations and concerns ↓ -4. Execute: hana_execute_workflow("data-cleansing") +4. Get workflow: hana_workflow_by_id("data-cleansing") + ↓ +5. Execute cleansing steps: - Identify issues - Clean data - Validate ↓ -5. Verify: hana_dataValidator(table) +6. Verify: hana_dataValidator(table) ↓ -6. Report: Quality metrics and changes +7. Report: Quality metrics and changes ``` ## Best Practices -### 1. Always Preview Before Executing +### 1. Review Workflow Templates First -```json -// Step 1: Preview -hana_preview_workflow("data-migration", parameters) +```bash +# Step 1: Browse the workflow +hana_workflow_by_id("data-migration") -// Step 2: Review and confirm -// Step 3: Execute -hana_execute_workflow("data-migration", parameters) +# Step 2: Review the steps and parameters +# Step 3: Execute each step, adapting as needed ``` -### 2. Use Error Handling Wisely +### 2. Handle Errors Between Steps -```json -{ - "stopOnError": true // For critical workflows -} - -{ - "stopOnError": false // For bulk operations with retry -} -``` +The AI agent should check results between workflow steps and decide whether to continue, retry, or stop based on the outcome. ### 3. Interpret All Results diff --git a/docs/05-development/mcp-server/discovery-tools.md b/docs/05-development/mcp-server/discovery-tools.md index 5130ba65..720e67ea 100644 --- a/docs/05-development/mcp-server/discovery-tools.md +++ b/docs/05-development/mcp-server/discovery-tools.md @@ -68,7 +68,7 @@ The recommendation system matches your intent to commands using: | "Verify connection" | `hana_status`, `hana_healthCheck` | | "Find missing columns" | `hana_compareSchema`, `hana_inspectTable` | -## Smart Search (`hana_smart_search`) +## Consolidated Search (`hana_search`) Comprehensive search across all resources in the MCP Server. diff --git a/docs/05-development/mcp-server/docs-search.md b/docs/05-development/mcp-server/docs-search.md index 7a0f4a91..e3f166f4 100644 --- a/docs/05-development/mcp-server/docs-search.md +++ b/docs/05-development/mcp-server/docs-search.md @@ -91,7 +91,7 @@ The MCP Server includes a comprehensive documentation index of all project docum ## MCP Tools for Documentation Access -### 1. Search Documentation (`hana_search_docs`) +### 1. Search Documentation (`hana_search`) Fast full-text search across all documentation. @@ -209,44 +209,13 @@ Retrieve full content of a specific documentation page. } ``` -### 3. List Documentation Categories (`hana_list_doc_categories`) +### 3. Browse Documentation Categories (MCP Resource) -Browse available documentation categories with sample documents. +Documentation categories are now available as an MCP resource at `hana://docs/categories` rather than as a tool, keeping the tool list concise. -**Parameters:** None - -**Returns:** - -```json -{ - "categories": [ - { - "name": "Getting Started", - "path": "01-getting-started", - "documentCount": 5, - "description": "Installation, setup, and quick start guides", - "samples": [ - { "title": "Installation", "path": "01-getting-started/installation.md" }, - { "title": "Configuration", "path": "01-getting-started/configuration.md" } - ] - }, - { - "name": "Commands", - "path": "02-commands", - "documentCount": 82, - "description": "Complete command reference and guides", - "samples": [ - { "title": "All Commands", "path": "02-commands/all-commands.md" }, - { "title": "Import", "path": "02-commands/data-tools/import.md" } - ] - } - ], - "total": 9, - "documentCount": 279 -} -``` +Similarly, documentation statistics are available as a resource at `hana://docs/statistics`. -### 4. Get Documentation Statistics (`hana_docs_stats`) +### 4. Consolidated Search (`hana_search`) Overview of documentation status and metrics. @@ -324,7 +293,7 @@ Document 3: "CSV File Format" ```typescript // Step 1: Search -const results = await mcpTool('hana_search_docs', { +const results = await mcpTool('hana_search', { query: 'how to connect to HANA database', limit: 5 }); @@ -343,13 +312,13 @@ const params = fullDoc.content.match(/## Parameters/i); ```typescript // Step 1: List categories -const categories = await mcpTool('hana_list_doc_categories'); +const categories = await mcpResource('hana://docs/categories'); // Step 2: Find category of interest const commands = categories.find(c => c.name === 'Commands'); // Step 3: Search within category -const results = await mcpTool('hana_search_docs', { +const results = await mcpTool('hana_search', { query: 'data validation', category: 'commands' }); @@ -364,7 +333,7 @@ for (const result of results) { ```typescript // Step 1: Search troubleshooting docs -const issues = await mcpTool('hana_search_docs', { +const issues = await mcpTool('hana_search', { query: 'connection timeout', category: 'troubleshooting', limit: 5 @@ -383,7 +352,7 @@ const solutions = guide.content.match(/## Solution/gi); ```typescript // Step 1: Get command examples -const examples = await mcpTool('hana_search_docs', { +const examples = await mcpTool('hana_search', { query: 'import command', docType: 'command', limit: 1 @@ -431,7 +400,7 @@ cd mcp-server npm run build # Restart MCP in your client -# Test with hana_search_docs +# Test with hana_search ``` ### Index Structure @@ -465,7 +434,7 @@ npm run build ```bash User: "How do I import data?" -Agent: Calls hana_search_docs("import data") +Agent: Calls hana_search("import data") System: Returns top 5 results with excerpts diff --git a/docs/05-development/mcp-server/features.md b/docs/05-development/mcp-server/features.md index 76b8a13f..200f0ef6 100644 --- a/docs/05-development/mcp-server/features.md +++ b/docs/05-development/mcp-server/features.md @@ -32,7 +32,7 @@ hana_duplicateDetection # Find duplicate rows hana_compareSchema # Compare database schemas ``` -All command aliases are also available (e.g., `hana_s` for status, `hana_imp` for import). +All command aliases still resolve at call time (e.g., `hana_s` for status, `hana_imp` for import), but they are not registered as separate tools to keep the tool list concise. ### 2. Discovery Tools @@ -69,16 +69,18 @@ Recommendations: Reason: Can check for duplicate key violations ``` -#### Smart Search (`hana_smart_search`) +#### Smart Search (`hana_search`) -Comprehensive search across all resources: +Consolidated search across all resources: **Searches:** -- Command names and descriptions -- Workflow templates by name/purpose -- Usage examples by scenario -- Parameter presets by use case +- Documentation pages (scope: `docs`) +- Command names and descriptions (scope: `commands`) +- Workflow templates by name/purpose (scope: `workflows`) +- Usage examples by scenario (scope: `examples`) +- Parameter presets by use case (scope: `presets`) +- All of the above (scope: `all`, the default) **Features:** @@ -166,16 +168,16 @@ Pre-configured parameter combinations for common use cases. ### 4. Workflows and Tasks -#### Workflow Execution (`hana_execute_workflow`, `hana_preview_workflow`) +#### Workflow Templates (`hana_workflows`, `hana_workflow_by_id`, `hana_search_workflows`) -Execute multi-step workflow sequences with automatic parameter substitution. +Browse and use multi-step workflow templates. The AI agent orchestrates execution — workflow templates provide the sequence and recommended parameters. **Features:** -- Parameter validation before execution -- Step result tracking -- Error handling with optional continuation -- Preview mode to see what will execute +- Browse all available workflows +- Get detailed steps for a specific workflow +- Search workflows by tag or purpose +- Parameter templates with `` substitution **Example Workflow - Data Quality Check:** @@ -293,9 +295,9 @@ AI-friendly analysis and insights from command results. } ``` -### 6. Documentation Search (`hana_search_docs`, `hana_get_doc`, `hana_list_doc_categories`) +### 6. Documentation Search (`hana_search`, `hana_get_doc`) -Access to all 279 project documentation pages with full-text search. +Access to all 279 project documentation pages with full-text search via the consolidated `hana_search` tool (use `scope: "docs"`). Documentation categories and statistics are available as MCP resources. **Features:** @@ -349,11 +351,12 @@ The MCP Server was built in three phases, each adding significant capabilities: ### Phase 3: Advanced Features -- Workflow execution system +- Workflow template system (browse, search, LLM-orchestrated execution) - Result interpretation engine -- Smart search system +- Consolidated search system (`hana_search`) - Conversation templates - Integrated documentation +- Static knowledge moved to MCP resources ## Context-Aware Guidance diff --git a/docs/05-development/mcp-server/implementation-phases.md b/docs/05-development/mcp-server/implementation-phases.md index c14695ca..7d700eb1 100644 --- a/docs/05-development/mcp-server/implementation-phases.md +++ b/docs/05-development/mcp-server/implementation-phases.md @@ -283,21 +283,21 @@ Context-sensitive suggestions based on results. ### Phase 3 Features Implemented -#### 1. Workflow Execution System (`hana_execute_workflow`, `hana_preview_workflow`) +#### 1. Workflow Template System (`hana_workflows`, `hana_workflow_by_id`, `hana_search_workflows`) -Automated multi-step command sequences. +Multi-step workflow templates that the AI agent orchestrates. **Files Created:** -- `src/workflow-execution.ts` (230 lines) +- Workflow definitions in `src/tools/content-tools.ts` **Features:** -- Parameter substitution -- Step validation -- Result tracking -- Error handling with options -- Preview mode +- Browse all available workflows +- Get detailed steps for a specific workflow +- Search by tag or purpose +- Parameter templates with `` substitution +- LLM-orchestrated execution (no simulated executor) **Built-in Workflows (20+):** @@ -308,7 +308,7 @@ Automated multi-step command sequences. - data-cleansing (7 steps) - And 15+ more... -**Workflow Structure:** +**Workflow Template Structure:** ```json { @@ -324,23 +324,7 @@ Automated multi-step command sequences. } ``` -**Execution Output:** - -```json -{ - "steps": [ - { - "step": 1, - "command": "dataProfile", - "status": "success", - "duration": 2.5, - "result": {...} - } - ], - "totalDuration": 4.3, - "status": "complete" -} -``` +The AI agent reads the workflow template and executes each step individually, making decisions between steps based on the results. #### 2. Result Interpretation Engine (`hana_interpret_result`) @@ -385,17 +369,17 @@ AI-friendly analysis of command results. } ``` -#### 3. Smart Search System (`hana_smart_search`) +#### 3. Consolidated Search System (`hana_search`) -Comprehensive search across all resources. +Unified search across all resources, replacing the previous separate `hana_smart_search` and `hana_search_docs` tools. **Files Created:** -- `src/smart-search.ts` (320 lines) +- `src/tools/search-tools.ts` **Features:** -- Multi-scope searching (commands, workflows, examples, presets) +- Multi-scope searching (docs, commands, workflows, examples, presets, or all) - Relevance ranking - Result type indicators - Context information @@ -454,21 +438,24 @@ Guided workflows for common tasks. } ``` -#### 5. Documentation Search Integration (4 tools) +#### 5. Documentation Search Integration -Access to 279 documentation pages. +Access to 279 documentation pages via consolidated search and MCP resources. **Files Created:** -- `src/docs-search.ts` (400 lines) +- `src/tools/search-tools.ts` (search handler) - `docs-index.json` (pre-built index) **Tools:** -- `hana_search_docs` - Full-text search +- `hana_search` (scope: `docs`) - Full-text search - `hana_get_doc` - Retrieve full content -- `hana_list_doc_categories` - Browse categories -- `hana_docs_stats` - Index statistics + +**Resources:** + +- `hana://docs/categories` - Browse categories +- `hana://docs/statistics` - Index statistics **Features:** diff --git a/docs/05-development/mcp-server/index.md b/docs/05-development/mcp-server/index.md index c44287bd..f09e2d79 100644 --- a/docs/05-development/mcp-server/index.md +++ b/docs/05-development/mcp-server/index.md @@ -145,7 +145,7 @@ All `hana-cli` commands are exposed as MCP tools with the `hana_` prefix: ### 2. Discovery System - **`hana_recommend`** - Get command suggestions from natural language intent -- **`hana_smart_search`** - Search commands, examples, presets, and workflows +- **`hana_search`** - Search commands, docs, examples, presets, and workflows - **`hana_quickstart`** - Get beginner-friendly first commands - **`hana_conversation_templates`** - Browse pre-built task workflows diff --git a/docs/05-development/mcp-server/prompts-and-resources.md b/docs/05-development/mcp-server/prompts-and-resources.md index f1fb4f95..fb8eb056 100644 --- a/docs/05-development/mcp-server/prompts-and-resources.md +++ b/docs/05-development/mcp-server/prompts-and-resources.md @@ -24,7 +24,7 @@ Instead of searching or guessing: Agent: "I want to import data but I'm not sure how" Traditional (without resources): -- Agent calls hana_search_docs → finds import.md +- Agent calls hana_search → finds import.md - Agent guesses at parameters - Agent tries import (may fail) diff --git a/mcp-server/build/executor.d.ts b/mcp-server/build/executor.d.ts index a4c17c3a..f545b66f 100644 --- a/mcp-server/build/executor.d.ts +++ b/mcp-server/build/executor.d.ts @@ -18,13 +18,6 @@ export interface ExecutionResult { export declare function executeCommand(commandName: string, args?: Record, context?: ConnectionContext): Promise; -/** - * Validates that required environment variables are set for database connection - */ -export declare function validateEnvironment(): { - valid: boolean; - message?: string; -}; /** * Formats execution result for display using the output formatter */ diff --git a/mcp-server/build/executor.d.ts.map b/mcp-server/build/executor.d.ts.map index f403e776..e99b3b1a 100644 --- a/mcp-server/build/executor.d.ts.map +++ b/mcp-server/build/executor.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAK5D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2ND;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAC9B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,eAAe,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA4IpD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAc1E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CA+EtF"} \ No newline at end of file +{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAK5D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2ND;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAC9B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,eAAe,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA4IpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CA+EtF"} \ No newline at end of file diff --git a/mcp-server/build/executor.js b/mcp-server/build/executor.js index df834a9a..84463557 100644 --- a/mcp-server/build/executor.js +++ b/mcp-server/build/executor.js @@ -332,23 +332,6 @@ export async function executeCommand(commandName, args = {}, context) { } }); } -/** - * Validates that required environment variables are set for database connection - */ -export function validateEnvironment() { - // The hana-cli tool uses various connection methods: - // - .env files or default-env.json in the project root - // - Connection parameters passed via CLI (--conn, --user, --password, etc.) - // - Service keys and BTP connections - // - // Most commands don't strictly require these at validation time - // since connection errors are handled at command execution - // - // Some commands like 'version' and 'help' work without any connection - // For now, we'll allow commands to run and let the CLI handle connection validation - // This provides better error messages from the actual command execution - return { valid: true }; -} /** * Formats execution result for display using the output formatter */ diff --git a/mcp-server/build/executor.js.map b/mcp-server/build/executor.js.map index ae71ab77..4d8dc960 100644 --- a/mcp-server/build/executor.js.map +++ b/mcp-server/build/executor.js.map @@ -1 +1 @@ -{"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/mcp-server/build/index.d.ts b/mcp-server/build/index.d.ts index 241fc4cb..75d27556 100644 --- a/mcp-server/build/index.d.ts +++ b/mcp-server/build/index.d.ts @@ -2,14 +2,9 @@ /** * MCP Server for SAP HANA CLI * - * CRITICAL: This file implements the Model Context Protocol (MCP) server. - * MCP communicates via JSON-RPC over STDIO. All logging MUST use console.error() - * to write to stderr, never console.log() which writes to stdout. - * - * Any non-JSON output to stdout will break the protocol and cause errors like: - * "Failed to parse message: ..." - * - * Use console.error() for all logging throughout this file and in modules it imports. + * CRITICAL: MCP communicates via JSON-RPC over STDIO. All logging MUST use + * console.error() (stderr), never console.log() (stdout). Any non-JSON output + * to stdout will break the protocol. */ export {}; //# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/mcp-server/build/index.d.ts.map b/mcp-server/build/index.d.ts.map index d57cb0c4..fb5fe9d5 100644 --- a/mcp-server/build/index.d.ts.map +++ b/mcp-server/build/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;GAWG"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG"} \ No newline at end of file diff --git a/mcp-server/build/index.js b/mcp-server/build/index.js index 48523d35..c1bd8782 100644 --- a/mcp-server/build/index.js +++ b/mcp-server/build/index.js @@ -2,47 +2,27 @@ /** * MCP Server for SAP HANA CLI * - * CRITICAL: This file implements the Model Context Protocol (MCP) server. - * MCP communicates via JSON-RPC over STDIO. All logging MUST use console.error() - * to write to stderr, never console.log() which writes to stdout. - * - * Any non-JSON output to stdout will break the protocol and cause errors like: - * "Failed to parse message: ..." - * - * Use console.error() for all logging throughout this file and in modules it imports. + * CRITICAL: MCP communicates via JSON-RPC over STDIO. All logging MUST use + * console.error() (stderr), never console.log() (stdout). Any non-JSON output + * to stdout will break the protocol. */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; -import { fileURLToPath, pathToFileURL } from 'url'; +import { pathToFileURL } from 'url'; import { dirname, join } from 'path'; -import { extractCommandInfo } from './command-parser.js'; -import { executeCommand, formatResult, validateEnvironment } from './executor.js'; -import { CATEGORIES, searchCommandsByTag, getCommandsInCategory, getAllWorkflows, searchWorkflowsByTag, getWorkflowById } from './command-metadata.js'; -import { getCommandExamples, getCommandPresets, hasExamples, hasPresets, getCommandsWithExamples, getCommandsWithPresets } from './examples-presets.js'; -import { recommendCommands, getQuickStartGuide } from './recommendation.js'; -import { getTroubleshootingGuide } from './next-steps.js'; -import { previewWorkflow, executeWorkflow } from './workflow-execution.js'; -import { interpretResult } from './result-interpretation.js'; -import { smartSearch } from './smart-search.js'; -import { getConversationTemplate, listConversationTemplates } from './conversation-templates.js'; -import ReadmeKnowledgeBase from './readme-knowledge-base.js'; -import { docsSearch } from './docs-search.js'; +import { fileURLToPath } from 'url'; +import { readFileSync } from 'fs'; import { listResources, readResource } from './resources.js'; 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 { errorResponse } from './tools/types.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); -/** - * Sanitize tool name to conform to MCP naming rules [a-z0-9_-] - */ -function sanitizeToolName(name) { - return name.replace(/[^a-z0-9_-]/g, '_'); -} -/** - * MCP Server for SAP HANA CLI Tools - * - * Exposes all hana-cli commands as MCP tools that can be called by LLMs - */ +const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'mcp-server', 'package.json'), 'utf-8')); class HanaCliMcpServer { server; commands = new Map(); @@ -50,7 +30,7 @@ class HanaCliMcpServer { 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({ name: 'hana-cli-mcp-server', - version: '1.0.0', + version: pkg.version, icons: [ { src: iconPngDataUri, @@ -80,1486 +60,41 @@ class HanaCliMcpServer { setupHandlers() { this.setupResourceHandlers(); this.setupPromptHandlers(); - // List available tools this.server.setRequestHandler(ListToolsRequestSchema, async () => { - const tools = []; - for (const [name, commandModule] of this.commands) { - const info = extractCommandInfo(commandModule); - // Build rich description with metadata - let fullDescription = info.description; - // Add category and tags inline - if (info.category) { - fullDescription += ` [Category: ${info.category}]`; - } - if (info.tags && info.tags.length > 0) { - fullDescription += ` [Tags: ${info.tags.join(', ')}]`; - } - // Add use cases if available - if (info.useCases && info.useCases.length > 0) { - fullDescription += `\n\n**Common Use Cases:**\n${info.useCases.map(uc => `- ${uc}`).join('\n')}`; - } - // Add related commands - if (info.relatedCommands && info.relatedCommands.length > 0) { - fullDescription += `\n\n**Related Commands:** ${info.relatedCommands.map(rc => `hana_${rc}`).join(', ')}`; - } - // Add tip about examples/presets if available - if (hasExamples(name)) { - fullDescription += `\n\n💡 **Tip:** Use \`hana_examples\` with command="${name}" to see usage examples.`; - } - if (hasPresets(name)) { - fullDescription += `\n\n📋 **Tip:** Use \`hana_parameter_presets\` with command="${name}" to see parameter templates.`; - } - // Extend schema with project context parameter - const extendedSchema = { - ...info.schema, - properties: { - ...(info.schema.properties || {}), - __projectContext: { - type: 'object', - description: 'Project-specific connection context (optional). Use this to connect to a project-specific database instead of the default. The CLI will use connection files from the specified projectPath.', - properties: { - projectPath: { - type: 'string', - description: 'Absolute path to the project directory. Example: "C:/Users/dev/projects/my-app" or "/home/user/projects/my-app"' - }, - connectionFile: { - type: 'string', - description: 'Connection file name relative to projectPath. Example: ".env" or "default-env.json". If provided, the CLI will use this specific file.' - }, - host: { - type: 'string', - description: 'Database host (for direct connection). Example: "database.example.com"' - }, - port: { - type: 'number', - description: 'Database port (for direct connection). Default is 30013.' - }, - user: { - type: 'string', - description: 'Database user (for direct connection). Example: "DBADMIN"' - }, - password: { - type: 'string', - description: 'Database password (for direct connection). SECURITY WARNING: Use connection files instead of hardcoding passwords.' - }, - database: { - type: 'string', - description: 'Database name (for direct connection). Default is "SYSTEMDB".' - } - } - } - } - }; - tools.push({ - name: `hana_${sanitizeToolName(name)}`, - description: fullDescription, - inputSchema: extendedSchema, - }); - // Also register aliases - if (info.aliases && info.aliases.length > 0) { - for (const alias of info.aliases) { - tools.push({ - name: `hana_${sanitizeToolName(alias)}`, - description: `${fullDescription} (alias for ${name})`, - inputSchema: extendedSchema, - }); - } - } - } - // Add discovery tools - tools.push({ - name: 'hana_discover_categories', - description: 'Discover available command categories and get an overview of what each category does. Use this to find commands for a specific task.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_discover_by_category', - description: 'Get all commands in a specific category. Useful for finding commands when you know the general area (e.g., "data-quality", "performance-analysis").', - inputSchema: { - type: 'object', - properties: { - category: { - type: 'string', - description: 'The category to query (e.g., "data-tools", "schema-tools", "object-inspection", "analysis-tools", "performance-monitoring", "backup-recovery", "system-admin", "system-tools", "security", "mass-operations", "connection-auth", "btp-integration", "hana-cloud", "hdi-management", "developer-tools")', - }, - }, - required: ['category'], - }, - }); - tools.push({ - name: 'hana_discover_by_tag', - description: 'Search commands by tag. Tags help identify commands for specific purposes (e.g., "import", "export", "validation", "performance", "user", "privilege").', - inputSchema: { - type: 'object', - properties: { - tag: { - type: 'string', - description: 'The tag to search for (e.g., "import", "export", "validation", "performance", "user", "security")', - }, - }, - required: ['tag'], - }, - }); - tools.push({ - name: 'hana_workflows', - description: 'List available workflows - multi-step task sequences for common scenarios like data validation, performance analysis, security audits, and backup procedures.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_workflow_by_id', - description: 'Get detailed steps for a specific workflow. Provides complete instructions including commands, parameters, and expected outputs.', - inputSchema: { - type: 'object', - properties: { - id: { - type: 'string', - description: 'Workflow ID (e.g., "validate-and-profile", "export-and-import", "performance-analysis", "security-audit", "backup-and-verify")', - }, - }, - required: ['id'], - }, - }); - tools.push({ - name: 'hana_search_workflows', - description: 'Search for workflows by tag or purpose. Find workflows for specific scenarios.', - inputSchema: { - type: 'object', - properties: { - tag: { - type: 'string', - description: 'Search tag (e.g., "data-quality", "performance", "security", "backup", "migration")', - }, - }, - required: ['tag'], - }, - }); - tools.push({ - name: 'hana_examples', - description: 'Get real-world usage examples for a specific command with parameter combinations, scenarios, and expected outputs. Essential for understanding how to use commands correctly.', - inputSchema: { - type: 'object', - properties: { - command: { - type: 'string', - description: 'Command name (without hana_ prefix, e.g., "import", "export", "dataProfile")', - }, - }, - required: ['command'], - }, - }); - tools.push({ - name: 'hana_parameter_presets', - description: 'Get parameter presets/templates for common use cases of a command. Shows pre-configured parameter combinations for scenarios like "quick-import", "safe-import", "large-file" etc.', - inputSchema: { - type: 'object', - properties: { - command: { - type: 'string', - description: 'Command name (without hana_ prefix)', - }, - }, - required: ['command'], - }, - }); - tools.push({ - name: 'hana_commands_with_examples', - description: 'List all commands that have usage examples available. Use this to discover which commands have detailed examples.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - // Phase 2: Enhanced Discovery Tools - tools.push({ - name: 'hana_recommend', - description: 'Get command recommendations based on natural language intent. Tell me what you want to do, and I\'ll suggest the best commands. Example: "find duplicate rows", "check database version", "export table to CSV".', - inputSchema: { - type: 'object', - properties: { - intent: { - type: 'string', - description: 'What you want to accomplish in natural language (e.g., "import CSV file", "find slow queries", "check user permissions")', - }, - limit: { - type: 'number', - description: 'Maximum number of recommendations to return (default: 5)', - default: 5, - }, - }, - required: ['intent'], - }, - }); - tools.push({ - name: 'hana_quickstart', - description: 'Get a beginner-friendly quick start guide with the recommended first 6 commands to run when starting with the database. Perfect for new users or initial database exploration.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_troubleshoot', - description: 'Get troubleshooting guide for a specific command including common issues, solutions, prerequisites, and tips. Essential when a command isn\'t working as expected.', - inputSchema: { - type: 'object', - properties: { - command: { - type: 'string', - description: 'Command name (without hana_ prefix) to get troubleshooting help for', - }, - }, - required: ['command'], - }, - }); - // Phase 3: Advanced Features - tools.push({ - name: 'hana_execute_workflow', - description: 'Execute a complete multi-step workflow with automatic parameter substitution. Runs multiple commands in sequence according to the workflow definition. Use hana_preview_workflow first to see what will be executed.', - inputSchema: { - type: 'object', - properties: { - workflowId: { - type: 'string', - description: 'Workflow ID from hana_workflows (e.g., "validate-and-profile", "export-and-import")', - }, - parameters: { - type: 'object', - description: 'Parameters to substitute in workflow commands. Keys are parameter names, values are actual values (e.g., {"table-name": "CUSTOMERS", "schema-name": "SALES"})', - }, - stopOnError: { - type: 'boolean', - default: true, - description: 'Stop workflow execution if any command fails', - }, - }, - required: ['workflowId', 'parameters'], - }, - }); - tools.push({ - name: 'hana_preview_workflow', - description: 'Preview what commands will be executed in a workflow with your parameters substituted. Shows all steps, commands, and parameters before execution. Always use this before hana_execute_workflow.', - inputSchema: { - type: 'object', - properties: { - workflowId: { - type: 'string', - description: 'Workflow ID to preview', - }, - parameters: { - type: 'object', - description: 'Parameters to substitute', - }, - }, - required: ['workflowId', 'parameters'], - }, - }); - tools.push({ - name: 'hana_interpret_result', - description: 'Get AI-friendly interpretation of command results with insights, recommendations, and analysis. Provides summary, key metrics, concerns detected, and actionable recommendations.', - inputSchema: { - type: 'object', - properties: { - command: { - type: 'string', - description: 'The command that was executed', - }, - result: { - type: 'string', - description: 'The command output to interpret', - }, - }, - required: ['command', 'result'], - }, - }); - tools.push({ - name: 'hana_smart_search', - description: 'Comprehensive search across all resources: commands, workflows, examples, presets, and parameters. More powerful than discover tools - searches everything at once with relevance scoring.', - inputSchema: { - type: 'object', - properties: { - query: { - type: 'string', - description: 'Search query (keywords or phrases)', - }, - scope: { - type: 'string', - enum: ['all', 'commands', 'workflows', 'examples', 'presets'], - default: 'all', - description: 'What to search (default: all)', - }, - limit: { - type: 'number', - default: 20, - description: 'Maximum results to return', - }, - }, - required: ['query'], - }, - }); - // Documentation Search Tools - tools.push({ - name: 'hana_search_docs', - description: 'Search the comprehensive documentation website (https://sap-samples.github.io/hana-developer-cli-tool-example/) for guides, tutorials, command references, and detailed explanations. Returns relevant documents with excerpts and metadata.', - inputSchema: { - type: 'object', - properties: { - query: { - type: 'string', - description: 'Search query (e.g., "import data", "BTP integration", "connection setup", "performance tuning")', - }, - category: { - type: 'string', - description: 'Optional: limit search to specific category (getting-started, commands, features, api-reference, development)', - }, - docType: { - type: 'string', - enum: ['tutorial', 'command', 'api', 'feature', 'troubleshooting', 'development', 'general'], - description: 'Optional: filter by document type', - }, - limit: { - type: 'number', - default: 10, - description: 'Maximum number of results to return (default: 10)', - }, - }, - required: ['query'], - }, - }); - tools.push({ - name: 'hana_get_doc', - description: 'Retrieve the full content of a specific documentation page. Use after hana_search_docs to get complete details from a relevant document.', - inputSchema: { - type: 'object', - properties: { - path: { - type: 'string', - description: 'Document path from search results (e.g., "01-getting-started/installation.md", "02-commands/data-tools/import.md")', - }, - }, - required: ['path'], - }, - }); - tools.push({ - name: 'hana_docs_stats', - description: 'Get documentation statistics including total documents, categories, and document types available. Useful for understanding the scope of available documentation.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_list_doc_categories', - description: 'List all available documentation categories and document types. Use this to understand what documentation is available before searching.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_conversation_templates', - description: 'List available conversation templates for common scenarios. Templates provide step-by-step guided workflows for tasks like data-exploration, troubleshooting, data-migration, performance-tuning, and security-audit.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_get_template', - description: 'Get a detailed conversation template for a specific scenario. Includes all steps, commands, expected outcomes, tips, and common questions with answers.', - inputSchema: { - type: 'object', - properties: { - scenario: { - type: 'string', - description: 'Scenario name (e.g., "data-exploration", "troubleshooting", "data-migration", "performance-tuning", "security-audit")', - }, - }, - required: ['scenario'], - }, - }); - // Knowledge Base Tools from README and Project Documentation - tools.push({ - name: 'hana_connection_guide', - description: 'Get detailed guide on connection resolution order and best practices. Shows all 7 steps the tool uses to find database credentials (admin, cds bind, .env, --conn parameter, home directory, default-env.json, fallback).', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_standard_parameters', - description: 'Get standardized parameters for a specific command category. Shows parameter conventions, aliases, defaults, and usage examples for command types like data-manipulation, batch-operations, and list-inspect.', - inputSchema: { - type: 'object', - properties: { - category: { - type: 'string', - enum: ['data-manipulation', 'batch-operations', 'list-inspect'], - description: 'Command category to get parameter guide for', - }, - }, - required: ['category'], - }, - }); - tools.push({ - name: 'hana_security_guide', - description: 'Get comprehensive security best practices and guidelines for using hana-cli. Covers connection configuration, SQL injection protection, parameter security, and environment security.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_best_practices', - description: 'Get naming conventions, alias patterns, and best practice patterns for using the CLI. Includes examples of safe operation patterns, cross-database usage, and batch processing.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_project_structure', - description: 'Get overview of the hana-cli project structure and key documentation resources. Shows all folders, their purposes, and links to relevant README files.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - tools.push({ - name: 'hana_docs_search', - description: 'Search across all project documentation including command categories, security guidelines, best practices, and resources. Use keywords to find relevant information.', - inputSchema: { - type: 'object', - properties: { - query: { - type: 'string', - description: 'Search query (e.g., "security", "connection", "parameters", "import", "export", "data-quality")', - }, - }, - required: ['query'], - }, - }); + const tools = [ + ...getDiscoveryToolDefinitions(), + ...getContentToolDefinitions(), + ...getSearchToolDefinitions(), + ...getCliToolDefinitions(), + ]; return { tools }; }); - // Execute tool calls this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; - // Remove 'hana_' prefix to get actual command name const commandName = name.startsWith('hana_') ? name.slice(5) : name; - // Handle discovery tools first - if (commandName === 'discover_categories') { - const categoryList = Object.entries(CATEGORIES).map(([key, value]) => ({ - id: key, - name: value.name, - description: value.description, - total: getCommandsInCategory(key).length, - })); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'Available command categories', - categories: categoryList, - usage: 'Use hana_discover_by_category to get commands in a specific category', - }, null, 2), - }, - ], - }; - } - if (commandName === 'discover_by_category') { - const category = args?.category; - if (!category) { - return { - content: [ - { - type: 'text', - text: 'Error: category parameter is required', - }, - ], - }; - } - const commands = getCommandsInCategory(category); - if (commands.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No commands found in category: ${category}`, - tip: 'Use hana_discover_categories to see available categories', - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - category, - categoryInfo: CATEGORIES[category], - commands: commands.map(cmd => ({ - command: cmd.command, - category: cmd.category, - tags: cmd.tags, - useCases: cmd.useCases, - relatedCommands: cmd.relatedCommands, - })), - total: commands.length, - }, null, 2), - }, - ], - }; - } - if (commandName === 'discover_by_tag') { - const tag = args?.tag; - if (!tag) { - return { - content: [ - { - type: 'text', - text: 'Error: tag parameter is required', - }, - ], - }; - } - const commands = searchCommandsByTag(tag); - if (commands.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No commands found with tag: ${tag}`, - tip: 'Try different tags or use hana_discover_by_category to browse', - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - tag, - commands: commands.map(cmd => ({ - command: cmd.command, - category: cmd.category, - tags: cmd.tags, - useCases: cmd.useCases, - relatedCommands: cmd.relatedCommands, - })), - total: commands.length, - }, null, 2), - }, - ], - }; - } - if (commandName === 'workflows') { - const workflows = getAllWorkflows(); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'Available workflows for common multi-step tasks', - workflows: workflows.map(wf => ({ - id: wf.id, - name: wf.name, - description: wf.description, - goal: wf.goal, - estimatedTime: wf.estimatedTime, - tags: wf.tags, - steps: wf.steps.length, - })), - total: workflows.length, - usage: 'Use hana_workflow_by_id to see detailed steps for a workflow', - }, null, 2), - }, - ], - }; - } - if (commandName === 'workflow_by_id') { - const id = args?.id; - if (!id) { - return { - content: [ - { - type: 'text', - text: 'Error: id parameter is required', - }, - ], - }; - } - const workflow = getWorkflowById(id); - if (!workflow) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `Workflow not found: ${id}`, - tip: 'Use hana_workflows to see available workflow IDs', - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify(workflow, null, 2), - }, - ], - }; - } - if (commandName === 'search_workflows') { - const tag = args?.tag; - if (!tag) { - return { - content: [ - { - type: 'text', - text: 'Error: tag parameter is required', - }, - ], - }; - } - const workflows = searchWorkflowsByTag(tag); - if (workflows.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No workflows found with tag: ${tag}`, - tip: 'Use hana_workflows to see available workflows', - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - tag, - workflows: workflows.map(wf => ({ - id: wf.id, - name: wf.name, - description: wf.description, - goal: wf.goal, - estimatedTime: wf.estimatedTime, - tags: wf.tags, - })), - total: workflows.length, - }, null, 2), - }, - ], - }; - } - if (commandName === 'examples') { - const command = args?.command; - if (!command) { - return { - content: [ - { - type: 'text', - text: 'Error: command parameter is required', - }, - ], - }; - } - const examples = getCommandExamples(command); - if (examples.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No examples available for command: ${command}`, - tip: 'Use hana_commands_with_examples to see which commands have examples', - availableCommands: getCommandsWithExamples(), - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - command, - examples: examples.map(ex => ({ - scenario: ex.scenario, - description: ex.description, - parameters: ex.parameters, - notes: ex.notes, - expectedOutput: ex.expectedOutput, - })), - total: examples.length, - usage: `To execute: Use hana_${command} with the parameters from any example`, - }, null, 2), - }, - ], - }; - } - if (commandName === 'parameter_presets') { - const command = args?.command; - if (!command) { - return { - content: [ - { - type: 'text', - text: 'Error: command parameter is required', - }, - ], - }; - } - const presets = getCommandPresets(command); - if (presets.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No presets available for command: ${command}`, - tip: 'Try hana_examples for usage examples instead', - commandsWithPresets: getCommandsWithPresets(), - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - command, - presets: presets.map(preset => ({ - name: preset.name, - description: preset.description, - parameters: preset.parameters, - notes: preset.notes, - whenToUse: preset.whenToUse, - })), - total: presets.length, - usage: 'Replace placeholder values (e.g., ) with your actual values', - }, null, 2), - }, - ], - }; - } - if (commandName === 'commands_with_examples') { - const commandsWithExamples = getCommandsWithExamples(); - const commandsWithPresets = getCommandsWithPresets(); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'Commands with examples and presets available', - commandsWithExamples: commandsWithExamples.sort(), - commandsWithPresets: commandsWithPresets.sort(), - totalWithExamples: commandsWithExamples.length, - totalWithPresets: commandsWithPresets.length, - usage: { - examples: 'Use hana_examples with command name to see detailed examples', - presets: 'Use hana_parameter_presets with command name to see parameter templates', - }, - }, null, 2), - }, - ], - }; - } - // Phase 2: Enhanced Discovery Handlers - if (commandName === 'recommend') { - const intent = args?.intent; - const limit = args?.limit || 5; - if (!intent) { - return { - content: [ - { - type: 'text', - text: 'Error: intent parameter is required. Describe what you want to do in natural language.', - }, - ], - }; - } - const recommendations = recommendCommands(intent, limit); - if (recommendations.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'No commands found matching your intent', - intent, - tip: 'Try using different words or browse by category with hana_discover_categories', - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - intent, - recommendations: recommendations.map(rec => ({ - command: `hana_${rec.command}`, - confidence: rec.confidence, - reason: rec.reason, - category: rec.category, - tags: rec.tags, - useCases: rec.useCases, - exampleParameters: rec.exampleParameters, - howToUse: rec.exampleParameters - ? `Call hana_${rec.command} with parameters: ${JSON.stringify(rec.exampleParameters)}` - : `Call hana_${rec.command}`, - getExamples: `Use hana_examples with command="${rec.command}" for detailed examples`, - })), - total: recommendations.length, - nextSteps: recommendations.length > 0 - ? `Try the highest confidence recommendation first, or use hana_examples to see usage examples` - : undefined, - }, null, 2), - }, - ], - }; - } - if (commandName === 'quickstart') { - const guide = getQuickStartGuide(); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - title: '🚀 Quick Start Guide for SAP HANA CLI', - description: 'Follow these steps to get started with your database', - steps: guide.map(step => ({ - order: step.order, - command: `hana_${step.command}`, - description: step.description, - purpose: step.purpose, - parameters: step.parameters, - tips: step.tips, - })), - totalSteps: guide.length, - recommendation: 'Execute these commands in order. Each step builds on the previous one.', - }, null, 2), - }, - ], - }; - } - if (commandName === 'troubleshoot') { - const command = args?.command; - if (!command) { - return { - content: [ - { - type: 'text', - text: 'Error: command parameter is required', - }, - ], - }; - } - const guide = getTroubleshootingGuide(command); - if (!guide) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No troubleshooting guide available for command: ${command}`, - tip: 'Try hana_examples for usage examples, or check command documentation', - availableGuides: ['import', 'export', 'dataProfile', 'tables', 'status', 'healthCheck'], - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - command: guide.command, - prerequisites: guide.prerequisites, - commonIssues: guide.commonIssues.map(issue => ({ - issue: issue.issue, - solution: issue.solution, - suggestedCommand: issue.command ? `hana_${issue.command}` : undefined, - parameters: issue.parameters, - })), - tips: guide.tips, - additionalHelp: { - examples: `Use hana_examples with command="${command}" for usage examples`, - presets: `Use hana_parameter_presets with command="${command}" for parameter templates`, - }, - }, null, 2), - }, - ], - }; - } - // Phase 3: Advanced Features Handlers - if (commandName === 'execute_workflow') { - const workflowId = args?.workflowId; - const parameters = args?.parameters || {}; - const stopOnError = args?.stopOnError !== false; - if (!workflowId) { - return { - content: [ - { - type: 'text', - text: 'Error: workflowId parameter is required', - }, - ], - }; - } - const result = await executeWorkflow(workflowId, parameters, stopOnError); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...result, - note: result.success - ? 'All workflow steps completed successfully' - : 'Workflow failed - see results for details', - }, null, 2), - }, - ], - }; - } - if (commandName === 'preview_workflow') { - const workflowId = args?.workflowId; - const parameters = args?.parameters || {}; - if (!workflowId) { - return { - content: [ - { - type: 'text', - text: 'Error: workflowId parameter is required', - }, - ], - }; - } - const preview = previewWorkflow(workflowId, parameters); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...preview, - note: preview.validation?.valid - ? 'Workflow ready to execute - use hana_execute_workflow with these parameters' - : 'Missing required parameters - see validation.missingParameters', - }, null, 2), - }, - ], - }; - } - if (commandName === 'interpret_result') { - const command = args?.command; - const result = args?.result; - if (!command || !result) { - return { - content: [ - { - type: 'text', - text: 'Error: both command and result parameters are required', - }, - ], - }; - } - const interpretation = interpretResult(command, result); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...interpretation, - usage: interpretation.recommendations.length > 0 - ? 'Follow recommendations in priority order for best results' - : undefined, - }, null, 2), - }, - ], - }; - } - if (commandName === 'smart_search') { - const query = args?.query; - const scope = args?.scope || 'all'; - const limit = args?.limit || 20; - if (!query) { - return { - content: [ - { - type: 'text', - text: 'Error: query parameter is required', - }, - ], - }; - } - const searchResults = smartSearch(query, scope, limit); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...searchResults, - note: searchResults.totalResults > 0 - ? `Found ${searchResults.totalResults} matches. Results sorted by relevance.` - : 'No matches found. Try different keywords or browse by category.', - }, null, 2), - }, - ], - }; - } - // Documentation Search Tool Handlers - if (commandName === 'search_docs') { - const query = args?.query; - const category = args?.category; - const docType = args?.docType; - const limit = args?.limit || 10; - if (!query) { - return { - content: [ - { - type: 'text', - text: 'Error: query parameter is required', - }, - ], - }; - } - if (!docsSearch.isAvailable()) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: 'Documentation index not available', - tip: 'Run "npm run build:docs-index" in the project root to generate the documentation index', - }, null, 2), - }, - ], - }; - } - const results = docsSearch.search(query, { category, docType, limit }); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - query, - totalResults: results.length, - results: results.map(r => ({ - title: r.document.title, - path: r.document.path, - category: r.document.category, - docType: r.document.docType, - relevance: r.relevance, - excerpt: r.snippet || r.document.excerpt, - matchedKeywords: r.matchedKeywords, - url: `https://sap-samples.github.io/hana-developer-cli-tool-example/${r.document.path.replace('.md', '.html')}`, - })), - tip: results.length > 0 - ? 'Use hana_get_doc with the path to read the full document content' - : 'No matches found. Try different keywords or use hana_list_doc_categories to browse available documentation', - }, null, 2), - }, - ], - }; - } - if (commandName === 'get_doc') { - const path = args?.path; - if (!path) { - return { - content: [ - { - type: 'text', - text: 'Error: path parameter is required', - }, - ], - }; - } - if (!docsSearch.isAvailable()) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: 'Documentation index not available', - tip: 'Run "npm run build:docs-index" in the project root to generate the documentation index', - }, null, 2), - }, - ], - }; - } - const document = docsSearch.getDocument(path); - const content = docsSearch.getDocumentContent(path); - if (!document || !content) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `Document not found: ${path}`, - tip: 'Use hana_search_docs to find valid document paths', - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - title: document.title, - path: document.path, - category: document.category, - docType: document.docType, - url: `https://sap-samples.github.io/hana-developer-cli-tool-example/${path.replace('.md', '.html')}`, - headings: document.headings, - content: content, - relatedLinks: document.links, - lastModified: document.lastModified, - }, null, 2), - }, - ], - }; - } - if (commandName === 'docs_stats') { - if (!docsSearch.isAvailable()) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: 'Documentation index not available', - tip: 'Run "npm run build:docs-index" in the project root to generate the documentation index', - }, null, 2), - }, - ], - }; - } - const stats = docsSearch.getStats(); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...stats, - websiteUrl: 'https://sap-samples.github.io/hana-developer-cli-tool-example/', - usage: 'Use hana_search_docs to search, hana_list_doc_categories to browse', - }, null, 2), - }, - ], - }; - } - if (commandName === 'list_doc_categories') { - if (!docsSearch.isAvailable()) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: 'Documentation index not available', - tip: 'Run "npm run build:docs-index" in the project root to generate the documentation index', - }, null, 2), - }, - ], - }; - } - const categories = docsSearch.getCategories(); - const docTypes = docsSearch.getDocTypes(); - const categorySummary = {}; - categories.forEach(cat => { - const docs = docsSearch.listByCategory(cat); - categorySummary[cat] = { - documentCount: docs.length, - sampleDocuments: docs.slice(0, 3).map(d => ({ - title: d.title, - path: d.path, - })), - }; - }); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - categories: categorySummary, - documentTypes: docTypes, - totalCategories: categories.length, - usage: 'Use hana_search_docs with category parameter to limit search scope', - }, null, 2), - }, - ], - }; - } - if (commandName === 'conversation_templates') { - const templates = listConversationTemplates(); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'Available conversation templates', - templates: templates.map(t => ({ - scenario: t.scenario, - description: t.description, - goal: t.goal, - usage: `Use hana_get_template with scenario="${t.scenario}" to see full details`, - })), - total: templates.length, - }, null, 2), - }, - ], - }; - } - if (commandName === 'get_template') { - const scenario = args?.scenario; - if (!scenario) { - return { - content: [ - { - type: 'text', - text: 'Error: scenario parameter is required', - }, - ], - }; - } - const template = getConversationTemplate(scenario); - if (!template) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `Template not found: ${scenario}`, - availableTemplates: listConversationTemplates().map(t => t.scenario), - }, null, 2), - }, - ], - }; - } - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...template, - usage: 'Follow steps in order. Each step builds on previous results.', - }, null, 2), - }, - ], - }; - } - // Knowledge Base Tool Handlers - if (commandName === 'connection_guide') { - return { - content: [ - { - type: 'text', - text: ReadmeKnowledgeBase.getConnectionGuide(), - }, - ], - }; - } - if (commandName === 'standard_parameters') { - const category = args?.category; - if (!category) { - return { - content: [ - { - type: 'text', - text: 'Error: category parameter is required. Available categories: data-manipulation, batch-operations, list-inspect', - }, - ], - }; - } - const guide = ReadmeKnowledgeBase.getParameterGuide(category); - return { - content: [ - { - type: 'text', - text: guide, - }, - ], - }; - } - if (commandName === 'security_guide') { - return { - content: [ - { - type: 'text', - text: ReadmeKnowledgeBase.getSecurityGuidelines(), - }, - ], - }; - } - if (commandName === 'best_practices') { - return { - content: [ - { - type: 'text', - text: ReadmeKnowledgeBase.getBestPractices(), - }, - ], - }; - } - if (commandName === 'project_structure') { - return { - content: [ - { - type: 'text', - text: ReadmeKnowledgeBase.getProjectStructure(), - }, - ], - }; - } - if (commandName === 'docs_search') { - const query = args?.query; - if (!query) { - return { - content: [ - { - type: 'text', - text: 'Error: query parameter is required', - }, - ], - }; - } - const results = ReadmeKnowledgeBase.searchDocumentation(query); - return { - content: [ - { - type: 'text', - text: results, - }, - ], - }; - } - // Check if command exists (either as main name or alias) - let actualCommandName = commandName; - if (!this.commands.has(commandName)) { - // Check if it's an alias (compare sanitized versions) - for (const [cmdName, cmdModule] of this.commands) { - if (cmdModule.aliases) { - for (const alias of cmdModule.aliases) { - if (sanitizeToolName(alias) === commandName) { - actualCommandName = cmdName; - break; - } - } - if (actualCommandName !== commandName) - break; - } - } - } - if (!this.commands.has(actualCommandName)) { - return { - content: [ - { - type: 'text', - text: `Unknown command: ${commandName}`, - }, - ], - }; - } - // Validate environment if needed - const envCheck = validateEnvironment(); - if (!envCheck.valid) { - return { - content: [ - { - type: 'text', - text: `Environment validation failed: ${envCheck.message}`, - }, - ], - }; - } - // Execute the command - try { - // Extract connection context if provided by agent - const context = args?.__projectContext; - // Remove context from args before passing to CLI (it's not a CLI parameter) - const cleanArgs = { ...args }; - delete cleanArgs.__projectContext; - const result = await executeCommand(actualCommandName, cleanArgs, context); - const formattedOutput = formatResult(result); - return { - content: [ - { - type: 'text', - text: formattedOutput, - }, - ], - }; - } - catch (error) { - return { - content: [ - { - type: 'text', - text: `Error executing command: ${error instanceof Error ? error.message : String(error)}`, - }, - ], - }; - } + const result = handleDiscoveryTool(commandName, args) ?? + handleContentTool(commandName, args) ?? + handleSearchTool(commandName, args) ?? + await handleCliTool(name, args); + if (result) + return result; + return errorResponse(`Unknown tool: ${name}`); }); } - /** - * Setup MCP Resource handlers for documentation access - */ setupResourceHandlers() { - // List available resources this.server.setRequestHandler(ListResourcesRequestSchema, async () => { try { - const resources = listResources(); - return { resources }; + return { resources: listResources() }; } catch (error) { console.error('[MCP] Error listing resources:', error); return { resources: [] }; } }); - // Read a specific resource this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => { try { - const { uri } = request.params; - const content = await readResource(uri); - return { - contents: [content], - }; + const content = await readResource(request.params.uri); + return { contents: [content] }; } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); @@ -1568,27 +103,20 @@ class HanaCliMcpServer { } }); } - /** - * Setup MCP Prompt handlers for guided workflows - */ setupPromptHandlers() { - // List available prompts this.server.setRequestHandler(ListPromptsRequestSchema, async () => { try { - const prompts = listPrompts(); - return { prompts }; + return { prompts: listPrompts() }; } catch (error) { console.error('[MCP] Error listing prompts:', error); return { prompts: [] }; } }); - // Get a specific prompt this.server.setRequestHandler(GetPromptRequestSchema, async (request) => { try { const { name, arguments: args } = request.params; - const result = getPrompt(name, args); - return result; + return getPrompt(name, args); } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); @@ -1597,39 +125,30 @@ class HanaCliMcpServer { } }); } - /** - * Load all commands from the parent hana-cli project - */ async loadCommands() { try { - // Import the index.js from parent project that exports init() - // __dirname is mcp-server/build, so go up 2 levels to project root const indexPath = join(__dirname, '..', '..', 'bin', 'index.js'); - // Convert to file:// URL for ES module import (required on Windows) const indexUrl = pathToFileURL(indexPath).href; const indexModule = await import(indexUrl); if (typeof indexModule.init !== 'function') { throw new Error('index.js does not export an init() function'); } - // Call init() to get all command modules const commands = await indexModule.init(); if (!Array.isArray(commands)) { throw new Error('init() did not return an array of commands'); } console.error(`[MCP] Loaded ${commands.length} command modules from hana-cli`); - // Store commands in map - let successCount = 0; for (const cmd of commands) { if (cmd && typeof cmd.command === 'string') { const commandName = cmd.command.split(' ')[0]; this.commands.set(commandName, cmd); - successCount++; } } - console.error(`[MCP] Registered ${this.commands.size} unique commands with ${successCount} processed modules`); + console.error(`[MCP] Registered ${this.commands.size} unique commands`); if (this.commands.size === 0) { throw new Error('No valid commands were registered'); } + initCliTools(this.commands); } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); @@ -1638,14 +157,12 @@ class HanaCliMcpServer { } } async run() { - // Load commands before starting server await this.loadCommands(); const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('[MCP] SAP HANA CLI MCP Server running on stdio'); } } -// Start the server const server = new HanaCliMcpServer(); server.run().catch((error) => { console.error('[MCP] Fatal error:', error); diff --git a/mcp-server/build/index.js.map b/mcp-server/build/index.js.map index c0148348..9d374b38 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":";AAEA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC9F,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAEtG,CAAC;AAEF,MAAM,gBAAgB;IACZ,MAAM,CAAS;IACf,QAAQ,GAAqB,IAAI,GAAG,EAAE,CAAC;IAE/C;QACE,MAAM,cAAc,GAClB,4uCAA4uC,CAAC;QAE/uC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CACtB;YACE,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,KAAK,EAAE;gBACL;oBACE,GAAG,EAAE,cAAc;oBACnB,QAAQ,EAAE,WAAW;oBACrB,KAAK,EAAE,CAAC,KAAK,CAAC;iBACf;aACF;SACF,EACD;YACE,YAAY,EAAE;gBACZ,KAAK,EAAE,EAAE;gBACT,SAAS,EAAE,EAAE;gBACb,OAAO,EAAE,EAAE;aACZ;SACF,CACF,CAAC;QAEF,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAEO,kBAAkB;QACxB,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;YAC9B,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAC9B,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa;QACnB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAE3B,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,KAAK,GAAG;gBACZ,GAAG,2BAA2B,EAAE;gBAChC,GAAG,yBAAyB,EAAE;gBAC9B,GAAG,wBAAwB,EAAE;gBAC7B,GAAG,qBAAqB,EAAE;aAC3B,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACrE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;YACjD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAEpE,MAAM,MAAM,GACV,mBAAmB,CAAC,WAAW,EAAE,IAA2B,CAAC;gBAC7D,iBAAiB,CAAC,WAAW,EAAE,IAA2B,CAAC;gBAC3D,gBAAgB,CAAC,WAAW,EAAE,IAA2B,CAAC;gBAC1D,MAAM,aAAa,CAAC,IAAI,EAAE,IAA2B,CAAC,CAAC;YAEzD,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;YAE1B,OAAO,aAAa,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,qBAAqB;QAC3B,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACnE,IAAI,CAAC;gBACH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,CAAC;YACxC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;gBACvD,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACzE,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACvD,OAAO,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,QAAQ,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACxE,OAAO,CAAC,KAAK,CAAC,gCAAgC,OAAO,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAC/E,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,mBAAmB;QACzB,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;YACjE,IAAI,CAAC;gBACH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;YACpC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;gBACrD,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACzB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACtE,IAAI,CAAC;gBACH,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;gBACjD,OAAO,SAAS,CAAC,IAAI,EAAE,IAA0C,CAAC,CAAC;YACrE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,QAAQ,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACxE,OAAO,CAAC,KAAK,CAAC,8BAA8B,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAC9E,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;YACjE,MAAM,QAAQ,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;YAC/C,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;YAE3C,IAAI,OAAO,WAAW,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC3C,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;YACjE,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;YAE1C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;YAChE,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,gBAAgB,QAAQ,CAAC,MAAM,gCAAgC,CAAC,CAAC;YAE/E,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBAC3C,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC9C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,oBAAoB,IAAI,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,CAAC;YAExE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACvD,CAAC;YAED,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxE,OAAO,CAAC,KAAK,CAAC,kCAAkC,QAAQ,EAAE,CAAC,CAAC;YAC5D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAClE,CAAC;CACF;AAED,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;AACtC,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC3B,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/mcp-server/build/output-formatter.d.ts.map b/mcp-server/build/output-formatter.d.ts.map index d288ee4f..37d1805f 100644 --- a/mcp-server/build/output-formatter.d.ts.map +++ b/mcp-server/build/output-formatter.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"output-formatter.d.ts","sourceRoot":"","sources":["../src/output-formatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoRH;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAgCpE"} \ No newline at end of file +{"version":3,"file":"output-formatter.d.ts","sourceRoot":"","sources":["../src/output-formatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA+RH;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBpE"} \ No newline at end of file diff --git a/mcp-server/build/output-formatter.js b/mcp-server/build/output-formatter.js index d05e390b..b745a4a1 100644 --- a/mcp-server/build/output-formatter.js +++ b/mcp-server/build/output-formatter.js @@ -226,33 +226,24 @@ function formatContainersOutput(output) { result += formatAsMarkdown({ headers, rows }); return result; } +const COMMAND_FORMATTERS = { + tables: formatTablesOutput, + schemas: formatSchemasOutput, + views: formatViewsOutput, + procedures: formatProceduresOutput, + functions: formatFunctionsOutput, + systemInfo: formatSystemInfoOutput, + sysInfo: formatSystemInfoOutput, + containers: formatContainersOutput, +}; /** * Main formatter function */ export function formatOutput(command, output) { - // Remove the connection config message for cleaner output const cleanOutput = output.replace(/Using Connection Configuration.*\n\n?/, ''); - // Detect command type and apply appropriate formatting - if (command.includes('tables') || command.includes(' t ')) { - return formatTablesOutput(cleanOutput); - } - else if (command.includes('schemas') || command.includes(' sch ')) { - return formatSchemasOutput(cleanOutput); - } - else if (command.includes('views') || command.includes(' v ')) { - return formatViewsOutput(cleanOutput); - } - else if (command.includes('procedures') || command.includes(' p ')) { - return formatProceduresOutput(cleanOutput); - } - else if (command.includes('functions') || command.includes(' f ')) { - return formatFunctionsOutput(cleanOutput); - } - else if (command.includes('systemInfo') || command.includes('sysInfo')) { - return formatSystemInfoOutput(cleanOutput); - } - else if (command.includes('containers') || command.includes('cont')) { - return formatContainersOutput(cleanOutput); + const formatter = COMMAND_FORMATTERS[command]; + if (formatter) { + return formatter(cleanOutput); } // For other commands, try generic table formatting const table = parseAsciiTable(cleanOutput); diff --git a/mcp-server/build/output-formatter.js.map b/mcp-server/build/output-formatter.js.map index d39d951a..4e617747 100644 --- a/mcp-server/build/output-formatter.js.map +++ b/mcp-server/build/output-formatter.js.map @@ -1 +1 @@ -{"version":3,"file":"output-formatter.js","sourceRoot":"","sources":["../src/output-formatter.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"output-formatter.js","sourceRoot":"","sources":["../src/output-formatter.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/mcp-server/build/resources.d.ts.map b/mcp-server/build/resources.d.ts.map index 1a5bc09d..a37c64b0 100644 --- a/mcp-server/build/resources.d.ts.map +++ b/mcp-server/build/resources.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,QAAQ,EAAE,CA4H1C;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAqRxG"} \ No newline at end of file +{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,QAAQ,EAAE,CAsL1C;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA+TxG"} \ No newline at end of file diff --git a/mcp-server/build/resources.js b/mcp-server/build/resources.js index 265063e2..ecad9168 100644 --- a/mcp-server/build/resources.js +++ b/mcp-server/build/resources.js @@ -9,6 +9,7 @@ import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; import { docsSearch } from './docs-search.js'; import { getCommandExamples, getCommandPresets } from './examples-presets.js'; +import ReadmeKnowledgeBase from './readme-knowledge-base.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); /** @@ -134,6 +135,62 @@ export function listResources() { description: 'List of guided workflows and templates for common tasks', mimeType: 'text/plain', }, + // Knowledge Base (migrated from tools for reduced context usage) + { + uri: 'hana://knowledge/connection-guide', + name: 'Connection Resolution Guide (Knowledge Base)', + description: 'Detailed 7-step connection resolution order and best practices', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/security-guide', + name: 'Security Guidelines (Knowledge Base)', + description: 'Connection security, SQL injection protection, parameter security, environment security', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/best-practices', + name: 'Best Practices (Knowledge Base)', + description: 'Naming conventions, alias patterns, safe operation patterns', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/project-structure', + name: 'Project Structure (Knowledge Base)', + description: 'Overview of hana-cli project folders and documentation resources', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/parameters/data-manipulation', + name: 'Data Manipulation Parameters', + description: 'Standard parameters for data manipulation commands (schema, table, output, format, etc.)', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/parameters/batch-operations', + name: 'Batch Operation Parameters', + description: 'Standard parameters for batch/mass operation commands', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/parameters/list-inspect', + name: 'List & Inspect Parameters', + description: 'Standard parameters for listing and inspection commands', + mimeType: 'text/markdown', + }, + // Documentation Index Metadata + { + uri: 'hana://docs/statistics', + name: 'Documentation Statistics', + description: 'Total documents, categories, and document types available in the documentation index', + mimeType: 'application/json', + }, + { + uri: 'hana://docs/categories', + name: 'Documentation Categories', + description: 'All available documentation categories and document types with sample documents', + mimeType: 'application/json', + }, ]; } /** @@ -387,6 +444,46 @@ Example: To explore a database, invoke the "explore-database" prompt. text, }; } + // Knowledge Base resources + if (uri === 'hana://knowledge/connection-guide') { + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getConnectionGuide() }; + } + if (uri === 'hana://knowledge/security-guide') { + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getSecurityGuidelines() }; + } + if (uri === 'hana://knowledge/best-practices') { + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getBestPractices() }; + } + if (uri === 'hana://knowledge/project-structure') { + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getProjectStructure() }; + } + if (uri.startsWith('hana://knowledge/parameters/')) { + const category = uri.replace('hana://knowledge/parameters/', ''); + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getParameterGuide(category) }; + } + // Documentation index metadata resources + if (uri === 'hana://docs/statistics') { + if (!docsSearch.isAvailable()) { + return { uri, mimeType: 'application/json', text: JSON.stringify({ error: 'Documentation index not available' }) }; + } + return { uri, mimeType: 'application/json', text: JSON.stringify(docsSearch.getStats(), null, 2) }; + } + if (uri === 'hana://docs/categories') { + if (!docsSearch.isAvailable()) { + return { uri, mimeType: 'application/json', text: JSON.stringify({ error: 'Documentation index not available' }) }; + } + const categories = docsSearch.getCategories(); + const docTypes = docsSearch.getDocTypes(); + const categorySummary = {}; + categories.forEach(cat => { + const docs = docsSearch.listByCategory(cat); + categorySummary[cat] = { + documentCount: docs.length, + sampleDocuments: docs.slice(0, 3).map(d => ({ title: d.title, path: d.path })), + }; + }); + return { uri, mimeType: 'application/json', text: JSON.stringify({ categories: categorySummary, documentTypes: docTypes }, null, 2) }; + } throw new Error(`Unknown resource: ${uri}`); } //# sourceMappingURL=resources.js.map \ No newline at end of file diff --git a/mcp-server/build/resources.js.map b/mcp-server/build/resources.js.map index b894d826..cf929cdc 100644 --- a/mcp-server/build/resources.js.map +++ b/mcp-server/build/resources.js.map @@ -1 +1 @@ -{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.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 new file mode 100644 index 00000000..b49d8be9 --- /dev/null +++ b/mcp-server/build/tools/cli-tools.d.ts @@ -0,0 +1,5 @@ +import { ToolDefinition, ToolResponse } from './types.js'; +export declare function initCliTools(commands: Map): void; +export declare function getCliToolDefinitions(): 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 new file mode 100644 index 00000000..449c5f01 --- /dev/null +++ b/mcp-server/build/tools/cli-tools.d.ts.map @@ -0,0 +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;AA0BvF,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,CAiC7G"} \ No newline at end of file diff --git a/mcp-server/build/tools/cli-tools.js b/mcp-server/build/tools/cli-tools.js new file mode 100644 index 00000000..894b21f6 --- /dev/null +++ b/mcp-server/build/tools/cli-tools.js @@ -0,0 +1,93 @@ +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'; +function sanitizeToolName(name) { + return name.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: { + projectPath: { type: 'string', description: 'Absolute path to the project directory.' }, + connectionFile: { type: 'string', description: 'Connection file name relative to projectPath (e.g., ".env", "default-env.json").' }, + host: { type: 'string', description: 'Database host (for direct connection).' }, + port: { type: 'number', description: 'Database port (default 30013).' }, + user: { type: 'string', description: 'Database user.' }, + password: { type: 'string', description: 'Database password. SECURITY WARNING: Prefer connection files instead.' }, + database: { type: 'string', description: 'Database name (default "SYSTEMDB").' }, + }, +}; +let commandsMap = new Map(); +export function initCliTools(commands) { + commandsMap = commands; +} +export function getCliToolDefinitions() { + 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 (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; +} +export async function handleCliTool(toolName, args) { + const commandName = toolName.startsWith('hana_') ? toolName.slice(5) : toolName; + let actualCommandName = commandName; + if (!commandsMap.has(commandName)) { + for (const [cmdName, cmdModule] of commandsMap) { + if (cmdModule.aliases) { + for (const alias of cmdModule.aliases) { + if (sanitizeToolName(alias) === commandName) { + actualCommandName = cmdName; + break; + } + } + if (actualCommandName !== commandName) + break; + } + } + } + if (!commandsMap.has(actualCommandName)) { + return null; + } + try { + const context = args?.__projectContext; + const cleanArgs = { ...args }; + delete cleanArgs.__projectContext; + const result = await executeCommand(actualCommandName, cleanArgs, context); + const formattedOutput = formatResult(result); + return textResponse(formattedOutput); + } + catch (error) { + return errorResponse(`Error executing command: ${error instanceof Error ? error.message : String(error)}`); + } +} +//# sourceMappingURL=cli-tools.js.map \ No newline at end of file diff --git a/mcp-server/build/tools/cli-tools.js.map b/mcp-server/build/tools/cli-tools.js.map new file mode 100644 index 00000000..77e9d930 --- /dev/null +++ b/mcp-server/build/tools/cli-tools.js.map @@ -0,0 +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 diff --git a/mcp-server/build/tools/content-tools.d.ts b/mcp-server/build/tools/content-tools.d.ts new file mode 100644 index 00000000..156b7e24 --- /dev/null +++ b/mcp-server/build/tools/content-tools.d.ts @@ -0,0 +1,4 @@ +import { ToolDefinition, ToolResponse } from './types.js'; +export declare function getContentToolDefinitions(): ToolDefinition[]; +export declare function handleContentTool(commandName: string, args: Record): ToolResponse | null; +//# sourceMappingURL=content-tools.d.ts.map \ No newline at end of file diff --git a/mcp-server/build/tools/content-tools.d.ts.map b/mcp-server/build/tools/content-tools.d.ts.map new file mode 100644 index 00000000..19015bca --- /dev/null +++ b/mcp-server/build/tools/content-tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"content-tools.d.ts","sourceRoot":"","sources":["../../src/tools/content-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAA+B,MAAM,YAAY,CAAC;AAWvF,wBAAgB,yBAAyB,IAAI,cAAc,EAAE,CAiF5D;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,YAAY,GAAG,IAAI,CA2IrG"} \ No newline at end of file diff --git a/mcp-server/build/tools/content-tools.js b/mcp-server/build/tools/content-tools.js new file mode 100644 index 00000000..c5004231 --- /dev/null +++ b/mcp-server/build/tools/content-tools.js @@ -0,0 +1,221 @@ +import { jsonResponse, errorResponse } from './types.js'; +import { getCommandExamples, getCommandPresets, getCommandsWithExamples, getCommandsWithPresets, } from '../examples-presets.js'; +import { recommendCommands, getQuickStartGuide } from '../recommendation.js'; +import { getTroubleshootingGuide } from '../next-steps.js'; +import { interpretResult } from '../result-interpretation.js'; +import { getConversationTemplate, listConversationTemplates } from '../conversation-templates.js'; +export function getContentToolDefinitions() { + return [ + { + name: 'hana_examples', + description: 'Get real-world usage examples for a specific command with parameter combinations, scenarios, and expected outputs. Essential for understanding how to use commands correctly.', + inputSchema: { + type: 'object', + properties: { + command: { type: 'string', description: 'Command name (without hana_ prefix, e.g., "import", "export", "dataProfile")' }, + }, + required: ['command'], + }, + }, + { + name: 'hana_parameter_presets', + description: 'Get parameter presets/templates for common use cases of a command. Shows pre-configured parameter combinations for scenarios like "quick-import", "safe-import", "large-file" etc.', + inputSchema: { + type: 'object', + properties: { + command: { type: 'string', description: 'Command name (without hana_ prefix)' }, + }, + required: ['command'], + }, + }, + { + name: 'hana_recommend', + description: 'Get command recommendations based on natural language intent. Tell me what you want to do, and I\'ll suggest the best commands. Example: "find duplicate rows", "check database version", "export table to CSV".', + inputSchema: { + type: 'object', + properties: { + intent: { type: 'string', description: 'What you want to accomplish in natural language (e.g., "import CSV file", "find slow queries", "check user permissions")' }, + limit: { type: 'number', description: 'Maximum number of recommendations to return (default: 5)', default: 5 }, + }, + required: ['intent'], + }, + }, + { + name: 'hana_quickstart', + description: 'Get a beginner-friendly quick start guide with the recommended first 6 commands to run when starting with the database. Perfect for new users or initial database exploration.', + inputSchema: { type: 'object', properties: {}, required: [] }, + }, + { + name: 'hana_troubleshoot', + description: 'Get troubleshooting guide for a specific command including common issues, solutions, prerequisites, and tips. Essential when a command isn\'t working as expected.', + inputSchema: { + type: 'object', + properties: { + command: { type: 'string', description: 'Command name (without hana_ prefix) to get troubleshooting help for' }, + }, + required: ['command'], + }, + }, + { + name: 'hana_interpret_result', + description: 'Get AI-friendly interpretation of command results with insights, recommendations, and analysis. Provides summary, key metrics, concerns detected, and actionable recommendations.', + inputSchema: { + type: 'object', + properties: { + command: { type: 'string', description: 'The command that was executed' }, + result: { type: 'string', description: 'The command output to interpret' }, + }, + required: ['command', 'result'], + }, + }, + { + name: 'hana_conversation_templates', + description: 'List available conversation templates for common scenarios. Templates provide step-by-step guided workflows for tasks like data-exploration, troubleshooting, data-migration, performance-tuning, and security-audit.', + inputSchema: { type: 'object', properties: {}, required: [] }, + }, + { + name: 'hana_get_template', + description: 'Get a detailed conversation template for a specific scenario. Includes all steps, commands, expected outcomes, tips, and common questions with answers.', + inputSchema: { + type: 'object', + properties: { + scenario: { type: 'string', description: 'Scenario name (e.g., "data-exploration", "troubleshooting", "data-migration", "performance-tuning", "security-audit")' }, + }, + required: ['scenario'], + }, + }, + ]; +} +export function handleContentTool(commandName, args) { + if (commandName === 'examples') { + const command = args?.command; + if (!command) + return errorResponse('Error: command parameter is required'); + const examples = getCommandExamples(command); + if (examples.length === 0) { + return jsonResponse({ + error: `No examples available for command: ${command}`, + availableCommands: getCommandsWithExamples(), + }); + } + return jsonResponse({ + command, examples, total: examples.length, + usage: `To execute: Use hana_${command} with the parameters from any example`, + }); + } + if (commandName === 'parameter_presets') { + const command = args?.command; + if (!command) + return errorResponse('Error: command parameter is required'); + const presets = getCommandPresets(command); + if (presets.length === 0) { + return jsonResponse({ + error: `No presets available for command: ${command}`, + tip: 'Try hana_examples for usage examples instead', + commandsWithPresets: getCommandsWithPresets(), + }); + } + return jsonResponse({ + command, presets, total: presets.length, + usage: 'Replace placeholder values (e.g., ) with your actual values', + }); + } + if (commandName === 'recommend') { + const intent = args?.intent; + const limit = args?.limit || 5; + if (!intent) + return errorResponse('Error: intent parameter is required. Describe what you want to do in natural language.'); + const recommendations = recommendCommands(intent, limit); + if (recommendations.length === 0) { + return jsonResponse({ + message: 'No commands found matching your intent', intent, + tip: 'Try using different words or browse by category with hana_discover_categories', + }); + } + return jsonResponse({ + intent, + recommendations: recommendations.map(rec => ({ + command: `hana_${rec.command}`, confidence: rec.confidence, reason: rec.reason, + category: rec.category, tags: rec.tags, useCases: rec.useCases, + exampleParameters: rec.exampleParameters, + howToUse: rec.exampleParameters + ? `Call hana_${rec.command} with parameters: ${JSON.stringify(rec.exampleParameters)}` + : `Call hana_${rec.command}`, + })), + total: recommendations.length, + }); + } + if (commandName === 'quickstart') { + const guide = getQuickStartGuide(); + return jsonResponse({ + title: 'Quick Start Guide for SAP HANA CLI', + description: 'Follow these steps to get started with your database', + steps: guide.map(step => ({ + order: step.order, command: `hana_${step.command}`, + description: step.description, purpose: step.purpose, + parameters: step.parameters, tips: step.tips, + })), + totalSteps: guide.length, + recommendation: 'Execute these commands in order. Each step builds on the previous one.', + }); + } + if (commandName === 'troubleshoot') { + const command = args?.command; + if (!command) + return errorResponse('Error: command parameter is required'); + const guide = getTroubleshootingGuide(command); + if (!guide) { + return jsonResponse({ + error: `No troubleshooting guide available for command: ${command}`, + availableGuides: ['import', 'export', 'dataProfile', 'tables', 'status', 'healthCheck'], + }); + } + return jsonResponse({ + command: guide.command, prerequisites: guide.prerequisites, + commonIssues: guide.commonIssues.map((issue) => ({ + issue: issue.issue, solution: issue.solution, + suggestedCommand: issue.command ? `hana_${issue.command}` : undefined, + parameters: issue.parameters, + })), + tips: guide.tips, + }); + } + if (commandName === 'interpret_result') { + const command = args?.command; + const result = args?.result; + if (!command || !result) + return errorResponse('Error: both command and result parameters are required'); + const interpretation = interpretResult(command, result); + return jsonResponse({ + ...interpretation, + usage: interpretation.recommendations.length > 0 + ? 'Follow recommendations in priority order for best results' : undefined, + }); + } + if (commandName === 'conversation_templates') { + const templates = listConversationTemplates(); + return jsonResponse({ + message: 'Available conversation templates', + templates: templates.map(t => ({ + scenario: t.scenario, description: t.description, goal: t.goal, + usage: `Use hana_get_template with scenario="${t.scenario}" to see full details`, + })), + total: templates.length, + }); + } + if (commandName === 'get_template') { + const scenario = args?.scenario; + if (!scenario) + return errorResponse('Error: scenario parameter is required'); + const template = getConversationTemplate(scenario); + if (!template) { + return jsonResponse({ + error: `Template not found: ${scenario}`, + availableTemplates: listConversationTemplates().map(t => t.scenario), + }); + } + return jsonResponse({ ...template, usage: 'Follow steps in order. Each step builds on previous results.' }); + } + return null; +} +//# sourceMappingURL=content-tools.js.map \ No newline at end of file diff --git a/mcp-server/build/tools/content-tools.js.map b/mcp-server/build/tools/content-tools.js.map new file mode 100644 index 00000000..7c7c6f99 --- /dev/null +++ b/mcp-server/build/tools/content-tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"content-tools.js","sourceRoot":"","sources":["../../src/tools/content-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 new file mode 100644 index 00000000..7972cef8 --- /dev/null +++ b/mcp-server/build/tools/discovery-tools.d.ts @@ -0,0 +1,4 @@ +import { ToolDefinition, ToolResponse } from './types.js'; +export declare function getDiscoveryToolDefinitions(): ToolDefinition[]; +export declare function handleDiscoveryTool(commandName: string, args: Record): 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 new file mode 100644 index 00000000..2b339fcc --- /dev/null +++ b/mcp-server/build/tools/discovery-tools.d.ts.map @@ -0,0 +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 diff --git a/mcp-server/build/tools/discovery-tools.js b/mcp-server/build/tools/discovery-tools.js new file mode 100644 index 00000000..6ba015b8 --- /dev/null +++ b/mcp-server/build/tools/discovery-tools.js @@ -0,0 +1,175 @@ +import { jsonResponse, errorResponse } from './types.js'; +import { CATEGORIES, getCommandsInCategory, searchCommandsByTag, getAllWorkflows, searchWorkflowsByTag, getWorkflowById, } from '../command-metadata.js'; +export function getDiscoveryToolDefinitions() { + return [ + { + name: 'hana_discover_categories', + description: 'Discover available command categories and get an overview of what each category does. Use this to find commands for a specific task.', + inputSchema: { type: 'object', properties: {}, required: [] }, + }, + { + name: 'hana_discover_by_category', + description: 'Get all commands in a specific category. Useful for finding commands when you know the general area (e.g., "data-tools", "performance-monitoring").', + inputSchema: { + type: 'object', + properties: { + category: { + type: 'string', + description: 'The category to query (e.g., "data-tools", "schema-tools", "object-inspection", "analysis-tools", "performance-monitoring", "backup-recovery", "system-admin", "system-tools", "security", "mass-operations", "connection-auth", "btp-integration", "hana-cloud", "hdi-management", "developer-tools")', + }, + }, + required: ['category'], + }, + }, + { + name: 'hana_discover_by_tag', + description: 'Search commands by tag. Tags help identify commands for specific purposes (e.g., "import", "export", "validation", "performance", "user", "privilege").', + inputSchema: { + type: 'object', + properties: { + tag: { + type: 'string', + description: 'The tag to search for (e.g., "import", "export", "validation", "performance", "user", "security")', + }, + }, + required: ['tag'], + }, + }, + { + name: 'hana_workflows', + description: 'List available workflows - multi-step task sequences for common scenarios like data validation, performance analysis, security audits, and backup procedures.', + inputSchema: { type: 'object', properties: {}, required: [] }, + }, + { + name: 'hana_workflow_by_id', + description: 'Get detailed steps for a specific workflow. Provides complete instructions including commands, parameters, and expected outputs.', + inputSchema: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Workflow ID (e.g., "validate-and-profile", "export-and-import", "performance-analysis", "security-audit", "backup-and-verify")', + }, + }, + required: ['id'], + }, + }, + { + name: 'hana_search_workflows', + description: 'Search for workflows by tag or purpose. Find workflows for specific scenarios.', + inputSchema: { + type: 'object', + properties: { + tag: { + type: 'string', + description: 'Search tag (e.g., "data-quality", "performance", "security", "backup", "migration")', + }, + }, + required: ['tag'], + }, + }, + ]; +} +export function handleDiscoveryTool(commandName, args) { + if (commandName === 'discover_categories') { + const categoryList = Object.entries(CATEGORIES).map(([key, value]) => ({ + id: key, + name: value.name, + description: value.description, + total: getCommandsInCategory(key).length, + })); + return jsonResponse({ + message: 'Available command categories', + categories: categoryList, + usage: 'Use hana_discover_by_category to get commands in a specific category', + }); + } + if (commandName === 'discover_by_category') { + const category = args?.category; + if (!category) + return errorResponse('Error: category parameter is required'); + const commands = getCommandsInCategory(category); + if (commands.length === 0) { + return jsonResponse({ + error: `No commands found in category: ${category}`, + tip: 'Use hana_discover_categories to see available categories', + }); + } + return jsonResponse({ + category, + categoryInfo: CATEGORIES[category], + commands: commands.map(cmd => ({ + command: cmd.command, category: cmd.category, + tags: cmd.tags, useCases: cmd.useCases, relatedCommands: cmd.relatedCommands, + })), + total: commands.length, + }); + } + if (commandName === 'discover_by_tag') { + const tag = args?.tag; + if (!tag) + return errorResponse('Error: tag parameter is required'); + const commands = searchCommandsByTag(tag); + if (commands.length === 0) { + return jsonResponse({ + error: `No commands found with tag: ${tag}`, + tip: 'Try different tags or use hana_discover_by_category to browse', + }); + } + return jsonResponse({ + tag, + commands: commands.map(cmd => ({ + command: cmd.command, category: cmd.category, + tags: cmd.tags, useCases: cmd.useCases, relatedCommands: cmd.relatedCommands, + })), + total: commands.length, + }); + } + if (commandName === 'workflows') { + const workflows = getAllWorkflows(); + return jsonResponse({ + message: 'Available workflows for common multi-step tasks', + workflows: workflows.map(wf => ({ + id: wf.id, name: wf.name, description: wf.description, + goal: wf.goal, estimatedTime: wf.estimatedTime, tags: wf.tags, steps: wf.steps.length, + })), + total: workflows.length, + usage: 'Use hana_workflow_by_id to see detailed steps for a workflow', + }); + } + if (commandName === 'workflow_by_id') { + const id = args?.id; + if (!id) + return errorResponse('Error: id parameter is required'); + const workflow = getWorkflowById(id); + if (!workflow) { + return jsonResponse({ + error: `Workflow not found: ${id}`, + tip: 'Use hana_workflows to see available workflow IDs', + }); + } + return jsonResponse(workflow); + } + if (commandName === 'search_workflows') { + const tag = args?.tag; + if (!tag) + return errorResponse('Error: tag parameter is required'); + const workflows = searchWorkflowsByTag(tag); + if (workflows.length === 0) { + return jsonResponse({ + error: `No workflows found with tag: ${tag}`, + tip: 'Use hana_workflows to see available workflows', + }); + } + return jsonResponse({ + tag, + workflows: workflows.map(wf => ({ + id: wf.id, name: wf.name, description: wf.description, + goal: wf.goal, estimatedTime: wf.estimatedTime, tags: wf.tags, + })), + total: workflows.length, + }); + } + return null; +} +//# sourceMappingURL=discovery-tools.js.map \ No newline at end of file diff --git a/mcp-server/build/tools/discovery-tools.js.map b/mcp-server/build/tools/discovery-tools.js.map new file mode 100644 index 00000000..0f925e78 --- /dev/null +++ b/mcp-server/build/tools/discovery-tools.js.map @@ -0,0 +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 diff --git a/mcp-server/build/tools/search-tools.d.ts b/mcp-server/build/tools/search-tools.d.ts new file mode 100644 index 00000000..14f22397 --- /dev/null +++ b/mcp-server/build/tools/search-tools.d.ts @@ -0,0 +1,4 @@ +import { ToolDefinition, ToolResponse } from './types.js'; +export declare function getSearchToolDefinitions(): ToolDefinition[]; +export declare function handleSearchTool(commandName: string, args: Record): ToolResponse | null; +//# sourceMappingURL=search-tools.d.ts.map \ No newline at end of file diff --git a/mcp-server/build/tools/search-tools.d.ts.map b/mcp-server/build/tools/search-tools.d.ts.map new file mode 100644 index 00000000..4e5870c8 --- /dev/null +++ b/mcp-server/build/tools/search-tools.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"search-tools.d.ts","sourceRoot":"","sources":["../../src/tools/search-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAA+B,MAAM,YAAY,CAAC;AAIvF,wBAAgB,wBAAwB,IAAI,cAAc,EAAE,CAqC3D;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,YAAY,GAAG,IAAI,CAiFpG"} \ No newline at end of file diff --git a/mcp-server/build/tools/search-tools.js b/mcp-server/build/tools/search-tools.js new file mode 100644 index 00000000..c3c3727a --- /dev/null +++ b/mcp-server/build/tools/search-tools.js @@ -0,0 +1,114 @@ +import { jsonResponse, errorResponse } from './types.js'; +import { docsSearch } from '../docs-search.js'; +import { smartSearch } from '../smart-search.js'; +export function getSearchToolDefinitions() { + return [ + { + name: 'hana_search', + description: 'Search across all hana-cli resources: documentation, commands, workflows, examples, and presets. Use scope to narrow results. Default searches everything with relevance scoring.', + inputSchema: { + type: 'object', + properties: { + query: { type: 'string', description: 'Search query (keywords or phrases)' }, + scope: { + type: 'string', + enum: ['all', 'docs', 'commands', 'workflows', 'examples', 'presets'], + description: 'What to search. "all" (default) searches everything, "docs" searches documentation website only, others search command metadata.', + }, + category: { type: 'string', description: 'Optional: limit doc search to specific category (getting-started, commands, features, api-reference, development)' }, + docType: { + type: 'string', + enum: ['tutorial', 'command', 'api', 'feature', 'troubleshooting', 'development', 'general'], + description: 'Optional: filter docs by document type', + }, + limit: { type: 'number', default: 10, description: 'Maximum number of results to return (default: 10)' }, + }, + required: ['query'], + }, + }, + { + name: 'hana_get_doc', + description: 'Retrieve the full content of a specific documentation page. Use after hana_search to get complete details from a relevant document.', + inputSchema: { + type: 'object', + properties: { + path: { type: 'string', description: 'Document path from search results (e.g., "01-getting-started/installation.md", "02-commands/data-tools/import.md")' }, + }, + required: ['path'], + }, + }, + ]; +} +export function handleSearchTool(commandName, args) { + if (commandName === 'search') { + const query = args?.query; + if (!query) + return errorResponse('Error: query parameter is required'); + const scope = args?.scope || 'all'; + const limit = args?.limit || 10; + const category = args?.category; + const docType = args?.docType; + const results = []; + if (scope === 'all' || scope === 'docs') { + if (docsSearch.isAvailable()) { + const docResults = docsSearch.search(query, { category, docType, limit }); + results.push(...docResults.map(r => ({ + type: 'documentation', + title: r.document.title, + path: r.document.path, + category: r.document.category, + relevance: r.relevance, + excerpt: r.snippet || r.document.excerpt, + url: `https://sap-samples.github.io/hana-developer-cli-tool-example/${r.document.path.replace('.md', '.html')}`, + }))); + } + } + if (scope === 'all' || scope !== 'docs') { + const smartScope = scope === 'all' ? 'all' : scope; + const smartResults = smartSearch(query, smartScope, limit); + if (smartResults.results) { + results.push(...smartResults.results.map((r) => ({ + type: r.type, + name: r.name, + relevance: r.relevance, + description: r.description, + howToUse: r.howToUse, + }))); + } + } + results.sort((a, b) => (b.relevance || 0) - (a.relevance || 0)); + const limited = results.slice(0, limit); + return jsonResponse({ + query, scope, totalResults: limited.length, + results: limited, + tip: limited.length > 0 + ? 'Use hana_get_doc with the path to read full documentation content' + : 'No matches found. Try different keywords or use hana_discover_categories to browse.', + }); + } + if (commandName === 'get_doc') { + const path = args?.path; + if (!path) + return errorResponse('Error: path parameter is required'); + if (!docsSearch.isAvailable()) { + return errorResponse('Documentation index not available. Run "npm run build:docs-index" in the project root.'); + } + const document = docsSearch.getDocument(path); + const content = docsSearch.getDocumentContent(path); + if (!document || !content) { + return jsonResponse({ + error: `Document not found: ${path}`, + tip: 'Use hana_search to find valid document paths', + }); + } + return jsonResponse({ + title: document.title, path: document.path, + category: document.category, docType: document.docType, + url: `https://sap-samples.github.io/hana-developer-cli-tool-example/${path.replace('.md', '.html')}`, + headings: document.headings, content, relatedLinks: document.links, + lastModified: document.lastModified, + }); + } + return null; +} +//# sourceMappingURL=search-tools.js.map \ No newline at end of file diff --git a/mcp-server/build/tools/search-tools.js.map b/mcp-server/build/tools/search-tools.js.map new file mode 100644 index 00000000..e9a2834c --- /dev/null +++ b/mcp-server/build/tools/search-tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"search-tools.js","sourceRoot":"","sources":["../../src/tools/search-tools.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/mcp-server/build/tools/types.d.ts b/mcp-server/build/tools/types.d.ts new file mode 100644 index 00000000..de1c34bc --- /dev/null +++ b/mcp-server/build/tools/types.d.ts @@ -0,0 +1,21 @@ +export interface ToolDefinition { + name: string; + description: string; + inputSchema: { + type: string; + properties: Record; + required?: string[]; + }; +} +export interface ToolResponse { + content: Array<{ + type: string; + text: string; + }>; + isError?: boolean; + [key: string]: unknown; +} +export declare function textResponse(text: string): ToolResponse; +export declare function jsonResponse(data: any): ToolResponse; +export declare function errorResponse(message: string): ToolResponse; +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/mcp-server/build/tools/types.d.ts.map b/mcp-server/build/tools/types.d.ts.map new file mode 100644 index 00000000..0a73e88c --- /dev/null +++ b/mcp-server/build/tools/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAEvD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,YAAY,CAEpD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAE3D"} \ No newline at end of file diff --git a/mcp-server/build/tools/types.js b/mcp-server/build/tools/types.js new file mode 100644 index 00000000..e9c54bcd --- /dev/null +++ b/mcp-server/build/tools/types.js @@ -0,0 +1,10 @@ +export function textResponse(text) { + return { content: [{ type: 'text', text }] }; +} +export function jsonResponse(data) { + return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] }; +} +export function errorResponse(message) { + return { content: [{ type: 'text', text: message }], isError: true }; +} +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/mcp-server/build/tools/types.js.map b/mcp-server/build/tools/types.js.map new file mode 100644 index 00000000..bc307dd8 --- /dev/null +++ b/mcp-server/build/tools/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAS;IACpC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACvE,CAAC"} \ No newline at end of file diff --git a/mcp-server/build/workflow-execution.d.ts b/mcp-server/build/workflow-execution.d.ts deleted file mode 100644 index 58aaa2e2..00000000 --- a/mcp-server/build/workflow-execution.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Workflow execution system - * Executes multi-step workflows with parameter substitution - */ -import { Workflow } from './command-metadata.js'; -export interface WorkflowExecutionResult { - workflowId: string; - workflowName: string; - totalSteps: number; - completedSteps: number; - failedStep?: number; - results: StepResult[]; - success: boolean; - duration?: number; -} -export interface StepResult { - step: number; - command: string; - parameters: Record; - success: boolean; - output?: string; - error?: string; - duration?: number; -} -/** - * Validate that all required parameters are provided - */ -export declare function validateWorkflowParameters(workflow: Workflow, parameters: Record): { - valid: boolean; - missing: string[]; -}; -/** - * Simulate workflow execution (dry run) - * In production, this would call executeCommand for each step - */ -export declare function executeWorkflow(workflowId: string, parameters: Record, stopOnError?: boolean): Promise; -/** - * Get workflow preview with substituted parameters - */ -export declare function previewWorkflow(workflowId: string, parameters: Record): any; -//# sourceMappingURL=workflow-execution.d.ts.map \ No newline at end of file diff --git a/mcp-server/build/workflow-execution.d.ts.map b/mcp-server/build/workflow-execution.d.ts.map deleted file mode 100644 index caf81dbf..00000000 --- a/mcp-server/build/workflow-execution.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"workflow-execution.d.ts","sourceRoot":"","sources":["../src/workflow-execution.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAoC,QAAQ,EAAgB,MAAM,uBAAuB,CAAC;AAEjG,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA6BD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA0BvC;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,WAAW,GAAE,OAAc,GAC1B,OAAO,CAAC,uBAAuB,CAAC,CAyElC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,GAAG,CA+BL"} \ No newline at end of file diff --git a/mcp-server/build/workflow-execution.js b/mcp-server/build/workflow-execution.js deleted file mode 100644 index 4bd62755..00000000 --- a/mcp-server/build/workflow-execution.js +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Workflow execution system - * Executes multi-step workflows with parameter substitution - */ -import { getWorkflowById } from './command-metadata.js'; -/** - * Substitute parameters in workflow steps - */ -function substituteParameters(parameters, parameterTemplate) { - const result = {}; - for (const [key, value] of Object.entries(parameterTemplate)) { - if (typeof value === 'string' && value.startsWith('<') && value.endsWith('>')) { - // Extract parameter name from format - const paramName = value.slice(1, -1); - if (parameters[paramName]) { - result[key] = parameters[paramName]; - } - else { - // Keep placeholder if no value provided - result[key] = value; - } - } - else { - result[key] = value; - } - } - return result; -} -/** - * Validate that all required parameters are provided - */ -export function validateWorkflowParameters(workflow, parameters) { - const required = new Set(); - // Extract all required parameters from workflow steps - for (const step of workflow.steps) { - if (step.keyParameters) { - for (const value of Object.values(step.keyParameters)) { - if (typeof value === 'string' && value.startsWith('<') && value.endsWith('>')) { - const paramName = value.slice(1, -1); - required.add(paramName); - } - } - } - } - const missing = []; - for (const param of required) { - if (!parameters[param]) { - missing.push(param); - } - } - return { - valid: missing.length === 0, - missing, - }; -} -/** - * Simulate workflow execution (dry run) - * In production, this would call executeCommand for each step - */ -export async function executeWorkflow(workflowId, parameters, stopOnError = true) { - const workflow = getWorkflowById(workflowId); - if (!workflow) { - return { - workflowId, - workflowName: 'Unknown', - totalSteps: 0, - completedSteps: 0, - results: [], - success: false, - error: `Workflow not found: ${workflowId}`, - }; - } - // Validate parameters - const validation = validateWorkflowParameters(workflow, parameters); - if (!validation.valid) { - return { - workflowId, - workflowName: workflow.name, - totalSteps: workflow.steps.length, - completedSteps: 0, - results: [], - success: false, - error: `Missing required parameters: ${validation.missing.join(', ')}`, - }; - } - const results = []; - const startTime = Date.now(); - let completedSteps = 0; - let failedStep; - for (const step of workflow.steps) { - const stepStartTime = Date.now(); - const stepParameters = step.keyParameters - ? substituteParameters(parameters, step.keyParameters) - : {}; - // Note: In production, this would call executeCommand(step.command, stepParameters) - // For now, we simulate the execution - const stepResult = { - step: step.order, - command: step.command, - parameters: stepParameters, - success: true, // Simulated success - output: `Successfully executed ${step.command}`, - duration: Date.now() - stepStartTime, - }; - results.push(stepResult); - if (stepResult.success) { - completedSteps++; - } - else { - failedStep = step.order; - if (stopOnError) { - break; - } - } - } - return { - workflowId, - workflowName: workflow.name, - totalSteps: workflow.steps.length, - completedSteps, - failedStep, - results, - success: completedSteps === workflow.steps.length, - duration: Date.now() - startTime, - }; -} -/** - * Get workflow preview with substituted parameters - */ -export function previewWorkflow(workflowId, parameters) { - const workflow = getWorkflowById(workflowId); - if (!workflow) { - return { - error: `Workflow not found: ${workflowId}`, - }; - } - const validation = validateWorkflowParameters(workflow, parameters); - return { - workflowId: workflow.id, - name: workflow.name, - description: workflow.description, - goal: workflow.goal, - estimatedTime: workflow.estimatedTime, - validation: { - valid: validation.valid, - missingParameters: validation.missing, - }, - steps: workflow.steps.map(step => ({ - order: step.order, - command: step.command, - description: step.description, - parameters: step.keyParameters - ? substituteParameters(parameters, step.keyParameters) - : {}, - expectedOutput: step.expectedOutput, - })), - }; -} -//# sourceMappingURL=workflow-execution.js.map \ No newline at end of file diff --git a/mcp-server/build/workflow-execution.js.map b/mcp-server/build/workflow-execution.js.map deleted file mode 100644 index 126c2732..00000000 --- a/mcp-server/build/workflow-execution.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"workflow-execution.js","sourceRoot":"","sources":["../src/workflow-execution.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAmB,eAAe,EAA0B,MAAM,uBAAuB,CAAC;AAuBjG;;GAEG;AACH,SAAS,oBAAoB,CAC3B,UAAkC,EAClC,iBAAyC;IAEzC,MAAM,MAAM,GAAwB,EAAE,CAAC;IAEvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9E,kDAAkD;YAClD,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1B,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACN,wCAAwC;gBACxC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACtB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAAkB,EAClB,UAAkC;IAElC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IAEnC,sDAAsD;IACtD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;gBACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9E,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;oBACrC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC;QAC3B,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,UAAkC,EAClC,cAAuB,IAAI;IAE3B,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAE7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,UAAU;YACV,YAAY,EAAE,SAAS;YACvB,UAAU,EAAE,CAAC;YACb,cAAc,EAAE,CAAC;YACjB,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,uBAAuB,UAAU,EAAE;SACpC,CAAC;IACX,CAAC;IAED,sBAAsB;IACtB,MAAM,UAAU,GAAG,0BAA0B,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACpE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO;YACL,UAAU;YACV,YAAY,EAAE,QAAQ,CAAC,IAAI;YAC3B,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;YACjC,cAAc,EAAE,CAAC;YACjB,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,gCAAgC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAChE,CAAC;IACX,CAAC;IAED,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,UAA8B,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACjC,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa;YACvC,CAAC,CAAC,oBAAoB,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC;YACtD,CAAC,CAAC,EAAE,CAAC;QAEP,oFAAoF;QACpF,qCAAqC;QACrC,MAAM,UAAU,GAAe;YAC7B,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,cAAc;YAC1B,OAAO,EAAE,IAAI,EAAE,oBAAoB;YACnC,MAAM,EAAE,yBAAyB,IAAI,CAAC,OAAO,EAAE;YAC/C,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa;SACrC,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEzB,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,cAAc,EAAE,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC;YACxB,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,UAAU;QACV,YAAY,EAAE,QAAQ,CAAC,IAAI;QAC3B,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;QACjC,cAAc;QACd,UAAU;QACV,OAAO;QACP,OAAO,EAAE,cAAc,KAAK,QAAQ,CAAC,KAAK,CAAC,MAAM;QACjD,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;KACjC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,UAAkB,EAClB,UAAkC;IAElC,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAE7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,KAAK,EAAE,uBAAuB,UAAU,EAAE;SAC3C,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,0BAA0B,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAEpE,OAAO;QACL,UAAU,EAAE,QAAQ,CAAC,EAAE;QACvB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,UAAU,EAAE;YACV,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,iBAAiB,EAAE,UAAU,CAAC,OAAO;SACtC;QACD,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,aAAa;gBAC5B,CAAC,CAAC,oBAAoB,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC;gBACtD,CAAC,CAAC,EAAE;YACN,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"} \ No newline at end of file diff --git a/mcp-server/npm-shrinkwrap.json b/mcp-server/npm-shrinkwrap.json index 91fef94b..71f49932 100644 --- a/mcp-server/npm-shrinkwrap.json +++ b/mcp-server/npm-shrinkwrap.json @@ -9,7 +9,7 @@ "version": "1.202604.0", "license": "SEE LICENSE IN ../LICENSE", "dependencies": { - "@modelcontextprotocol/sdk": "^1.27.1" + "@modelcontextprotocol/sdk": "^1.29.0" }, "bin": { "hana-cli-mcp-server": "build/index.js" @@ -32,9 +32,9 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz", - "integrity": "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==", + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz", + "integrity": "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==", "license": "MIT", "dependencies": { "@hono/node-server": "^1.19.9", diff --git a/mcp-server/package.json b/mcp-server/package.json index 2b1cc3db..d59e258d 100644 --- a/mcp-server/package.json +++ b/mcp-server/package.json @@ -19,7 +19,7 @@ "author": "SAP", "license": "SEE LICENSE IN ../LICENSE", "dependencies": { - "@modelcontextprotocol/sdk": "^1.27.1" + "@modelcontextprotocol/sdk": "^1.29.0" }, "devDependencies": { "@types/node": "^25.5.0", diff --git a/mcp-server/src/executor.ts b/mcp-server/src/executor.ts index 4b34c1dc..1cc12aa6 100644 --- a/mcp-server/src/executor.ts +++ b/mcp-server/src/executor.ts @@ -388,25 +388,6 @@ export async function executeCommand( }); } -/** - * Validates that required environment variables are set for database connection - */ -export function validateEnvironment(): { valid: boolean; message?: string } { - // The hana-cli tool uses various connection methods: - // - .env files or default-env.json in the project root - // - Connection parameters passed via CLI (--conn, --user, --password, etc.) - // - Service keys and BTP connections - // - // Most commands don't strictly require these at validation time - // since connection errors are handled at command execution - // - // Some commands like 'version' and 'help' work without any connection - - // For now, we'll allow commands to run and let the CLI handle connection validation - // This provides better error messages from the actual command execution - return { valid: true }; -} - /** * Formats execution result for display using the output formatter */ diff --git a/mcp-server/src/index.ts b/mcp-server/src/index.ts index 10702d20..f0408226 100644 --- a/mcp-server/src/index.ts +++ b/mcp-server/src/index.ts @@ -2,15 +2,10 @@ /** * MCP Server for SAP HANA CLI - * - * CRITICAL: This file implements the Model Context Protocol (MCP) server. - * MCP communicates via JSON-RPC over STDIO. All logging MUST use console.error() - * to write to stderr, never console.log() which writes to stdout. - * - * Any non-JSON output to stdout will break the protocol and cause errors like: - * "Failed to parse message: ..." - * - * Use console.error() for all logging throughout this file and in modules it imports. + * + * CRITICAL: MCP communicates via JSON-RPC over STDIO. All logging MUST use + * console.error() (stderr), never console.log() (stdout). Any non-JSON output + * to stdout will break the protocol. */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; @@ -23,39 +18,25 @@ import { ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; -import { fileURLToPath, pathToFileURL } from 'url'; +import { pathToFileURL } from 'url'; import { dirname, join } from 'path'; -import { extractCommandInfo } from './command-parser.js'; -import { executeCommand, formatResult, validateEnvironment } from './executor.js'; -import { ConnectionContext } from './connection-context.js'; -import { CATEGORIES, getCommandsByCategory, searchCommandsByTag, getCommandsInCategory, getAllWorkflows, searchWorkflowsByTag, getWorkflowById } from './command-metadata.js'; -import { getCommandExamples, getCommandPresets, hasExamples, hasPresets, getCommandsWithExamples, getCommandsWithPresets } from './examples-presets.js'; -import { recommendCommands, getQuickStartGuide } from './recommendation.js'; -import { getTroubleshootingGuide } from './next-steps.js'; -import { previewWorkflow, executeWorkflow } from './workflow-execution.js'; -import { interpretResult } from './result-interpretation.js'; -import { smartSearch } from './smart-search.js'; -import { getConversationTemplate, listConversationTemplates } from './conversation-templates.js'; -import ReadmeKnowledgeBase from './readme-knowledge-base.js'; -import { docsSearch } from './docs-search.js'; +import { fileURLToPath } from 'url'; +import { readFileSync } from 'fs'; import { listResources, readResource } from './resources.js'; 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 { errorResponse } from './tools/types.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); -/** - * Sanitize tool name to conform to MCP naming rules [a-z0-9_-] - */ -function sanitizeToolName(name: string): string { - return name.replace(/[^a-z0-9_-]/g, '_'); -} +const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'mcp-server', 'package.json'), 'utf-8')) as { + version: string; +}; -/** - * MCP Server for SAP HANA CLI Tools - * - * Exposes all hana-cli commands as MCP tools that can be called by LLMs - */ class HanaCliMcpServer { private server: Server; private commands: Map = new Map(); @@ -67,7 +48,7 @@ class HanaCliMcpServer { this.server = new Server( { name: 'hana-cli-mcp-server', - version: '1.0.0', + version: pkg.version, icons: [ { src: iconPngDataUri, @@ -103,1621 +84,47 @@ class HanaCliMcpServer { private setupHandlers(): void { this.setupResourceHandlers(); this.setupPromptHandlers(); - - // List available tools - this.server.setRequestHandler(ListToolsRequestSchema, async () => { - const tools = []; - - for (const [name, commandModule] of this.commands) { - const info = extractCommandInfo(commandModule); - - // Build rich description with metadata - let fullDescription = info.description; - - // Add category and tags inline - if (info.category) { - fullDescription += ` [Category: ${info.category}]`; - } - if (info.tags && info.tags.length > 0) { - fullDescription += ` [Tags: ${info.tags.join(', ')}]`; - } - - // Add use cases if available - if (info.useCases && info.useCases.length > 0) { - fullDescription += `\n\n**Common Use Cases:**\n${info.useCases.map(uc => `- ${uc}`).join('\n')}`; - } - - // Add related commands - if (info.relatedCommands && info.relatedCommands.length > 0) { - fullDescription += `\n\n**Related Commands:** ${info.relatedCommands.map(rc => `hana_${rc}`).join(', ')}`; - } - - // Add tip about examples/presets if available - if (hasExamples(name)) { - fullDescription += `\n\n💡 **Tip:** Use \`hana_examples\` with command="${name}" to see usage examples.`; - } - if (hasPresets(name)) { - fullDescription += `\n\n📋 **Tip:** Use \`hana_parameter_presets\` with command="${name}" to see parameter templates.`; - } - - // Extend schema with project context parameter - const extendedSchema = { - ...info.schema, - properties: { - ...(info.schema.properties || {}), - __projectContext: { - type: 'object', - description: 'Project-specific connection context (optional). Use this to connect to a project-specific database instead of the default. The CLI will use connection files from the specified projectPath.', - properties: { - projectPath: { - type: 'string', - description: 'Absolute path to the project directory. Example: "C:/Users/dev/projects/my-app" or "/home/user/projects/my-app"' - }, - connectionFile: { - type: 'string', - description: 'Connection file name relative to projectPath. Example: ".env" or "default-env.json". If provided, the CLI will use this specific file.' - }, - host: { - type: 'string', - description: 'Database host (for direct connection). Example: "database.example.com"' - }, - port: { - type: 'number', - description: 'Database port (for direct connection). Default is 30013.' - }, - user: { - type: 'string', - description: 'Database user (for direct connection). Example: "DBADMIN"' - }, - password: { - type: 'string', - description: 'Database password (for direct connection). SECURITY WARNING: Use connection files instead of hardcoding passwords.' - }, - database: { - type: 'string', - description: 'Database name (for direct connection). Default is "SYSTEMDB".' - } - } - } - } - }; - - tools.push({ - name: `hana_${sanitizeToolName(name)}`, - description: fullDescription, - inputSchema: extendedSchema, - }); - - // Also register aliases - if (info.aliases && info.aliases.length > 0) { - for (const alias of info.aliases) { - tools.push({ - name: `hana_${sanitizeToolName(alias)}`, - description: `${fullDescription} (alias for ${name})`, - inputSchema: extendedSchema, - }); - } - } - } - - // Add discovery tools - tools.push({ - name: 'hana_discover_categories', - description: 'Discover available command categories and get an overview of what each category does. Use this to find commands for a specific task.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_discover_by_category', - description: 'Get all commands in a specific category. Useful for finding commands when you know the general area (e.g., "data-quality", "performance-analysis").', - inputSchema: { - type: 'object', - properties: { - category: { - type: 'string', - description: 'The category to query (e.g., "data-tools", "schema-tools", "object-inspection", "analysis-tools", "performance-monitoring", "backup-recovery", "system-admin", "system-tools", "security", "mass-operations", "connection-auth", "btp-integration", "hana-cloud", "hdi-management", "developer-tools")', - }, - }, - required: ['category'], - }, - }); - - tools.push({ - name: 'hana_discover_by_tag', - description: 'Search commands by tag. Tags help identify commands for specific purposes (e.g., "import", "export", "validation", "performance", "user", "privilege").', - inputSchema: { - type: 'object', - properties: { - tag: { - type: 'string', - description: 'The tag to search for (e.g., "import", "export", "validation", "performance", "user", "security")', - }, - }, - required: ['tag'], - }, - }); - - tools.push({ - name: 'hana_workflows', - description: 'List available workflows - multi-step task sequences for common scenarios like data validation, performance analysis, security audits, and backup procedures.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_workflow_by_id', - description: 'Get detailed steps for a specific workflow. Provides complete instructions including commands, parameters, and expected outputs.', - inputSchema: { - type: 'object', - properties: { - id: { - type: 'string', - description: 'Workflow ID (e.g., "validate-and-profile", "export-and-import", "performance-analysis", "security-audit", "backup-and-verify")', - }, - }, - required: ['id'], - }, - }); - - tools.push({ - name: 'hana_search_workflows', - description: 'Search for workflows by tag or purpose. Find workflows for specific scenarios.', - inputSchema: { - type: 'object', - properties: { - tag: { - type: 'string', - description: 'Search tag (e.g., "data-quality", "performance", "security", "backup", "migration")', - }, - }, - required: ['tag'], - }, - }); - - tools.push({ - name: 'hana_examples', - description: 'Get real-world usage examples for a specific command with parameter combinations, scenarios, and expected outputs. Essential for understanding how to use commands correctly.', - inputSchema: { - type: 'object', - properties: { - command: { - type: 'string', - description: 'Command name (without hana_ prefix, e.g., "import", "export", "dataProfile")', - }, - }, - required: ['command'], - }, - }); - - tools.push({ - name: 'hana_parameter_presets', - description: 'Get parameter presets/templates for common use cases of a command. Shows pre-configured parameter combinations for scenarios like "quick-import", "safe-import", "large-file" etc.', - inputSchema: { - type: 'object', - properties: { - command: { - type: 'string', - description: 'Command name (without hana_ prefix)', - }, - }, - required: ['command'], - }, - }); - - tools.push({ - name: 'hana_commands_with_examples', - description: 'List all commands that have usage examples available. Use this to discover which commands have detailed examples.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - // Phase 2: Enhanced Discovery Tools - tools.push({ - name: 'hana_recommend', - description: 'Get command recommendations based on natural language intent. Tell me what you want to do, and I\'ll suggest the best commands. Example: "find duplicate rows", "check database version", "export table to CSV".', - inputSchema: { - type: 'object', - properties: { - intent: { - type: 'string', - description: 'What you want to accomplish in natural language (e.g., "import CSV file", "find slow queries", "check user permissions")', - }, - limit: { - type: 'number', - description: 'Maximum number of recommendations to return (default: 5)', - default: 5, - }, - }, - required: ['intent'], - }, - }); - - tools.push({ - name: 'hana_quickstart', - description: 'Get a beginner-friendly quick start guide with the recommended first 6 commands to run when starting with the database. Perfect for new users or initial database exploration.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_troubleshoot', - description: 'Get troubleshooting guide for a specific command including common issues, solutions, prerequisites, and tips. Essential when a command isn\'t working as expected.', - inputSchema: { - type: 'object', - properties: { - command: { - type: 'string', - description: 'Command name (without hana_ prefix) to get troubleshooting help for', - }, - }, - required: ['command'], - }, - }); - - // Phase 3: Advanced Features - tools.push({ - name: 'hana_execute_workflow', - description: 'Execute a complete multi-step workflow with automatic parameter substitution. Runs multiple commands in sequence according to the workflow definition. Use hana_preview_workflow first to see what will be executed.', - inputSchema: { - type: 'object', - properties: { - workflowId: { - type: 'string', - description: 'Workflow ID from hana_workflows (e.g., "validate-and-profile", "export-and-import")', - }, - parameters: { - type: 'object', - description: 'Parameters to substitute in workflow commands. Keys are parameter names, values are actual values (e.g., {"table-name": "CUSTOMERS", "schema-name": "SALES"})', - }, - stopOnError: { - type: 'boolean', - default: true, - description: 'Stop workflow execution if any command fails', - }, - }, - required: ['workflowId', 'parameters'], - }, - }); - - tools.push({ - name: 'hana_preview_workflow', - description: 'Preview what commands will be executed in a workflow with your parameters substituted. Shows all steps, commands, and parameters before execution. Always use this before hana_execute_workflow.', - inputSchema: { - type: 'object', - properties: { - workflowId: { - type: 'string', - description: 'Workflow ID to preview', - }, - parameters: { - type: 'object', - description: 'Parameters to substitute', - }, - }, - required: ['workflowId', 'parameters'], - }, - }); - - tools.push({ - name: 'hana_interpret_result', - description: 'Get AI-friendly interpretation of command results with insights, recommendations, and analysis. Provides summary, key metrics, concerns detected, and actionable recommendations.', - inputSchema: { - type: 'object', - properties: { - command: { - type: 'string', - description: 'The command that was executed', - }, - result: { - type: 'string', - description: 'The command output to interpret', - }, - }, - required: ['command', 'result'], - }, - }); - - tools.push({ - name: 'hana_smart_search', - description: 'Comprehensive search across all resources: commands, workflows, examples, presets, and parameters. More powerful than discover tools - searches everything at once with relevance scoring.', - inputSchema: { - type: 'object', - properties: { - query: { - type: 'string', - description: 'Search query (keywords or phrases)', - }, - scope: { - type: 'string', - enum: ['all', 'commands', 'workflows', 'examples', 'presets'], - default: 'all', - description: 'What to search (default: all)', - }, - limit: { - type: 'number', - default: 20, - description: 'Maximum results to return', - }, - }, - required: ['query'], - }, - }); - - // Documentation Search Tools - tools.push({ - name: 'hana_search_docs', - description: 'Search the comprehensive documentation website (https://sap-samples.github.io/hana-developer-cli-tool-example/) for guides, tutorials, command references, and detailed explanations. Returns relevant documents with excerpts and metadata.', - inputSchema: { - type: 'object', - properties: { - query: { - type: 'string', - description: 'Search query (e.g., "import data", "BTP integration", "connection setup", "performance tuning")', - }, - category: { - type: 'string', - description: 'Optional: limit search to specific category (getting-started, commands, features, api-reference, development)', - }, - docType: { - type: 'string', - enum: ['tutorial', 'command', 'api', 'feature', 'troubleshooting', 'development', 'general'], - description: 'Optional: filter by document type', - }, - limit: { - type: 'number', - default: 10, - description: 'Maximum number of results to return (default: 10)', - }, - }, - required: ['query'], - }, - }); - - tools.push({ - name: 'hana_get_doc', - description: 'Retrieve the full content of a specific documentation page. Use after hana_search_docs to get complete details from a relevant document.', - inputSchema: { - type: 'object', - properties: { - path: { - type: 'string', - description: 'Document path from search results (e.g., "01-getting-started/installation.md", "02-commands/data-tools/import.md")', - }, - }, - required: ['path'], - }, - }); - - tools.push({ - name: 'hana_docs_stats', - description: 'Get documentation statistics including total documents, categories, and document types available. Useful for understanding the scope of available documentation.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_list_doc_categories', - description: 'List all available documentation categories and document types. Use this to understand what documentation is available before searching.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_conversation_templates', - description: 'List available conversation templates for common scenarios. Templates provide step-by-step guided workflows for tasks like data-exploration, troubleshooting, data-migration, performance-tuning, and security-audit.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_get_template', - description: 'Get a detailed conversation template for a specific scenario. Includes all steps, commands, expected outcomes, tips, and common questions with answers.', - inputSchema: { - type: 'object', - properties: { - scenario: { - type: 'string', - description: 'Scenario name (e.g., "data-exploration", "troubleshooting", "data-migration", "performance-tuning", "security-audit")', - }, - }, - required: ['scenario'], - }, - }); - - // Knowledge Base Tools from README and Project Documentation - tools.push({ - name: 'hana_connection_guide', - description: 'Get detailed guide on connection resolution order and best practices. Shows all 7 steps the tool uses to find database credentials (admin, cds bind, .env, --conn parameter, home directory, default-env.json, fallback).', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_standard_parameters', - description: 'Get standardized parameters for a specific command category. Shows parameter conventions, aliases, defaults, and usage examples for command types like data-manipulation, batch-operations, and list-inspect.', - inputSchema: { - type: 'object', - properties: { - category: { - type: 'string', - enum: ['data-manipulation', 'batch-operations', 'list-inspect'], - description: 'Command category to get parameter guide for', - }, - }, - required: ['category'], - }, - }); - - tools.push({ - name: 'hana_security_guide', - description: 'Get comprehensive security best practices and guidelines for using hana-cli. Covers connection configuration, SQL injection protection, parameter security, and environment security.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_best_practices', - description: 'Get naming conventions, alias patterns, and best practice patterns for using the CLI. Includes examples of safe operation patterns, cross-database usage, and batch processing.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_project_structure', - description: 'Get overview of the hana-cli project structure and key documentation resources. Shows all folders, their purposes, and links to relevant README files.', - inputSchema: { - type: 'object', - properties: {}, - required: [], - }, - }); - - tools.push({ - name: 'hana_docs_search', - description: 'Search across all project documentation including command categories, security guidelines, best practices, and resources. Use keywords to find relevant information.', - inputSchema: { - type: 'object', - properties: { - query: { - type: 'string', - description: 'Search query (e.g., "security", "connection", "parameters", "import", "export", "data-quality")', - }, - }, - required: ['query'], - }, - }); + this.server.setRequestHandler(ListToolsRequestSchema, async () => { + const tools = [ + ...getDiscoveryToolDefinitions(), + ...getContentToolDefinitions(), + ...getSearchToolDefinitions(), + ...getCliToolDefinitions(), + ]; return { tools }; }); - // Execute tool calls this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; - - // Remove 'hana_' prefix to get actual command name const commandName = name.startsWith('hana_') ? name.slice(5) : name; - // Handle discovery tools first - if (commandName === 'discover_categories') { - const categoryList = Object.entries(CATEGORIES).map(([key, value]) => ({ - id: key, - name: value.name, - description: value.description, - total: getCommandsInCategory(key).length, - })); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'Available command categories', - categories: categoryList, - usage: 'Use hana_discover_by_category to get commands in a specific category', - }, null, 2), - }, - ], - }; - } - - if (commandName === 'discover_by_category') { - const category = (args as any)?.category; - if (!category) { - return { - content: [ - { - type: 'text', - text: 'Error: category parameter is required', - }, - ], - }; - } - - const commands = getCommandsInCategory(category); - if (commands.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No commands found in category: ${category}`, - tip: 'Use hana_discover_categories to see available categories', - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - category, - categoryInfo: CATEGORIES[category as keyof typeof CATEGORIES], - commands: commands.map(cmd => ({ - command: cmd.command, - category: cmd.category, - tags: cmd.tags, - useCases: cmd.useCases, - relatedCommands: cmd.relatedCommands, - })), - total: commands.length, - }, null, 2), - }, - ], - }; - } - - if (commandName === 'discover_by_tag') { - const tag = (args as any)?.tag; - if (!tag) { - return { - content: [ - { - type: 'text', - text: 'Error: tag parameter is required', - }, - ], - }; - } - - const commands = searchCommandsByTag(tag); - if (commands.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No commands found with tag: ${tag}`, - tip: 'Try different tags or use hana_discover_by_category to browse', - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - tag, - commands: commands.map(cmd => ({ - command: cmd.command, - category: cmd.category, - tags: cmd.tags, - useCases: cmd.useCases, - relatedCommands: cmd.relatedCommands, - })), - total: commands.length, - }, null, 2), - }, - ], - }; - } + const result = + handleDiscoveryTool(commandName, args as Record) ?? + handleContentTool(commandName, args as Record) ?? + handleSearchTool(commandName, args as Record) ?? + await handleCliTool(name, args as Record); - if (commandName === 'workflows') { - const workflows = getAllWorkflows(); - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'Available workflows for common multi-step tasks', - workflows: workflows.map(wf => ({ - id: wf.id, - name: wf.name, - description: wf.description, - goal: wf.goal, - estimatedTime: wf.estimatedTime, - tags: wf.tags, - steps: wf.steps.length, - })), - total: workflows.length, - usage: 'Use hana_workflow_by_id to see detailed steps for a workflow', - }, null, 2), - }, - ], - }; - } - - if (commandName === 'workflow_by_id') { - const id = (args as any)?.id; - if (!id) { - return { - content: [ - { - type: 'text', - text: 'Error: id parameter is required', - }, - ], - }; - } - - const workflow = getWorkflowById(id); - if (!workflow) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `Workflow not found: ${id}`, - tip: 'Use hana_workflows to see available workflow IDs', - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify(workflow, null, 2), - }, - ], - }; - } + if (result) return result; - if (commandName === 'search_workflows') { - const tag = (args as any)?.tag; - if (!tag) { - return { - content: [ - { - type: 'text', - text: 'Error: tag parameter is required', - }, - ], - }; - } - - const workflows = searchWorkflowsByTag(tag); - if (workflows.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No workflows found with tag: ${tag}`, - tip: 'Use hana_workflows to see available workflows', - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - tag, - workflows: workflows.map(wf => ({ - id: wf.id, - name: wf.name, - description: wf.description, - goal: wf.goal, - estimatedTime: wf.estimatedTime, - tags: wf.tags, - })), - total: workflows.length, - }, null, 2), - }, - ], - }; - } - - if (commandName === 'examples') { - const command = (args as any)?.command; - if (!command) { - return { - content: [ - { - type: 'text', - text: 'Error: command parameter is required', - }, - ], - }; - } - - const examples = getCommandExamples(command); - if (examples.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No examples available for command: ${command}`, - tip: 'Use hana_commands_with_examples to see which commands have examples', - availableCommands: getCommandsWithExamples(), - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - command, - examples: examples.map(ex => ({ - scenario: ex.scenario, - description: ex.description, - parameters: ex.parameters, - notes: ex.notes, - expectedOutput: ex.expectedOutput, - })), - total: examples.length, - usage: `To execute: Use hana_${command} with the parameters from any example`, - }, null, 2), - }, - ], - }; - } - - if (commandName === 'parameter_presets') { - const command = (args as any)?.command; - if (!command) { - return { - content: [ - { - type: 'text', - text: 'Error: command parameter is required', - }, - ], - }; - } - - const presets = getCommandPresets(command); - if (presets.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No presets available for command: ${command}`, - tip: 'Try hana_examples for usage examples instead', - commandsWithPresets: getCommandsWithPresets(), - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - command, - presets: presets.map(preset => ({ - name: preset.name, - description: preset.description, - parameters: preset.parameters, - notes: preset.notes, - whenToUse: preset.whenToUse, - })), - total: presets.length, - usage: 'Replace placeholder values (e.g., ) with your actual values', - }, null, 2), - }, - ], - }; - } - - if (commandName === 'commands_with_examples') { - const commandsWithExamples = getCommandsWithExamples(); - const commandsWithPresets = getCommandsWithPresets(); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'Commands with examples and presets available', - commandsWithExamples: commandsWithExamples.sort(), - commandsWithPresets: commandsWithPresets.sort(), - totalWithExamples: commandsWithExamples.length, - totalWithPresets: commandsWithPresets.length, - usage: { - examples: 'Use hana_examples with command name to see detailed examples', - presets: 'Use hana_parameter_presets with command name to see parameter templates', - }, - }, null, 2), - }, - ], - }; - } - - // Phase 2: Enhanced Discovery Handlers - if (commandName === 'recommend') { - const intent = (args as any)?.intent; - const limit = (args as any)?.limit || 5; - - if (!intent) { - return { - content: [ - { - type: 'text', - text: 'Error: intent parameter is required. Describe what you want to do in natural language.', - }, - ], - }; - } - - const recommendations = recommendCommands(intent, limit); - - if (recommendations.length === 0) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'No commands found matching your intent', - intent, - tip: 'Try using different words or browse by category with hana_discover_categories', - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - intent, - recommendations: recommendations.map(rec => ({ - command: `hana_${rec.command}`, - confidence: rec.confidence, - reason: rec.reason, - category: rec.category, - tags: rec.tags, - useCases: rec.useCases, - exampleParameters: rec.exampleParameters, - howToUse: rec.exampleParameters - ? `Call hana_${rec.command} with parameters: ${JSON.stringify(rec.exampleParameters)}` - : `Call hana_${rec.command}`, - getExamples: `Use hana_examples with command="${rec.command}" for detailed examples`, - })), - total: recommendations.length, - nextSteps: recommendations.length > 0 - ? `Try the highest confidence recommendation first, or use hana_examples to see usage examples` - : undefined, - }, null, 2), - }, - ], - }; - } - - if (commandName === 'quickstart') { - const guide = getQuickStartGuide(); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - title: '🚀 Quick Start Guide for SAP HANA CLI', - description: 'Follow these steps to get started with your database', - steps: guide.map(step => ({ - order: step.order, - command: `hana_${step.command}`, - description: step.description, - purpose: step.purpose, - parameters: step.parameters, - tips: step.tips, - })), - totalSteps: guide.length, - recommendation: 'Execute these commands in order. Each step builds on the previous one.', - }, null, 2), - }, - ], - }; - } - - if (commandName === 'troubleshoot') { - const command = (args as any)?.command; - - if (!command) { - return { - content: [ - { - type: 'text', - text: 'Error: command parameter is required', - }, - ], - }; - } - - const guide = getTroubleshootingGuide(command); - - if (!guide) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `No troubleshooting guide available for command: ${command}`, - tip: 'Try hana_examples for usage examples, or check command documentation', - availableGuides: ['import', 'export', 'dataProfile', 'tables', 'status', 'healthCheck'], - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - command: guide.command, - prerequisites: guide.prerequisites, - commonIssues: guide.commonIssues.map(issue => ({ - issue: issue.issue, - solution: issue.solution, - suggestedCommand: issue.command ? `hana_${issue.command}` : undefined, - parameters: issue.parameters, - })), - tips: guide.tips, - additionalHelp: { - examples: `Use hana_examples with command="${command}" for usage examples`, - presets: `Use hana_parameter_presets with command="${command}" for parameter templates`, - }, - }, null, 2), - }, - ], - }; - } - - // Phase 3: Advanced Features Handlers - if (commandName === 'execute_workflow') { - const workflowId = (args as any)?.workflowId; - const parameters = (args as any)?.parameters || {}; - const stopOnError = (args as any)?.stopOnError !== false; - - if (!workflowId) { - return { - content: [ - { - type: 'text', - text: 'Error: workflowId parameter is required', - }, - ], - }; - } - - const result = await executeWorkflow(workflowId, parameters, stopOnError); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...result, - note: result.success - ? 'All workflow steps completed successfully' - : 'Workflow failed - see results for details', - }, null, 2), - }, - ], - }; - } - - if (commandName === 'preview_workflow') { - const workflowId = (args as any)?.workflowId; - const parameters = (args as any)?.parameters || {}; - - if (!workflowId) { - return { - content: [ - { - type: 'text', - text: 'Error: workflowId parameter is required', - }, - ], - }; - } - - const preview = previewWorkflow(workflowId, parameters); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...preview, - note: preview.validation?.valid - ? 'Workflow ready to execute - use hana_execute_workflow with these parameters' - : 'Missing required parameters - see validation.missingParameters', - }, null, 2), - }, - ], - }; - } - - if (commandName === 'interpret_result') { - const command = (args as any)?.command; - const result = (args as any)?.result; - - if (!command || !result) { - return { - content: [ - { - type: 'text', - text: 'Error: both command and result parameters are required', - }, - ], - }; - } - - const interpretation = interpretResult(command, result); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...interpretation, - usage: interpretation.recommendations.length > 0 - ? 'Follow recommendations in priority order for best results' - : undefined, - }, null, 2), - }, - ], - }; - } - - if (commandName === 'smart_search') { - const query = (args as any)?.query; - const scope = (args as any)?.scope || 'all'; - const limit = (args as any)?.limit || 20; - - if (!query) { - return { - content: [ - { - type: 'text', - text: 'Error: query parameter is required', - }, - ], - }; - } - - const searchResults = smartSearch(query, scope, limit); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...searchResults, - note: searchResults.totalResults > 0 - ? `Found ${searchResults.totalResults} matches. Results sorted by relevance.` - : 'No matches found. Try different keywords or browse by category.', - }, null, 2), - }, - ], - }; - } - - // Documentation Search Tool Handlers - if (commandName === 'search_docs') { - const query = (args as any)?.query; - const category = (args as any)?.category; - const docType = (args as any)?.docType; - const limit = (args as any)?.limit || 10; - - if (!query) { - return { - content: [ - { - type: 'text', - text: 'Error: query parameter is required', - }, - ], - }; - } - - if (!docsSearch.isAvailable()) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: 'Documentation index not available', - tip: 'Run "npm run build:docs-index" in the project root to generate the documentation index', - }, null, 2), - }, - ], - }; - } - - const results = docsSearch.search(query, { category, docType, limit }); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - query, - totalResults: results.length, - results: results.map(r => ({ - title: r.document.title, - path: r.document.path, - category: r.document.category, - docType: r.document.docType, - relevance: r.relevance, - excerpt: r.snippet || r.document.excerpt, - matchedKeywords: r.matchedKeywords, - url: `https://sap-samples.github.io/hana-developer-cli-tool-example/${r.document.path.replace('.md', '.html')}`, - })), - tip: results.length > 0 - ? 'Use hana_get_doc with the path to read the full document content' - : 'No matches found. Try different keywords or use hana_list_doc_categories to browse available documentation', - }, null, 2), - }, - ], - }; - } - - if (commandName === 'get_doc') { - const path = (args as any)?.path; - - if (!path) { - return { - content: [ - { - type: 'text', - text: 'Error: path parameter is required', - }, - ], - }; - } - - if (!docsSearch.isAvailable()) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: 'Documentation index not available', - tip: 'Run "npm run build:docs-index" in the project root to generate the documentation index', - }, null, 2), - }, - ], - }; - } - - const document = docsSearch.getDocument(path); - const content = docsSearch.getDocumentContent(path); - - if (!document || !content) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `Document not found: ${path}`, - tip: 'Use hana_search_docs to find valid document paths', - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - title: document.title, - path: document.path, - category: document.category, - docType: document.docType, - url: `https://sap-samples.github.io/hana-developer-cli-tool-example/${path.replace('.md', '.html')}`, - headings: document.headings, - content: content, - relatedLinks: document.links, - lastModified: document.lastModified, - }, null, 2), - }, - ], - }; - } - - if (commandName === 'docs_stats') { - if (!docsSearch.isAvailable()) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: 'Documentation index not available', - tip: 'Run "npm run build:docs-index" in the project root to generate the documentation index', - }, null, 2), - }, - ], - }; - } - - const stats = docsSearch.getStats(); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...stats, - websiteUrl: 'https://sap-samples.github.io/hana-developer-cli-tool-example/', - usage: 'Use hana_search_docs to search, hana_list_doc_categories to browse', - }, null, 2), - }, - ], - }; - } - - if (commandName === 'list_doc_categories') { - if (!docsSearch.isAvailable()) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: 'Documentation index not available', - tip: 'Run "npm run build:docs-index" in the project root to generate the documentation index', - }, null, 2), - }, - ], - }; - } - - const categories = docsSearch.getCategories(); - const docTypes = docsSearch.getDocTypes(); - - const categorySummary: Record = {}; - categories.forEach(cat => { - const docs = docsSearch.listByCategory(cat); - categorySummary[cat] = { - documentCount: docs.length, - sampleDocuments: docs.slice(0, 3).map(d => ({ - title: d.title, - path: d.path, - })), - }; - }); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - categories: categorySummary, - documentTypes: docTypes, - totalCategories: categories.length, - usage: 'Use hana_search_docs with category parameter to limit search scope', - }, null, 2), - }, - ], - }; - } - - if (commandName === 'conversation_templates') { - const templates = listConversationTemplates(); - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - message: 'Available conversation templates', - templates: templates.map(t => ({ - scenario: t.scenario, - description: t.description, - goal: t.goal, - usage: `Use hana_get_template with scenario="${t.scenario}" to see full details`, - })), - total: templates.length, - }, null, 2), - }, - ], - }; - } - - if (commandName === 'get_template') { - const scenario = (args as any)?.scenario; - - if (!scenario) { - return { - content: [ - { - type: 'text', - text: 'Error: scenario parameter is required', - }, - ], - }; - } - - const template = getConversationTemplate(scenario); - - if (!template) { - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - error: `Template not found: ${scenario}`, - availableTemplates: listConversationTemplates().map(t => t.scenario), - }, null, 2), - }, - ], - }; - } - - return { - content: [ - { - type: 'text', - text: JSON.stringify({ - ...template, - usage: 'Follow steps in order. Each step builds on previous results.', - }, null, 2), - }, - ], - }; - } - - // Knowledge Base Tool Handlers - if (commandName === 'connection_guide') { - return { - content: [ - { - type: 'text', - text: ReadmeKnowledgeBase.getConnectionGuide(), - }, - ], - }; - } - - if (commandName === 'standard_parameters') { - const category = (args as any)?.category; - - if (!category) { - return { - content: [ - { - type: 'text', - text: 'Error: category parameter is required. Available categories: data-manipulation, batch-operations, list-inspect', - }, - ], - }; - } - - const guide = ReadmeKnowledgeBase.getParameterGuide(category); - - return { - content: [ - { - type: 'text', - text: guide, - }, - ], - }; - } - - if (commandName === 'security_guide') { - return { - content: [ - { - type: 'text', - text: ReadmeKnowledgeBase.getSecurityGuidelines(), - }, - ], - }; - } - - if (commandName === 'best_practices') { - return { - content: [ - { - type: 'text', - text: ReadmeKnowledgeBase.getBestPractices(), - }, - ], - }; - } - - if (commandName === 'project_structure') { - return { - content: [ - { - type: 'text', - text: ReadmeKnowledgeBase.getProjectStructure(), - }, - ], - }; - } - - if (commandName === 'docs_search') { - const query = (args as any)?.query; - - if (!query) { - return { - content: [ - { - type: 'text', - text: 'Error: query parameter is required', - }, - ], - }; - } - - const results = ReadmeKnowledgeBase.searchDocumentation(query); - - return { - content: [ - { - type: 'text', - text: results, - }, - ], - }; - } - - // Check if command exists (either as main name or alias) - let actualCommandName = commandName; - if (!this.commands.has(commandName)) { - // Check if it's an alias (compare sanitized versions) - for (const [cmdName, cmdModule] of this.commands) { - if (cmdModule.aliases) { - for (const alias of cmdModule.aliases) { - if (sanitizeToolName(alias) === commandName) { - actualCommandName = cmdName; - break; - } - } - if (actualCommandName !== commandName) break; - } - } - } - - if (!this.commands.has(actualCommandName)) { - return { - content: [ - { - type: 'text', - text: `Unknown command: ${commandName}`, - }, - ], - }; - } - - // Validate environment if needed - const envCheck = validateEnvironment(); - if (!envCheck.valid) { - return { - content: [ - { - type: 'text', - text: `Environment validation failed: ${envCheck.message}`, - }, - ], - }; - } - - // Execute the command - try { - // Extract connection context if provided by agent - const context = (args as any)?.__projectContext as ConnectionContext | undefined; - - // Remove context from args before passing to CLI (it's not a CLI parameter) - const cleanArgs = { ...args }; - delete cleanArgs.__projectContext; - - const result = await executeCommand(actualCommandName, cleanArgs, context); - const formattedOutput = formatResult(result); - - return { - content: [ - { - type: 'text', - text: formattedOutput, - }, - ], - }; - } catch (error) { - return { - content: [ - { - type: 'text', - text: `Error executing command: ${error instanceof Error ? error.message : String(error)}`, - }, - ], - }; - } + return errorResponse(`Unknown tool: ${name}`); }); } - /** - * Setup MCP Resource handlers for documentation access - */ private setupResourceHandlers(): void { - // List available resources this.server.setRequestHandler(ListResourcesRequestSchema, async () => { try { - const resources = listResources(); - return { resources }; + return { resources: listResources() }; } catch (error) { console.error('[MCP] Error listing resources:', error); return { resources: [] }; } }); - // Read a specific resource this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => { try { - const { uri } = request.params; - const content = await readResource(uri); - return { - contents: [content], - }; + const content = await readResource(request.params.uri); + return { contents: [content] }; } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); console.error(`[MCP] Error reading resource ${request.params.uri}:`, errorMsg); @@ -1726,27 +133,20 @@ class HanaCliMcpServer { }); } - /** - * Setup MCP Prompt handlers for guided workflows - */ private setupPromptHandlers(): void { - // List available prompts this.server.setRequestHandler(ListPromptsRequestSchema, async () => { try { - const prompts = listPrompts(); - return { prompts }; + return { prompts: listPrompts() }; } catch (error) { console.error('[MCP] Error listing prompts:', error); return { prompts: [] }; } }); - // Get a specific prompt this.server.setRequestHandler(GetPromptRequestSchema, async (request) => { try { const { name, arguments: args } = request.params; - const result = getPrompt(name, args as Record | undefined); - return result; + return getPrompt(name, args as Record | undefined); } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); console.error(`[MCP] Error getting prompt ${request.params.name}:`, errorMsg); @@ -1755,15 +155,9 @@ class HanaCliMcpServer { }); } - /** - * Load all commands from the parent hana-cli project - */ async loadCommands(): Promise { try { - // Import the index.js from parent project that exports init() - // __dirname is mcp-server/build, so go up 2 levels to project root const indexPath = join(__dirname, '..', '..', 'bin', 'index.js'); - // Convert to file:// URL for ES module import (required on Windows) const indexUrl = pathToFileURL(indexPath).href; const indexModule = await import(indexUrl); @@ -1771,7 +165,6 @@ class HanaCliMcpServer { throw new Error('index.js does not export an init() function'); } - // Call init() to get all command modules const commands = await indexModule.init(); if (!Array.isArray(commands)) { @@ -1780,21 +173,20 @@ class HanaCliMcpServer { console.error(`[MCP] Loaded ${commands.length} command modules from hana-cli`); - // Store commands in map - let successCount = 0; for (const cmd of commands) { if (cmd && typeof cmd.command === 'string') { const commandName = cmd.command.split(' ')[0]; this.commands.set(commandName, cmd); - successCount++; } } - console.error(`[MCP] Registered ${this.commands.size} unique commands with ${successCount} processed modules`); - + console.error(`[MCP] Registered ${this.commands.size} unique commands`); + if (this.commands.size === 0) { throw new Error('No valid commands were registered'); } + + initCliTools(this.commands); } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); console.error(`[MCP] Failed to load commands: ${errorMsg}`); @@ -1803,19 +195,15 @@ class HanaCliMcpServer { } async run(): Promise { - // Load commands before starting server await this.loadCommands(); - const transport = new StdioServerTransport(); await this.server.connect(transport); - console.error('[MCP] SAP HANA CLI MCP Server running on stdio'); } } -// Start the server const server = new HanaCliMcpServer(); server.run().catch((error) => { console.error('[MCP] Fatal error:', error); process.exit(1); -}); \ No newline at end of file +}); diff --git a/mcp-server/src/output-formatter.ts b/mcp-server/src/output-formatter.ts index 85497f00..38c9e924 100644 --- a/mcp-server/src/output-formatter.ts +++ b/mcp-server/src/output-formatter.ts @@ -277,30 +277,28 @@ function formatContainersOutput(output: string): string { return result; } +const COMMAND_FORMATTERS: Record string> = { + tables: formatTablesOutput, + schemas: formatSchemasOutput, + views: formatViewsOutput, + procedures: formatProceduresOutput, + functions: formatFunctionsOutput, + systemInfo: formatSystemInfoOutput, + sysInfo: formatSystemInfoOutput, + containers: formatContainersOutput, +}; + /** * Main formatter function */ export function formatOutput(command: string, output: string): string { - // Remove the connection config message for cleaner output const cleanOutput = output.replace(/Using Connection Configuration.*\n\n?/, ''); - - // Detect command type and apply appropriate formatting - if (command.includes('tables') || command.includes(' t ')) { - return formatTablesOutput(cleanOutput); - } else if (command.includes('schemas') || command.includes(' sch ')) { - return formatSchemasOutput(cleanOutput); - } else if (command.includes('views') || command.includes(' v ')) { - return formatViewsOutput(cleanOutput); - } else if (command.includes('procedures') || command.includes(' p ')) { - return formatProceduresOutput(cleanOutput); - } else if (command.includes('functions') || command.includes(' f ')) { - return formatFunctionsOutput(cleanOutput); - } else if (command.includes('systemInfo') || command.includes('sysInfo')) { - return formatSystemInfoOutput(cleanOutput); - } else if (command.includes('containers') || command.includes('cont')) { - return formatContainersOutput(cleanOutput); + + const formatter = COMMAND_FORMATTERS[command]; + if (formatter) { + return formatter(cleanOutput); } - + // For other commands, try generic table formatting const table = parseAsciiTable(cleanOutput); if (table && table.rows.length > 0) { @@ -309,7 +307,7 @@ export function formatOutput(command: string, output: string): string { result += formatAsMarkdown(table); return result; } - + // Return original output if no formatting applied return output; } \ No newline at end of file diff --git a/mcp-server/src/resources.ts b/mcp-server/src/resources.ts index 0b4c60d0..c0c921a9 100644 --- a/mcp-server/src/resources.ts +++ b/mcp-server/src/resources.ts @@ -10,6 +10,7 @@ import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; import { docsSearch } from './docs-search.js'; import { getCommandExamples, getCommandPresets } from './examples-presets.js'; +import ReadmeKnowledgeBase from './readme-knowledge-base.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -147,6 +148,64 @@ export function listResources(): Resource[] { description: 'List of guided workflows and templates for common tasks', mimeType: 'text/plain', }, + + // Knowledge Base (migrated from tools for reduced context usage) + { + uri: 'hana://knowledge/connection-guide', + name: 'Connection Resolution Guide (Knowledge Base)', + description: 'Detailed 7-step connection resolution order and best practices', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/security-guide', + name: 'Security Guidelines (Knowledge Base)', + description: 'Connection security, SQL injection protection, parameter security, environment security', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/best-practices', + name: 'Best Practices (Knowledge Base)', + description: 'Naming conventions, alias patterns, safe operation patterns', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/project-structure', + name: 'Project Structure (Knowledge Base)', + description: 'Overview of hana-cli project folders and documentation resources', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/parameters/data-manipulation', + name: 'Data Manipulation Parameters', + description: 'Standard parameters for data manipulation commands (schema, table, output, format, etc.)', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/parameters/batch-operations', + name: 'Batch Operation Parameters', + description: 'Standard parameters for batch/mass operation commands', + mimeType: 'text/markdown', + }, + { + uri: 'hana://knowledge/parameters/list-inspect', + name: 'List & Inspect Parameters', + description: 'Standard parameters for listing and inspection commands', + mimeType: 'text/markdown', + }, + + // Documentation Index Metadata + { + uri: 'hana://docs/statistics', + name: 'Documentation Statistics', + description: 'Total documents, categories, and document types available in the documentation index', + mimeType: 'application/json', + }, + { + uri: 'hana://docs/categories', + name: 'Documentation Categories', + description: 'All available documentation categories and document types with sample documents', + mimeType: 'application/json', + }, ]; } @@ -429,5 +488,47 @@ Example: To explore a database, invoke the "explore-database" prompt. }; } + // Knowledge Base resources + if (uri === 'hana://knowledge/connection-guide') { + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getConnectionGuide() }; + } + if (uri === 'hana://knowledge/security-guide') { + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getSecurityGuidelines() }; + } + if (uri === 'hana://knowledge/best-practices') { + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getBestPractices() }; + } + if (uri === 'hana://knowledge/project-structure') { + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getProjectStructure() }; + } + if (uri.startsWith('hana://knowledge/parameters/')) { + const category = uri.replace('hana://knowledge/parameters/', ''); + return { uri, mimeType: 'text/markdown', text: ReadmeKnowledgeBase.getParameterGuide(category) }; + } + + // Documentation index metadata resources + if (uri === 'hana://docs/statistics') { + if (!docsSearch.isAvailable()) { + return { uri, mimeType: 'application/json', text: JSON.stringify({ error: 'Documentation index not available' }) }; + } + return { uri, mimeType: 'application/json', text: JSON.stringify(docsSearch.getStats(), null, 2) }; + } + if (uri === 'hana://docs/categories') { + if (!docsSearch.isAvailable()) { + return { uri, mimeType: 'application/json', text: JSON.stringify({ error: 'Documentation index not available' }) }; + } + const categories = docsSearch.getCategories(); + const docTypes = docsSearch.getDocTypes(); + const categorySummary: Record = {}; + categories.forEach(cat => { + const docs = docsSearch.listByCategory(cat); + categorySummary[cat] = { + documentCount: docs.length, + sampleDocuments: docs.slice(0, 3).map(d => ({ title: d.title, path: d.path })), + }; + }); + return { uri, mimeType: 'application/json', text: JSON.stringify({ categories: categorySummary, documentTypes: docTypes }, null, 2) }; + } + throw new Error(`Unknown resource: ${uri}`); } diff --git a/mcp-server/src/tools/cli-tools.ts b/mcp-server/src/tools/cli-tools.ts new file mode 100644 index 00000000..d96487ab --- /dev/null +++ b/mcp-server/src/tools/cli-tools.ts @@ -0,0 +1,103 @@ +import { ToolDefinition, ToolResponse, textResponse, errorResponse } from './types.js'; +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'; + +function sanitizeToolName(name: string): string { + return name.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: { + projectPath: { type: 'string', description: 'Absolute path to the project directory.' }, + connectionFile: { type: 'string', description: 'Connection file name relative to projectPath (e.g., ".env", "default-env.json").' }, + host: { type: 'string', description: 'Database host (for direct connection).' }, + port: { type: 'number', description: 'Database port (default 30013).' }, + user: { type: 'string', description: 'Database user.' }, + password: { type: 'string', description: 'Database password. SECURITY WARNING: Prefer connection files instead.' }, + database: { type: 'string', description: 'Database name (default "SYSTEMDB").' }, + }, +}; + +let commandsMap: Map = new Map(); + +export function initCliTools(commands: Map): void { + commandsMap = commands; +} + +export function getCliToolDefinitions(): ToolDefinition[] { + const tools: ToolDefinition[] = []; + + 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 (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; +} + +export async function handleCliTool(toolName: string, args: Record): Promise { + const commandName = toolName.startsWith('hana_') ? toolName.slice(5) : toolName; + + let actualCommandName = commandName; + if (!commandsMap.has(commandName)) { + for (const [cmdName, cmdModule] of commandsMap) { + if (cmdModule.aliases) { + for (const alias of cmdModule.aliases) { + if (sanitizeToolName(alias) === commandName) { + actualCommandName = cmdName; + break; + } + } + if (actualCommandName !== commandName) break; + } + } + } + + if (!commandsMap.has(actualCommandName)) { + return null; + } + + try { + const context = args?.__projectContext as ConnectionContext | undefined; + const cleanArgs = { ...args }; + delete cleanArgs.__projectContext; + + const result = await executeCommand(actualCommandName, cleanArgs, context); + const formattedOutput = formatResult(result); + return textResponse(formattedOutput); + } catch (error) { + return errorResponse(`Error executing command: ${error instanceof Error ? error.message : String(error)}`); + } +} diff --git a/mcp-server/src/tools/content-tools.ts b/mcp-server/src/tools/content-tools.ts new file mode 100644 index 00000000..96dc7bdc --- /dev/null +++ b/mcp-server/src/tools/content-tools.ts @@ -0,0 +1,234 @@ +import { ToolDefinition, ToolResponse, jsonResponse, errorResponse } from './types.js'; +import { + getCommandExamples, getCommandPresets, + hasExamples, hasPresets, + getCommandsWithExamples, getCommandsWithPresets, +} from '../examples-presets.js'; +import { recommendCommands, getQuickStartGuide } from '../recommendation.js'; +import { getTroubleshootingGuide } from '../next-steps.js'; +import { interpretResult } from '../result-interpretation.js'; +import { getConversationTemplate, listConversationTemplates } from '../conversation-templates.js'; + +export function getContentToolDefinitions(): ToolDefinition[] { + return [ + { + name: 'hana_examples', + description: 'Get real-world usage examples for a specific command with parameter combinations, scenarios, and expected outputs. Essential for understanding how to use commands correctly.', + inputSchema: { + type: 'object', + properties: { + command: { type: 'string', description: 'Command name (without hana_ prefix, e.g., "import", "export", "dataProfile")' }, + }, + required: ['command'], + }, + }, + { + name: 'hana_parameter_presets', + description: 'Get parameter presets/templates for common use cases of a command. Shows pre-configured parameter combinations for scenarios like "quick-import", "safe-import", "large-file" etc.', + inputSchema: { + type: 'object', + properties: { + command: { type: 'string', description: 'Command name (without hana_ prefix)' }, + }, + required: ['command'], + }, + }, + { + name: 'hana_recommend', + description: 'Get command recommendations based on natural language intent. Tell me what you want to do, and I\'ll suggest the best commands. Example: "find duplicate rows", "check database version", "export table to CSV".', + inputSchema: { + type: 'object', + properties: { + intent: { type: 'string', description: 'What you want to accomplish in natural language (e.g., "import CSV file", "find slow queries", "check user permissions")' }, + limit: { type: 'number', description: 'Maximum number of recommendations to return (default: 5)', default: 5 }, + }, + required: ['intent'], + }, + }, + { + name: 'hana_quickstart', + description: 'Get a beginner-friendly quick start guide with the recommended first 6 commands to run when starting with the database. Perfect for new users or initial database exploration.', + inputSchema: { type: 'object', properties: {}, required: [] }, + }, + { + name: 'hana_troubleshoot', + description: 'Get troubleshooting guide for a specific command including common issues, solutions, prerequisites, and tips. Essential when a command isn\'t working as expected.', + inputSchema: { + type: 'object', + properties: { + command: { type: 'string', description: 'Command name (without hana_ prefix) to get troubleshooting help for' }, + }, + required: ['command'], + }, + }, + { + name: 'hana_interpret_result', + description: 'Get AI-friendly interpretation of command results with insights, recommendations, and analysis. Provides summary, key metrics, concerns detected, and actionable recommendations.', + inputSchema: { + type: 'object', + properties: { + command: { type: 'string', description: 'The command that was executed' }, + result: { type: 'string', description: 'The command output to interpret' }, + }, + required: ['command', 'result'], + }, + }, + { + name: 'hana_conversation_templates', + description: 'List available conversation templates for common scenarios. Templates provide step-by-step guided workflows for tasks like data-exploration, troubleshooting, data-migration, performance-tuning, and security-audit.', + inputSchema: { type: 'object', properties: {}, required: [] }, + }, + { + name: 'hana_get_template', + description: 'Get a detailed conversation template for a specific scenario. Includes all steps, commands, expected outcomes, tips, and common questions with answers.', + inputSchema: { + type: 'object', + properties: { + scenario: { type: 'string', description: 'Scenario name (e.g., "data-exploration", "troubleshooting", "data-migration", "performance-tuning", "security-audit")' }, + }, + required: ['scenario'], + }, + }, + ]; +} + +export function handleContentTool(commandName: string, args: Record): ToolResponse | null { + if (commandName === 'examples') { + const command = args?.command; + if (!command) return errorResponse('Error: command parameter is required'); + + const examples = getCommandExamples(command); + if (examples.length === 0) { + return jsonResponse({ + error: `No examples available for command: ${command}`, + availableCommands: getCommandsWithExamples(), + }); + } + return jsonResponse({ + command, examples, total: examples.length, + usage: `To execute: Use hana_${command} with the parameters from any example`, + }); + } + + if (commandName === 'parameter_presets') { + const command = args?.command; + if (!command) return errorResponse('Error: command parameter is required'); + + const presets = getCommandPresets(command); + if (presets.length === 0) { + return jsonResponse({ + error: `No presets available for command: ${command}`, + tip: 'Try hana_examples for usage examples instead', + commandsWithPresets: getCommandsWithPresets(), + }); + } + return jsonResponse({ + command, presets, total: presets.length, + usage: 'Replace placeholder values (e.g., ) with your actual values', + }); + } + + if (commandName === 'recommend') { + const intent = args?.intent; + const limit = args?.limit || 5; + if (!intent) return errorResponse('Error: intent parameter is required. Describe what you want to do in natural language.'); + + const recommendations = recommendCommands(intent, limit); + if (recommendations.length === 0) { + return jsonResponse({ + message: 'No commands found matching your intent', intent, + tip: 'Try using different words or browse by category with hana_discover_categories', + }); + } + return jsonResponse({ + intent, + recommendations: recommendations.map(rec => ({ + command: `hana_${rec.command}`, confidence: rec.confidence, reason: rec.reason, + category: rec.category, tags: rec.tags, useCases: rec.useCases, + exampleParameters: rec.exampleParameters, + howToUse: rec.exampleParameters + ? `Call hana_${rec.command} with parameters: ${JSON.stringify(rec.exampleParameters)}` + : `Call hana_${rec.command}`, + })), + total: recommendations.length, + }); + } + + if (commandName === 'quickstart') { + const guide = getQuickStartGuide(); + return jsonResponse({ + title: 'Quick Start Guide for SAP HANA CLI', + description: 'Follow these steps to get started with your database', + steps: guide.map(step => ({ + order: step.order, command: `hana_${step.command}`, + description: step.description, purpose: step.purpose, + parameters: step.parameters, tips: step.tips, + })), + totalSteps: guide.length, + recommendation: 'Execute these commands in order. Each step builds on the previous one.', + }); + } + + if (commandName === 'troubleshoot') { + const command = args?.command; + if (!command) return errorResponse('Error: command parameter is required'); + + const guide = getTroubleshootingGuide(command); + if (!guide) { + return jsonResponse({ + error: `No troubleshooting guide available for command: ${command}`, + availableGuides: ['import', 'export', 'dataProfile', 'tables', 'status', 'healthCheck'], + }); + } + return jsonResponse({ + command: guide.command, prerequisites: guide.prerequisites, + commonIssues: guide.commonIssues.map((issue: any) => ({ + issue: issue.issue, solution: issue.solution, + suggestedCommand: issue.command ? `hana_${issue.command}` : undefined, + parameters: issue.parameters, + })), + tips: guide.tips, + }); + } + + if (commandName === 'interpret_result') { + const command = args?.command; + const result = args?.result; + if (!command || !result) return errorResponse('Error: both command and result parameters are required'); + + const interpretation = interpretResult(command, result); + return jsonResponse({ + ...interpretation, + usage: interpretation.recommendations.length > 0 + ? 'Follow recommendations in priority order for best results' : undefined, + }); + } + + if (commandName === 'conversation_templates') { + const templates = listConversationTemplates(); + return jsonResponse({ + message: 'Available conversation templates', + templates: templates.map(t => ({ + scenario: t.scenario, description: t.description, goal: t.goal, + usage: `Use hana_get_template with scenario="${t.scenario}" to see full details`, + })), + total: templates.length, + }); + } + + if (commandName === 'get_template') { + const scenario = args?.scenario; + if (!scenario) return errorResponse('Error: scenario parameter is required'); + + const template = getConversationTemplate(scenario); + if (!template) { + return jsonResponse({ + error: `Template not found: ${scenario}`, + availableTemplates: listConversationTemplates().map(t => t.scenario), + }); + } + return jsonResponse({ ...template, usage: 'Follow steps in order. Each step builds on previous results.' }); + } + + return null; +} diff --git a/mcp-server/src/tools/discovery-tools.ts b/mcp-server/src/tools/discovery-tools.ts new file mode 100644 index 00000000..9b050565 --- /dev/null +++ b/mcp-server/src/tools/discovery-tools.ts @@ -0,0 +1,189 @@ +import { ToolDefinition, ToolResponse, jsonResponse, errorResponse } from './types.js'; +import { + CATEGORIES, + getCommandsInCategory, + searchCommandsByTag, + getAllWorkflows, + searchWorkflowsByTag, + getWorkflowById, +} from '../command-metadata.js'; + +export function getDiscoveryToolDefinitions(): ToolDefinition[] { + return [ + { + name: 'hana_discover_categories', + description: 'Discover available command categories and get an overview of what each category does. Use this to find commands for a specific task.', + inputSchema: { type: 'object', properties: {}, required: [] }, + }, + { + name: 'hana_discover_by_category', + description: 'Get all commands in a specific category. Useful for finding commands when you know the general area (e.g., "data-tools", "performance-monitoring").', + inputSchema: { + type: 'object', + properties: { + category: { + type: 'string', + description: 'The category to query (e.g., "data-tools", "schema-tools", "object-inspection", "analysis-tools", "performance-monitoring", "backup-recovery", "system-admin", "system-tools", "security", "mass-operations", "connection-auth", "btp-integration", "hana-cloud", "hdi-management", "developer-tools")', + }, + }, + required: ['category'], + }, + }, + { + name: 'hana_discover_by_tag', + description: 'Search commands by tag. Tags help identify commands for specific purposes (e.g., "import", "export", "validation", "performance", "user", "privilege").', + inputSchema: { + type: 'object', + properties: { + tag: { + type: 'string', + description: 'The tag to search for (e.g., "import", "export", "validation", "performance", "user", "security")', + }, + }, + required: ['tag'], + }, + }, + { + name: 'hana_workflows', + description: 'List available workflows - multi-step task sequences for common scenarios like data validation, performance analysis, security audits, and backup procedures.', + inputSchema: { type: 'object', properties: {}, required: [] }, + }, + { + name: 'hana_workflow_by_id', + description: 'Get detailed steps for a specific workflow. Provides complete instructions including commands, parameters, and expected outputs.', + inputSchema: { + type: 'object', + properties: { + id: { + type: 'string', + description: 'Workflow ID (e.g., "validate-and-profile", "export-and-import", "performance-analysis", "security-audit", "backup-and-verify")', + }, + }, + required: ['id'], + }, + }, + { + name: 'hana_search_workflows', + description: 'Search for workflows by tag or purpose. Find workflows for specific scenarios.', + inputSchema: { + type: 'object', + properties: { + tag: { + type: 'string', + description: 'Search tag (e.g., "data-quality", "performance", "security", "backup", "migration")', + }, + }, + required: ['tag'], + }, + }, + ]; +} + +export function handleDiscoveryTool(commandName: string, args: Record): ToolResponse | null { + if (commandName === 'discover_categories') { + const categoryList = Object.entries(CATEGORIES).map(([key, value]) => ({ + id: key, + name: value.name, + description: value.description, + total: getCommandsInCategory(key).length, + })); + return jsonResponse({ + message: 'Available command categories', + categories: categoryList, + usage: 'Use hana_discover_by_category to get commands in a specific category', + }); + } + + if (commandName === 'discover_by_category') { + const category = args?.category; + if (!category) return errorResponse('Error: category parameter is required'); + + const commands = getCommandsInCategory(category); + if (commands.length === 0) { + return jsonResponse({ + error: `No commands found in category: ${category}`, + tip: 'Use hana_discover_categories to see available categories', + }); + } + return jsonResponse({ + category, + categoryInfo: CATEGORIES[category as keyof typeof CATEGORIES], + commands: commands.map(cmd => ({ + command: cmd.command, category: cmd.category, + tags: cmd.tags, useCases: cmd.useCases, relatedCommands: cmd.relatedCommands, + })), + total: commands.length, + }); + } + + if (commandName === 'discover_by_tag') { + const tag = args?.tag; + if (!tag) return errorResponse('Error: tag parameter is required'); + + const commands = searchCommandsByTag(tag); + if (commands.length === 0) { + return jsonResponse({ + error: `No commands found with tag: ${tag}`, + tip: 'Try different tags or use hana_discover_by_category to browse', + }); + } + return jsonResponse({ + tag, + commands: commands.map(cmd => ({ + command: cmd.command, category: cmd.category, + tags: cmd.tags, useCases: cmd.useCases, relatedCommands: cmd.relatedCommands, + })), + total: commands.length, + }); + } + + if (commandName === 'workflows') { + const workflows = getAllWorkflows(); + return jsonResponse({ + message: 'Available workflows for common multi-step tasks', + workflows: workflows.map(wf => ({ + id: wf.id, name: wf.name, description: wf.description, + goal: wf.goal, estimatedTime: wf.estimatedTime, tags: wf.tags, steps: wf.steps.length, + })), + total: workflows.length, + usage: 'Use hana_workflow_by_id to see detailed steps for a workflow', + }); + } + + if (commandName === 'workflow_by_id') { + const id = args?.id; + if (!id) return errorResponse('Error: id parameter is required'); + + const workflow = getWorkflowById(id); + if (!workflow) { + return jsonResponse({ + error: `Workflow not found: ${id}`, + tip: 'Use hana_workflows to see available workflow IDs', + }); + } + return jsonResponse(workflow); + } + + if (commandName === 'search_workflows') { + const tag = args?.tag; + if (!tag) return errorResponse('Error: tag parameter is required'); + + const workflows = searchWorkflowsByTag(tag); + if (workflows.length === 0) { + return jsonResponse({ + error: `No workflows found with tag: ${tag}`, + tip: 'Use hana_workflows to see available workflows', + }); + } + return jsonResponse({ + tag, + workflows: workflows.map(wf => ({ + id: wf.id, name: wf.name, description: wf.description, + goal: wf.goal, estimatedTime: wf.estimatedTime, tags: wf.tags, + })), + total: workflows.length, + }); + } + + return null; +} diff --git a/mcp-server/src/tools/search-tools.ts b/mcp-server/src/tools/search-tools.ts new file mode 100644 index 00000000..a3fa6e71 --- /dev/null +++ b/mcp-server/src/tools/search-tools.ts @@ -0,0 +1,125 @@ +import { ToolDefinition, ToolResponse, jsonResponse, errorResponse } from './types.js'; +import { docsSearch } from '../docs-search.js'; +import { smartSearch } from '../smart-search.js'; + +export function getSearchToolDefinitions(): ToolDefinition[] { + return [ + { + name: 'hana_search', + description: 'Search across all hana-cli resources: documentation, commands, workflows, examples, and presets. Use scope to narrow results. Default searches everything with relevance scoring.', + inputSchema: { + type: 'object', + properties: { + query: { type: 'string', description: 'Search query (keywords or phrases)' }, + scope: { + type: 'string', + enum: ['all', 'docs', 'commands', 'workflows', 'examples', 'presets'], + description: 'What to search. "all" (default) searches everything, "docs" searches documentation website only, others search command metadata.', + }, + category: { type: 'string', description: 'Optional: limit doc search to specific category (getting-started, commands, features, api-reference, development)' }, + docType: { + type: 'string', + enum: ['tutorial', 'command', 'api', 'feature', 'troubleshooting', 'development', 'general'], + description: 'Optional: filter docs by document type', + }, + limit: { type: 'number', default: 10, description: 'Maximum number of results to return (default: 10)' }, + }, + required: ['query'], + }, + }, + { + name: 'hana_get_doc', + description: 'Retrieve the full content of a specific documentation page. Use after hana_search to get complete details from a relevant document.', + inputSchema: { + type: 'object', + properties: { + path: { type: 'string', description: 'Document path from search results (e.g., "01-getting-started/installation.md", "02-commands/data-tools/import.md")' }, + }, + required: ['path'], + }, + }, + ]; +} + +export function handleSearchTool(commandName: string, args: Record): ToolResponse | null { + if (commandName === 'search') { + const query = args?.query; + if (!query) return errorResponse('Error: query parameter is required'); + + const scope = args?.scope || 'all'; + const limit = args?.limit || 10; + const category = args?.category; + const docType = args?.docType; + + const results: any[] = []; + + if (scope === 'all' || scope === 'docs') { + if (docsSearch.isAvailable()) { + const docResults = docsSearch.search(query, { category, docType, limit }); + results.push(...docResults.map(r => ({ + type: 'documentation', + title: r.document.title, + path: r.document.path, + category: r.document.category, + relevance: r.relevance, + excerpt: r.snippet || r.document.excerpt, + url: `https://sap-samples.github.io/hana-developer-cli-tool-example/${r.document.path.replace('.md', '.html')}`, + }))); + } + } + + if (scope === 'all' || scope !== 'docs') { + const smartScope = scope === 'all' ? 'all' : scope; + const smartResults = smartSearch(query, smartScope, limit); + if (smartResults.results) { + results.push(...smartResults.results.map((r: any) => ({ + type: r.type, + name: r.name, + relevance: r.relevance, + description: r.description, + howToUse: r.howToUse, + }))); + } + } + + results.sort((a, b) => (b.relevance || 0) - (a.relevance || 0)); + const limited = results.slice(0, limit); + + return jsonResponse({ + query, scope, totalResults: limited.length, + results: limited, + tip: limited.length > 0 + ? 'Use hana_get_doc with the path to read full documentation content' + : 'No matches found. Try different keywords or use hana_discover_categories to browse.', + }); + } + + if (commandName === 'get_doc') { + const path = args?.path; + if (!path) return errorResponse('Error: path parameter is required'); + + if (!docsSearch.isAvailable()) { + return errorResponse('Documentation index not available. Run "npm run build:docs-index" in the project root.'); + } + + const document = docsSearch.getDocument(path); + const content = docsSearch.getDocumentContent(path); + + if (!document || !content) { + return jsonResponse({ + error: `Document not found: ${path}`, + tip: 'Use hana_search to find valid document paths', + }); + } + + return jsonResponse({ + title: document.title, path: document.path, + category: document.category, docType: document.docType, + url: `https://sap-samples.github.io/hana-developer-cli-tool-example/${path.replace('.md', '.html')}`, + headings: document.headings, content, relatedLinks: document.links, + lastModified: document.lastModified, + }); + } + + return null; +} diff --git a/mcp-server/src/tools/types.ts b/mcp-server/src/tools/types.ts new file mode 100644 index 00000000..2f98129d --- /dev/null +++ b/mcp-server/src/tools/types.ts @@ -0,0 +1,27 @@ +export interface ToolDefinition { + name: string; + description: string; + inputSchema: { + type: string; + properties: Record; + required?: string[]; + }; +} + +export interface ToolResponse { + content: Array<{ type: string; text: string }>; + isError?: boolean; + [key: string]: unknown; +} + +export function textResponse(text: string): ToolResponse { + return { content: [{ type: 'text', text }] }; +} + +export function jsonResponse(data: any): ToolResponse { + return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] }; +} + +export function errorResponse(message: string): ToolResponse { + return { content: [{ type: 'text', text: message }], isError: true }; +} diff --git a/mcp-server/src/workflow-execution.ts b/mcp-server/src/workflow-execution.ts deleted file mode 100644 index b0b5dae1..00000000 --- a/mcp-server/src/workflow-execution.ts +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Workflow execution system - * Executes multi-step workflows with parameter substitution - */ - -import { getAllWorkflows, getWorkflowById, Workflow, WorkflowStep } from './command-metadata.js'; - -export interface WorkflowExecutionResult { - workflowId: string; - workflowName: string; - totalSteps: number; - completedSteps: number; - failedStep?: number; - results: StepResult[]; - success: boolean; - duration?: number; -} - -export interface StepResult { - step: number; - command: string; - parameters: Record; - success: boolean; - output?: string; - error?: string; - duration?: number; -} - -/** - * Substitute parameters in workflow steps - */ -function substituteParameters( - parameters: Record, - parameterTemplate: Record -): Record { - const result: Record = {}; - - for (const [key, value] of Object.entries(parameterTemplate)) { - if (typeof value === 'string' && value.startsWith('<') && value.endsWith('>')) { - // Extract parameter name from format - const paramName = value.slice(1, -1); - if (parameters[paramName]) { - result[key] = parameters[paramName]; - } else { - // Keep placeholder if no value provided - result[key] = value; - } - } else { - result[key] = value; - } - } - - return result; -} - -/** - * Validate that all required parameters are provided - */ -export function validateWorkflowParameters( - workflow: Workflow, - parameters: Record -): { valid: boolean; missing: string[] } { - const required = new Set(); - - // Extract all required parameters from workflow steps - for (const step of workflow.steps) { - if (step.keyParameters) { - for (const value of Object.values(step.keyParameters)) { - if (typeof value === 'string' && value.startsWith('<') && value.endsWith('>')) { - const paramName = value.slice(1, -1); - required.add(paramName); - } - } - } - } - - const missing: string[] = []; - for (const param of required) { - if (!parameters[param]) { - missing.push(param); - } - } - - return { - valid: missing.length === 0, - missing, - }; -} - -/** - * Simulate workflow execution (dry run) - * In production, this would call executeCommand for each step - */ -export async function executeWorkflow( - workflowId: string, - parameters: Record, - stopOnError: boolean = true -): Promise { - const workflow = getWorkflowById(workflowId); - - if (!workflow) { - return { - workflowId, - workflowName: 'Unknown', - totalSteps: 0, - completedSteps: 0, - results: [], - success: false, - error: `Workflow not found: ${workflowId}`, - } as any; - } - - // Validate parameters - const validation = validateWorkflowParameters(workflow, parameters); - if (!validation.valid) { - return { - workflowId, - workflowName: workflow.name, - totalSteps: workflow.steps.length, - completedSteps: 0, - results: [], - success: false, - error: `Missing required parameters: ${validation.missing.join(', ')}`, - } as any; - } - - const results: StepResult[] = []; - const startTime = Date.now(); - let completedSteps = 0; - let failedStep: number | undefined; - - for (const step of workflow.steps) { - const stepStartTime = Date.now(); - const stepParameters = step.keyParameters - ? substituteParameters(parameters, step.keyParameters) - : {}; - - // Note: In production, this would call executeCommand(step.command, stepParameters) - // For now, we simulate the execution - const stepResult: StepResult = { - step: step.order, - command: step.command, - parameters: stepParameters, - success: true, // Simulated success - output: `Successfully executed ${step.command}`, - duration: Date.now() - stepStartTime, - }; - - results.push(stepResult); - - if (stepResult.success) { - completedSteps++; - } else { - failedStep = step.order; - if (stopOnError) { - break; - } - } - } - - return { - workflowId, - workflowName: workflow.name, - totalSteps: workflow.steps.length, - completedSteps, - failedStep, - results, - success: completedSteps === workflow.steps.length, - duration: Date.now() - startTime, - }; -} - -/** - * Get workflow preview with substituted parameters - */ -export function previewWorkflow( - workflowId: string, - parameters: Record -): any { - const workflow = getWorkflowById(workflowId); - - if (!workflow) { - return { - error: `Workflow not found: ${workflowId}`, - }; - } - - const validation = validateWorkflowParameters(workflow, parameters); - - return { - workflowId: workflow.id, - name: workflow.name, - description: workflow.description, - goal: workflow.goal, - estimatedTime: workflow.estimatedTime, - validation: { - valid: validation.valid, - missingParameters: validation.missing, - }, - steps: workflow.steps.map(step => ({ - order: step.order, - command: step.command, - description: step.description, - parameters: step.keyParameters - ? substituteParameters(parameters, step.keyParameters) - : {}, - expectedOutput: step.expectedOutput, - })), - }; -} diff --git a/package.json b/package.json index db6946d3..9938219f 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,10 @@ "description": "HANA Developer Command Line Interface", "main": "index.js", "bin": { - "hana-cli": "./bin/cli.js" + "hana-cli": "./bin/cli.js", + "hana-cli-mcp": "./mcp-server/build/index.js" }, + "mcpName": "io.github.SAP-samples/hana-cli", "type": "module", "engines": { "node": ">=20.19.0" diff --git a/scripts/prepare-release.js b/scripts/prepare-release.js index 7189c415..32009daa 100644 --- a/scripts/prepare-release.js +++ b/scripts/prepare-release.js @@ -141,6 +141,14 @@ function run() { cwd: PACKAGES['mcp-server'].dir, stdio: 'pipe', }) + + const serverJsonPath = join(ROOT, 'server.json') + const serverJson = JSON.parse(readFileSync(serverJsonPath, 'utf8')) + serverJson.version = newVersion + if (serverJson.packages?.[0]) { + serverJson.packages[0].version = newVersion + } + writeFileSync(serverJsonPath, JSON.stringify(serverJson, null, 2) + '\n') } } diff --git a/server.json b/server.json new file mode 100644 index 00000000..a730b060 --- /dev/null +++ b/server.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", + "name": "io.github.SAP-samples/hana-cli", + "title": "SAP HANA CLI", + "description": "150+ SAP HANA database tools as MCP tools for AI assistants", + "repository": { + "url": "https://github.com/SAP-samples/hana-developer-cli-tool-example", + "source": "github" + }, + "version": "4.202604.0", + "packages": [ + { + "registryType": "npm", + "identifier": "hana-cli", + "version": "4.202604.0", + "runtimeHint": "npx", + "runtimeArguments": ["-y", "-p", "hana-cli", "hana-cli-mcp"], + "packageArguments": [], + "transport": { + "type": "stdio" + } + } + ] +}