diff options
| author | christine betts <[email protected]> | 2025-07-14 15:34:44 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-14 15:34:44 +0000 |
| commit | e9d680e8a45b18152042214891132eec60e4a09b (patch) | |
| tree | f745dd75afd81079369b4234ecbf34f1adad396e /packages/vscode-ide-companion/src | |
| parent | 64f1d80b26af25708356e8a743ea7fab1496c7e9 (diff) | |
Introduce VSCode companion extension (#3917)
Diffstat (limited to 'packages/vscode-ide-companion/src')
| -rw-r--r-- | packages/vscode-ide-companion/src/extension.ts | 14 | ||||
| -rw-r--r-- | packages/vscode-ide-companion/src/ide-server.ts | 109 |
2 files changed, 123 insertions, 0 deletions
diff --git a/packages/vscode-ide-companion/src/extension.ts b/packages/vscode-ide-companion/src/extension.ts new file mode 100644 index 00000000..ecc63048 --- /dev/null +++ b/packages/vscode-ide-companion/src/extension.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as vscode from 'vscode'; +import { startIDEServer } from './ide-server'; + +export async function activate(context: vscode.ExtensionContext) { + startIDEServer(context); +} + +export function deactivate() {} diff --git a/packages/vscode-ide-companion/src/ide-server.ts b/packages/vscode-ide-companion/src/ide-server.ts new file mode 100644 index 00000000..6d25367c --- /dev/null +++ b/packages/vscode-ide-companion/src/ide-server.ts @@ -0,0 +1,109 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as vscode from 'vscode'; +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; +import express, { Request, Response } from 'express'; + +export async function startIDEServer(_context: vscode.ExtensionContext) { + const app = express(); + app.use(express.json()); + + const mcpServer = createMcpServer(); + const transport = new StreamableHTTPServerTransport({ + sessionIdGenerator: undefined, + enableJsonResponse: true, + }); + + mcpServer.connect(transport); + + app.post('/mcp', async (req: Request, res: Response) => { + console.log('Received MCP request:', req.body); + try { + await transport.handleRequest(req, res, req.body); + } catch (error) { + console.error('Error handling MCP request:', error); + if (!res.headersSent) { + res.status(500).json({ + jsonrpc: '2.0', + error: { + code: -32603, + message: 'Internal server error', + }, + id: null, + }); + } + } + }); + + // Handle GET requests for SSE streams + app.get('/mcp', async (req: Request, res: Response) => { + res.status(405).set('Allow', 'POST').send('Method Not Allowed'); + }); + + // Start the server + // TODO(#3918): Generate dynamically and write to env variable + const PORT = 3000; + app.listen(PORT, (error) => { + if (error) { + console.error('Failed to start server:', error); + vscode.window.showErrorMessage( + `Companion server failed to start on port ${PORT}: ${error.message}`, + ); + } + console.log(`MCP Streamable HTTP Server listening on port ${PORT}`); + }); +} + +const createMcpServer = () => { + const server = new McpServer({ + name: 'vscode-ide-server', + version: '1.0.0', + }); + server.registerTool( + 'getActiveFile', + { + description: + '(IDE Tool) Get the path of the file currently active in VS Code.', + inputSchema: {}, + }, + async () => { + try { + const activeEditor = vscode.window.activeTextEditor; + const filePath = activeEditor + ? activeEditor.document.uri.fsPath + : undefined; + if (filePath) { + return { + content: [{ type: 'text', text: `Active file: ${filePath}` }], + }; + } else { + return { + content: [ + { + type: 'text', + text: 'No file is currently active in the editor.', + }, + ], + }; + } + } catch (error) { + return { + content: [ + { + type: 'text', + text: `Failed to get active file: ${ + (error as Error).message || 'Unknown error' + }`, + }, + ], + }; + } + }, + ); + return server; +}; |
