{"_id":"@ai-capabilities-suite/mcp-client-base","_rev":"3-bfefe7cc87acce530492e21638f67e00","name":"@ai-capabilities-suite/mcp-client-base","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@ai-capabilities-suite/mcp-client-base","version":"1.0.0","keywords":["mcp","model-context-protocol","vscode","extension","client","timeout","reconnect"],"author":{"name":"Digital Defiance"},"license":"MIT","_id":"@ai-capabilities-suite/mcp-client-base@1.0.0","maintainers":[{"name":"jessica-mulein","email":"jessica@mulein.com"}],"homepage":"https://github.com/Digital-Defiance/mcp-client-base#readme","bugs":{"url":"https://github.com/Digital-Defiance/mcp-client-base/issues"},"dist":{"shasum":"09ba219803b1488f67d1ad1f1e8b1d02bde6fb3e","tarball":"https://registry.npmjs.org/@ai-capabilities-suite/mcp-client-base/-/mcp-client-base-1.0.0.tgz","fileCount":31,"integrity":"sha512-+Rbr7U82/OX7ausqVRlgr2Z06X7D9NIrkbqtzecQmMMbQG0PJ7cFoFhy+8S0Hg0KuipiH0wamPihnXTZUi2eeQ==","signatures":[{"sig":"MEYCIQCyc0SOy5Zm+eMB7XfJLZXuYn+GNPbv8gN1XKRwXio5UQIhAP6JeRmPVZ2WW6jnWAep1FcDmIKoPtJOL027B3izn4lq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94907},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","watch":"tsc --watch","test:watch":"jest --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"jessica-mulein","email":"jessica@mulein.com"},"repository":{"url":"git+https://github.com/Digital-Defiance/mcp-client-base.git","type":"git"},"_npmVersion":"11.6.3","description":"Shared MCP client base class with timeout handling, re-synchronization, and connection state management","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","fast-check":"^3.15.0","typescript":"^5.3.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@types/vscode":"^1.85.0","@typescript-eslint/parser":"^8.0.0","@typescript-eslint/eslint-plugin":"^8.0.0","@digitaldefiance/express-suite-test-utils":"^1.0.13"},"peerDependencies":{"vscode":"^1.85.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-client-base_1.0.0_1766002386473_0.9547904511338958","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@ai-capabilities-suite/mcp-client-base","version":"1.0.1","keywords":["mcp","model-context-protocol","vscode","extension","client","timeout","reconnect"],"author":{"name":"Digital Defiance"},"license":"MIT","_id":"@ai-capabilities-suite/mcp-client-base@1.0.1","maintainers":[{"name":"jessica-mulein","email":"jessica@mulein.com"}],"homepage":"https://github.com/Digital-Defiance/mcp-client-base#readme","bugs":{"url":"https://github.com/Digital-Defiance/mcp-client-base/issues"},"dist":{"shasum":"2c81f8b3399d9557924b594c7bd342c6d611803f","tarball":"https://registry.npmjs.org/@ai-capabilities-suite/mcp-client-base/-/mcp-client-base-1.0.1.tgz","fileCount":35,"integrity":"sha512-kAv14HauuOgBeuccJf8Cx1lQ47vRw5jEEqtguNqoZh/2RkRs5ZGXdZ3cXC7bMly6uUTRkAufyHKAoY60udld9Q==","signatures":[{"sig":"MEUCIQDLjn3IH/cizxT2IJRaCD7VzoULBKnS2Fn/ea//nwrIngIgdwoYMhpnuaBOltxRC4+PGMk+lplGXRa3RpCRG7zETgs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120827},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","watch":"tsc --watch","test:watch":"jest --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"jessica-mulein","email":"jessica@mulein.com"},"repository":{"url":"git+https://github.com/Digital-Defiance/mcp-client-base.git","type":"git"},"_npmVersion":"11.6.3","description":"Shared MCP client base class with timeout handling, re-synchronization, and connection state management","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","ts-jest":"^29.1.0","fast-check":"^3.15.0","typescript":"^5.3.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@types/vscode":"^1.85.0","@typescript-eslint/parser":"^8.0.0","@typescript-eslint/eslint-plugin":"^8.0.0","@digitaldefiance/express-suite-test-utils":"^1.0.13"},"peerDependencies":{"vscode":"^1.85.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-client-base_1.0.1_1766303925616_0.7960072277631935","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@ai-capabilities-suite/mcp-client-base","version":"1.0.2","description":"Shared MCP client base class with timeout handling, re-synchronization, and connection state management","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","watch":"tsc --watch","clean":"rm -rf dist","test":"jest","test:watch":"jest --watch","lint":"eslint src --ext .ts","prepublishOnly":"npm run build"},"keywords":["mcp","model-context-protocol","vscode","extension","client","timeout","reconnect"],"author":{"name":"Digital Defiance"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Digital-Defiance/mcp-client-base.git"},"peerDependencies":{"vscode":"^1.85.0"},"devDependencies":{"@digitaldefiance/express-suite-test-utils":"^1.0.13","@types/jest":"^29.5.0","@types/node":"^20.0.0","@types/vscode":"^1.85.0","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","eslint":"^8.0.0","fast-check":"^3.15.0","jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.3.0"},"_id":"@ai-capabilities-suite/mcp-client-base@1.0.2","bugs":{"url":"https://github.com/Digital-Defiance/mcp-client-base/issues"},"homepage":"https://github.com/Digital-Defiance/mcp-client-base#readme","_nodeVersion":"22.21.1","_npmVersion":"11.6.3","dist":{"integrity":"sha512-/hgUUZy+XL60nK5DGLoEU7ZmhY0BaCd2WLUru5VJbbn1tnq3kiBdAkpZ8xbBaHiouNtZsl9Qox6Y0ym7c/nrOg==","shasum":"0a96fdfc31fcb515c63e9e97eda74f3830e6daf2","tarball":"https://registry.npmjs.org/@ai-capabilities-suite/mcp-client-base/-/mcp-client-base-1.0.2.tgz","fileCount":35,"unpackedSize":121707,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAEsduHWqUDkAd9xk+GqB15dcKodFPRX9oikBMZrojNTAiAqbuJBUkgdpUcTbj9ayma50yu794Dp0NcVcaQKhh5fCA=="}]},"_npmUser":{"name":"jessica-mulein","email":"jessica@mulein.com"},"directories":{},"maintainers":[{"name":"jessica-mulein","email":"jessica@mulein.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-client-base_1.0.2_1766616249358_0.2505411458001232"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-17T20:13:06.387Z","modified":"2025-12-24T22:44:09.728Z","1.0.0":"2025-12-17T20:13:06.648Z","1.0.1":"2025-12-21T07:58:45.775Z","1.0.2":"2025-12-24T22:44:09.513Z"},"bugs":{"url":"https://github.com/Digital-Defiance/mcp-client-base/issues"},"author":{"name":"Digital Defiance"},"license":"MIT","homepage":"https://github.com/Digital-Defiance/mcp-client-base#readme","keywords":["mcp","model-context-protocol","vscode","extension","client","timeout","reconnect"],"repository":{"type":"git","url":"git+https://github.com/Digital-Defiance/mcp-client-base.git"},"description":"Shared MCP client base class with timeout handling, re-synchronization, and connection state management","maintainers":[{"name":"jessica-mulein","email":"jessica@mulein.com"}],"readme":"# @ai-capabilities-suite/mcp-client-base\n\nShared MCP (Model Context Protocol) client base class providing consistent timeout handling, automatic re-synchronization, and connection state management for VSCode extensions.\n\n## Features\n\n- **Configurable Timeouts**: Different timeout values for initialization vs. standard requests\n- **Automatic Re-synchronization**: Exponential backoff retry logic when timeouts occur\n- **Connection State Management**: Track and notify listeners of connection state changes\n- **Consistent Error Handling**: Unified error messages and recovery options\n- **Extensible Architecture**: Abstract base class that extensions can customize\n- **Comprehensive Logging**: Structured logging with timestamps and request IDs\n- **Diagnostic Commands**: Built-in commands for troubleshooting connection issues\n\n## Installation\n\n```bash\nnpm install @ai-capabilities-suite/mcp-client-base\n```\n\n## Quick Start\n\n```typescript\nimport {\n  BaseMCPClient,\n  MCPClientConfig,\n} from \"@ai-capabilities-suite/mcp-client-base\";\nimport * as vscode from \"vscode\";\n\n// 1. Extend BaseMCPClient\nexport class MyMCPClient extends BaseMCPClient {\n  protected getServerCommand() {\n    return { command: \"npx\", args: [\"-y\", \"@my-org/my-mcp-server\"] };\n  }\n\n  protected getServerEnv() {\n    return { ...process.env };\n  }\n\n  protected async onServerReady() {\n    // Extension-specific initialization\n  }\n}\n\n// 2. Create and start the client\nconst outputChannel = vscode.window.createOutputChannel(\"My Extension\", {\n  log: true,\n});\nconst client = new MyMCPClient(outputChannel);\nawait client.start();\n\n// 3. Use the client\nconst result = await client.callTool(\"my_tool\", { param: \"value\" });\n```\n\n## Documentation\n\n- [API Reference](./docs/API.md) - Complete API documentation\n- [Extending BaseMCPClient](./docs/EXTENDING.md) - Guide to creating custom MCP clients\n- [Configuration Guide](./docs/CONFIGURATION.md) - Timeout and re-sync configuration\n- [Diagnostic Commands](./docs/DIAGNOSTICS.md) - Troubleshooting and diagnostic tools\n- [Troubleshooting Guide](./docs/TROUBLESHOOTING.md) - Common issues and solutions\n\n## Key Concepts\n\n### Connection States\n\nThe client tracks connection state through a state machine:\n\n- `DISCONNECTED` - Not connected to server\n- `CONNECTING` - Attempting to establish connection\n- `CONNECTED` - Successfully connected and ready\n- `TIMEOUT_RETRYING` - Timeout occurred, attempting re-synchronization\n- `ERROR` - Unrecoverable error occurred\n\n### Timeout Handling\n\nDifferent request types have different timeout values:\n\n- **Initialization**: 60 seconds (server startup can be slow)\n- **Standard Requests**: 30 seconds (normal operations)\n- **Tools List**: 60 seconds (may involve discovery)\n\n### Re-synchronization\n\nWhen a timeout occurs during initialization, the client automatically attempts to re-synchronize using exponential backoff:\n\n1. First retry after 2 seconds\n2. Second retry after 3 seconds (2 × 1.5)\n3. Third retry after 4.5 seconds (3 × 1.5)\n\n## Usage Examples\n\n### Basic Extension\n\n```typescript\nimport { BaseMCPClient } from \"@ai-capabilities-suite/mcp-client-base\";\nimport * as vscode from \"vscode\";\n\nexport class MyMCPClient extends BaseMCPClient {\n  constructor(outputChannel: vscode.LogOutputChannel) {\n    super(outputChannel, {\n      timeout: {\n        initializationTimeoutMs: 60000,\n        standardRequestTimeoutMs: 30000,\n        toolsListTimeoutMs: 60000,\n      },\n      reSync: {\n        maxRetries: 3,\n        retryDelayMs: 2000,\n        backoffMultiplier: 1.5,\n      },\n      logging: {\n        logLevel: \"info\",\n        logCommunication: true,\n      },\n    });\n  }\n\n  protected getServerCommand() {\n    return {\n      command: \"npx\",\n      args: [\"-y\", \"@my-org/my-mcp-server\"],\n    };\n  }\n\n  protected getServerEnv() {\n    return { ...process.env };\n  }\n\n  protected async onServerReady() {\n    // Verify server is working\n    await this.callTool(\"health_check\", {});\n  }\n\n  // Extension-specific methods\n  async doSomething(params: any): Promise<any> {\n    return await this.callTool(\"my_tool\", params);\n  }\n}\n```\n\n### Monitoring Connection State\n\n```typescript\nconst client = new MyMCPClient(outputChannel);\n\n// Subscribe to state changes\nconst disposable = client.onStateChange((status) => {\n  console.log(`State: ${status.state}`);\n  console.log(`Message: ${status.message}`);\n  console.log(`Server Running: ${status.serverProcessRunning}`);\n\n  if (status.state === \"ERROR\") {\n    vscode.window.showErrorMessage(`Connection error: ${status.message}`);\n  }\n});\n\nawait client.start();\n\n// Later: cleanup\ndisposable.dispose();\nclient.stop();\n```\n\n### Using Diagnostic Commands\n\n```typescript\nimport { diagnosticCommands } from \"@ai-capabilities-suite/mcp-client-base\";\n\n// Register your extension\ndiagnosticCommands.registerExtension({\n  name: \"my-extension\",\n  displayName: \"My Extension\",\n  client: myClient,\n});\n\n// Reconnect to server\nawait diagnosticCommands.reconnectToServer(\"my-extension\");\n\n// Restart server\nawait diagnosticCommands.restartServer(\"my-extension\");\n\n// Get diagnostics\nconst diag = diagnosticCommands.getDiagnostics(\"my-extension\");\nconsole.log(diagnosticCommands.formatDiagnostics(diag));\n\n// Get all extensions status\nconst allDiag = diagnosticCommands.getAllDiagnostics();\nconsole.log(diagnosticCommands.formatAllDiagnostics());\n```\n\n## Configuration\n\n### Default Configuration\n\n```typescript\n{\n  timeout: {\n    initializationTimeoutMs: 60000,  // 60 seconds\n    standardRequestTimeoutMs: 30000,  // 30 seconds\n    toolsListTimeoutMs: 60000,        // 60 seconds\n  },\n  reSync: {\n    maxRetries: 3,                    // 3 retry attempts\n    retryDelayMs: 2000,               // 2 second initial delay\n    backoffMultiplier: 1.5,           // 1.5x backoff multiplier\n  },\n  logging: {\n    logLevel: 'info',                 // info level logging\n    logCommunication: true,           // log all communication\n  },\n}\n```\n\n### Custom Configuration\n\n```typescript\nconst client = new MyMCPClient(outputChannel, {\n  timeout: {\n    initializationTimeoutMs: 120000, // 2 minutes for slow servers\n    standardRequestTimeoutMs: 45000, // 45 seconds for slow operations\n  },\n  reSync: {\n    maxRetries: 5, // More retry attempts\n    retryDelayMs: 1000, // Faster initial retry\n    backoffMultiplier: 2.0, // Aggressive backoff\n  },\n  logging: {\n    logLevel: \"debug\", // Verbose logging\n    logCommunication: true,\n  },\n});\n```\n\n## Architecture\n\nThe package consists of four main components:\n\n1. **BaseMCPClient** - Abstract base class with core functionality\n2. **TimeoutManager** - Configurable timeout handling\n3. **ConnectionStateManager** - Connection state tracking and notifications\n4. **ReSyncManager** - Automatic re-synchronization with exponential backoff\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│              @ai-capabilities-suite/mcp-client-base         │\n│                                                              │\n│  ┌────────────────────────────────────────────────────────┐ │\n│  │              BaseMCPClient (Abstract)                   │ │\n│  │  ┌──────────────┐  ┌────────────────┐  ┌───────────┐ │ │\n│  │  │   Timeout    │  │ Re-sync Logic  │  │  Request  │ │ │\n│  │  │   Manager    │  │                │  │   Queue   │ │ │\n│  │  └──────────────┘  └────────────────┘  └───────────┘ │ │\n│  │  ┌──────────────────────────────────────────────────┐ │ │\n│  │  │        ConnectionStateManager                     │ │ │\n│  │  └──────────────────────────────────────────────────┘ │ │\n│  └────────────────────────────────────────────────────────┘ │\n└─────────────────────────────────────────────────────────────┘\n                            ▲\n                            │ extends\n          ┌─────────────────┼─────────────────┐\n          │                 │                  │\n┌─────────┴──────┐  ┌──────┴───────┐  ┌──────┴───────┐\n│ MCPProcessClient│  │MCPScreenshot │  │MCPDebugger   │\n│                 │  │   Client     │  │   Client     │\n└─────────────────┘  └──────────────┘  └──────────────┘\n```\n\n## Testing\n\nThe package includes comprehensive tests:\n\n- **Unit Tests** - Test individual components in isolation\n- **Property-Based Tests** - Verify correctness properties across all inputs\n- **Integration Tests** - Test full client lifecycle\n\nRun tests:\n\n```bash\nnpm test\n```\n\n## Contributing\n\nContributions are welcome! Please ensure:\n\n1. All tests pass\n2. New features include tests\n3. Documentation is updated\n4. Code follows existing style\n\n## License\n\nMIT\n","readmeFilename":"README.md"}