UNPKG

hana-cli

Version:
204 lines (160 loc) 8.74 kB
# MCP Connection Context - Visual Summary ## The Problem: Connection Mismatch ```mermaid flowchart LR subgraph PA[Project A: ~/projects/project-a] Aenv[.env<br/>host=db-a.company.com<br/>user=admin-a<br/>password=pass-a] Apkg[package.json] end subgraph PB[Project B: ~/projects/project-b] Benv[.env<br/>host=db-b.company.com<br/>user=admin-b<br/>password=pass-b] Bpkg[package.json] end Q["AI Agent asks:<br/>List tables in Project B"] --> M["MCP Server calls: hana_tables"] M --> C["CLI connects via:<br/>~/.hana-cli/default.json<br/>(WRONG DB)"] C --> R["Result:<br/>Tables from Project A's database"] ``` ## The Solution: Project Context Passing ```mermaid flowchart LR subgraph PA2[Project A: ~/projects/project-a] A2env[.env<br/>database-a credentials] A2pkg[package.json] end subgraph PB2[Project B: ~/projects/project-b] B2env[.env<br/>database-b credentials] B2pkg[package.json] end Q2["AI Agent asks:<br/>List tables in Project B<br/>+ __projectContext.projectPath"] --> M2["MCP Server extracts context"] M2 --> X2["CLI changes to:<br/>~/projects/project-b/"] X2 --> C2["CLI connects via:<br/>~/projects/project-b/.env<br/>(CORRECT DB)"] C2 --> R2["Result:<br/>Tables from Project B's database"] ``` --- ## Current Architecture ```mermaid flowchart TB A["AI Agent / LLM"] --> B["MCP Server (index.ts)<br/>✓ Lists commands, discovers features<br/>✗ No project context received"] B --> C["Executor (executor.ts)<br/>spawn('node', [cli.js, 'tables', '--schema...'])<br/>✗ cwd = install path (hardcoded)<br/>✗ No project-specific env vars"] C --> D["CLI Process"] D --> E["Database Client (database/index.js)<br/>dbClientClass.getNewClient()<br/>✓ Gets connection options from getConnOptions()"] E --> F["Connections Module (connections.js)<br/>Search order (cwd=install path):<br/>1. .cdsrc-private.json<br/>2. default-env.json (install path) USED<br/>3. ~/.hana-cli/default.json (home dir)<br/>4. .env file<br/>5. VCAP_SERVICES<br/>✗ Never looks in project dir<br/>✗ Always uses install path or home dir"] F --> G["✗ WRONG DATABASE!"] ``` ## Proposed Architecture ```mermaid flowchart TB A2["AI Agent / LLM"] --> B2["MCP Server (index.ts) [UPDATED]<br/>✓ Extracts __projectContext from args<br/>✓ Removes context from CLI args (not a param)<br/>✓ Passes context to executeCommand()"] B2 --> C2["Executor (executor.ts) [UPDATED]<br/>✓ Receives connection context<br/>✓ Sets cwd = context.projectPath<br/>✓ Sets env vars: HANA_CLI_PROJECT_PATH<br/>✓ Sets env vars: HANA_CLI_CONN_FILE<br/>spawn('node', [cli.js, 'tables'...], {env, cwd})"] C2 --> D2["CLI Process"] D2 --> E2["Database Client (database/index.js)<br/>dbClientClass.getNewClient()<br/>✓ Gets connection options from getConnOptions()"] E2 --> F2["Connections Module (connections.js) [UPDATED]<br/>NEW: Check HANA_CLI_PROJECT_PATH and chdir<br/>Search order (project directory):<br/>1. .cdsrc-private.json (project) USED<br/>2. default-env.json (project) USED<br/>3. ~/.hana-cli/default.json (fallback)<br/>4. .env file (project) USED<br/>5. VCAP_SERVICES<br/>✓ First looks in project directory<br/>✓ Can still fall back to home dir"] F2 --> G2["✓ CORRECT DATABASE!"] ``` --- ## Message Flow Comparison ### Before (All commands use install path) ```mermaid flowchart TB subgraph Before[Before: install path always used] B1["Agent: List tables in Project A"] --> B2["MCP: tables {schema: 'A_SCHEMA'}"] B2 --> B3["CLI connects via ~/.hana-cli/default.json (Database A)"] B4["Agent: List tables in Project B"] --> B5["MCP: tables {schema: 'B_SCHEMA'}"] B5 --> B6["CLI connects via ~/.hana-cli/default.json (Database A) ✗"] B3 --> B7["Result: Both commands hit Database A (WRONG)"] B6 --> B7 end ``` ### After (Each command uses project context) ```mermaid flowchart TB subgraph After[After: project context applied] A1["Agent: List tables in Project A"] --> A2["MCP: tables {schema: 'A_SCHEMA', __projectContext: {projectPath: '/proj/a'}}"] A2 --> A3["CLI changes to /proj/a, connects via ./default-env.json (Database A) ✓"] A4["Agent: List tables in Project B"] --> A5["MCP: tables {schema: 'B_SCHEMA', __projectContext: {projectPath: '/proj/b'}}"] A5 --> A6["CLI changes to /proj/b, connects via ./default-env.json (Database B) ✓"] A3 --> A7["Result: Each command hits correct database (CORRECT)"] A6 --> A7 end ``` --- ## Implementation Timeline ```mermaid timeline title Implementation Timeline Week 1 : Update executor.ts, Update index.ts, Update schemas Week 2 : CLI updates, Security, Testing Week 3 onwards : Testing, Documentation, Rollout ``` --- ## Key Code Sections to Modify | Component | File | Lines | Change Type | | --------- | ---- | ----- | ----------- | | Context Interface | `mcp-server/src/connection-context.ts` | NEW | Create | | Executor Function | `mcp-server/src/executor.ts` | 240-280 | Update signature & spawn | | Tool Handler | `mcp-server/src/index.ts` | 145, 1325 | Update schemas & handler | | CLI Connections | `utils/connections.js` | 92-110 | Add env var checks | --- ## Data Flow: Single Command Execution ```mermaid flowchart TB A["Tool Called: hana_tables"] --> B["Arguments: {schema: 'MY_SCHEMA', __projectContext: {projectPath: '/app'}}"] B --> C["Tool Handler<br/>Extract context and remove __projectContext"] C --> D["executeCommand('tables', cleanArgs, context)"] D --> E["Executor builds env<br/>HANA_CLI_PROJECT_PATH=/app<br/>HANA_CLI_CONN_FILE=.env"] E --> F["Spawn CLI<br/>node /install/bin/cli.js tables<br/>cwd=/app"] F --> G["CLI Process (bin/cli.js)<br/>Table handler getNewClient()"] G --> H["Database Client (database/index.js)<br/>getConnOptions()"] H --> I["Connections Module (connections.js)<br/>chdir('/app') and search .env<br/>Load credentials"] I --> J["Return: Connection to app's database ✓"] ``` --- ## Backward Compatibility ```mermaid flowchart LR subgraph Current[Current Users (No Context)] C1["MCP Tool Call: hana_tables<br/>{schema: 'X_SCHEMA'}"] --> C2["Behavior:<br/>No context extracted<br/>Uses install path (cwd)<br/>Finds ~/.hana-cli/default.json<br/>Works as before ✓"] end subgraph New[New Users (With Context)] N1["MCP Tool Call: hana_tables<br/>{schema: 'X_SCHEMA', __projectContext: {...}}"] --> N2["Behavior:<br/>Context extracted<br/>Uses project path (cwd)<br/>Finds /project/.env<br/>Works correctly ✓"] end ``` --- ## Security Model ```mermaid flowchart TB S1["MCP Tool Input (from AI Agent)<br/>✓ projectPath<br/>✓ connectionFile name<br/>✓ host/port/user/password (prefer .env files)"] S1 --> S2["Validation Layer"] S2 --> S3["Executor Security Checks<br/>✓ Normalize paths (prevent ..)<br/>✓ Check path exists<br/>✓ Optional: whitelist allowed paths<br/>✓ Sanitize env variable names<br/>✓ Don't log passwords"] S3 --> S4["Environment Variables (to CLI)<br/>✓ HANA_CLI_PROJECT_PATH=/safe/path<br/>✓ HANA_CLI_USER=safe_user<br/>✗ HANA_CLI_PASSWORD=[NEVER LOG]"] ``` --- ## Testing Matrix | Test Case | Before | After | Expected | | --- | --- | --- | --- | | No context param | Works | Works | Same behavior | | With projectPath | Ignored | Used | Uses project dir | | With connectionFile | Ignored | Used | Uses specified file | | With direct credentials | Ignored | Used | Direct connection | | Context switching | N/A | Works | Each cmd gets own DB | | Multiple projects | Fails | Works | Isolated contexts | --- ## Benefits Summary | Perspective | Benefit | | ----------- | ------- | | **AI Agents** | Can work with multiple projects, switching databases mid-conversation | | **Developers** | No manual connection setup per project | | **Teams** | Project-specific DBs for different environments (dev/test/prod) | | **Security** | Each project isolated to its credentials | | **Backward Compat** | Existing integrations work unchanged | --- ## Quick Reference: 5-Step Implementation 1. **Create interface** `connection-context.ts` 2. **Update executor** Handle context in `executeCommand()` 3. **Update MCP tools** Pass context from handler 4. **Update CLI** Check env vars in `connections.js` 5. **Test & Deploy** Backward compatible, no breaking changes ## See Also - [Architecture](./architecture.md) - [Connection Guide](./connection-guide.md) - [Server Usage](./server-usage.md)