@ai-ide-bridge/mcp 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+
2
+ > @ai-ide-bridge/mcp@1.0.2 build /home/runner/work/llm-bridge/llm-bridge/packages/mcp
3
+ > tsc
4
+
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # @ai-ide-bridge/mcp
2
+
3
+ The Model Context Protocol (MCP) server for **AI IDE Bridge**.
4
+
5
+ AI IDE Bridge is a local HTTP server that translates OpenAI-compatible API requests into provider-specific calls, enabling any OpenAI-format client to use any AI IDE's model catalog.
6
+
7
+ ## Overview
8
+
9
+ `@ai-ide-bridge/mcp` implements an MCP server over stdio, enabling direct integration with AI IDEs like Cursor. It exposes bridge status, model catalogs, and client configuration generation as MCP tools.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install @ai-ide-bridge/mcp
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ Configure the MCP server in your AI IDE (e.g., Cursor MCP settings):
20
+
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "llm-bridge": {
25
+ "command": "npx",
26
+ "args": ["-y", "@ai-ide-bridge/mcp"]
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ ## Available Tools
33
+
34
+ - `bridge_status` — Check bridge health and active plugins.
35
+ - `list_models` — Retrieve available models from all active plugins.
36
+ - `generate_opencode_config` — Generate provider configuration fragments for OpenCode.
37
+
38
+ ## Documentation
39
+
40
+ For full documentation and setup instructions, please visit the main repository: [https://github.com/aeswibon/llm-bridge](https://github.com/aeswibon/llm-bridge).
41
+
42
+ ## License
43
+
44
+ MIT
@@ -0,0 +1 @@
1
+ export { createMcpServer } from './server.js';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { createMcpServer } from './server.js';
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ export declare function createMcpServer(): McpServer;
package/dist/server.js ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { z } from 'zod';
5
+ const BRIDGE_PORT = Number(process.env.LLM_BRIDGE_PORT ?? '3849');
6
+ const BRIDGE_HOST = process.env.LLM_BRIDGE_HOST ?? '127.0.0.1';
7
+ function bridgeUrl(path) {
8
+ return `http://${BRIDGE_HOST}:${BRIDGE_PORT}${path}`;
9
+ }
10
+ export function createMcpServer() {
11
+ const server = new McpServer({ name: 'llm-bridge-mcp', version: '2.0.0' }, {
12
+ instructions: 'Manage llm-bridge: check status, list models, generate OpenCode config.',
13
+ });
14
+ server.registerTool('bridge_status', { description: 'Check llm-bridge server health and status.' }, async () => {
15
+ try {
16
+ const res = await fetch(bridgeUrl('/health'));
17
+ const body = await res.json();
18
+ if (res.ok) {
19
+ return { content: [{ type: 'text', text: JSON.stringify(body, null, 2) }] };
20
+ }
21
+ return { content: [{ type: 'text', text: `Bridge unhealthy: status ${res.status}` }] };
22
+ }
23
+ catch (e) {
24
+ const msg = e instanceof Error ? e.message : String(e);
25
+ return { content: [{ type: 'text', text: `Cannot reach bridge: ${msg}` }] };
26
+ }
27
+ });
28
+ server.registerTool('list_models', { description: 'List available models from the active provider.' }, async () => {
29
+ try {
30
+ const res = await fetch(bridgeUrl('/v1/models'));
31
+ const body = await res.json();
32
+ if (res.ok) {
33
+ const modelIds = body.data?.map((m) => m.id) ?? [];
34
+ return { content: [{ type: 'text', text: `Available models: ${modelIds.join(', ')}` }] };
35
+ }
36
+ return {
37
+ content: [{ type: 'text', text: `Failed to list models: ${JSON.stringify(body)}` }],
38
+ };
39
+ }
40
+ catch (e) {
41
+ const msg = e instanceof Error ? e.message : String(e);
42
+ return { content: [{ type: 'text', text: `Cannot reach bridge: ${msg}` }] };
43
+ }
44
+ });
45
+ server.registerTool('generate_opencode_config', {
46
+ description: 'Generate an OpenCode provider fragment for the bridge.',
47
+ inputSchema: {
48
+ providerId: z.string().optional().describe('Provider key (default: llm-bridge).'),
49
+ modelId: z.string().optional().describe('Model id (default: composer-2).'),
50
+ },
51
+ }, async ({ providerId, modelId }) => {
52
+ const pid = providerId ?? 'llm-bridge';
53
+ const mid = modelId ?? 'composer-2';
54
+ const fragment = {
55
+ provider: {
56
+ [pid]: {
57
+ npm: '@ai-sdk/openai-compatible',
58
+ name: 'LLM Bridge',
59
+ options: {
60
+ apiKey: 'bridge-local',
61
+ baseURL: bridgeUrl('/v1'),
62
+ },
63
+ models: { [mid]: { name: mid } },
64
+ },
65
+ },
66
+ };
67
+ return {
68
+ content: [
69
+ {
70
+ type: 'text',
71
+ text: `Merge into opencode.json:\n\n${JSON.stringify(fragment, null, 2)}`,
72
+ },
73
+ ],
74
+ };
75
+ });
76
+ return server;
77
+ }
78
+ async function main() {
79
+ const server = createMcpServer();
80
+ const transport = new StdioServerTransport();
81
+ await server.connect(transport);
82
+ }
83
+ const entry = process.argv[1];
84
+ if (entry && new URL(import.meta.url).pathname.endsWith(entry.split('/').pop())) {
85
+ void main();
86
+ }
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@ai-ide-bridge/mcp",
3
+ "version": "1.0.2",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "llm-bridge-mcp": "./dist/server.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "test": "vitest run",
13
+ "lint": "tsc --noEmit",
14
+ "typecheck": "tsc --noEmit",
15
+ "dev": "tsc --watch"
16
+ },
17
+ "dependencies": {
18
+ "@modelcontextprotocol/sdk": "^1.29.0",
19
+ "zod": "^3.25.76"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^22.15.0",
23
+ "vitest": "^2.0.0"
24
+ }
25
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { createMcpServer } from './server.js';
package/src/server.ts ADDED
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { z } from 'zod';
5
+
6
+ const BRIDGE_PORT = Number(process.env.LLM_BRIDGE_PORT ?? '3849');
7
+ const BRIDGE_HOST = process.env.LLM_BRIDGE_HOST ?? '127.0.0.1';
8
+
9
+ function bridgeUrl(path: string): string {
10
+ return `http://${BRIDGE_HOST}:${BRIDGE_PORT}${path}`;
11
+ }
12
+
13
+ export function createMcpServer(): McpServer {
14
+ const server = new McpServer(
15
+ { name: 'llm-bridge-mcp', version: '2.0.0' },
16
+ {
17
+ instructions: 'Manage llm-bridge: check status, list models, generate OpenCode config.',
18
+ },
19
+ );
20
+
21
+ server.registerTool(
22
+ 'bridge_status',
23
+ { description: 'Check llm-bridge server health and status.' },
24
+ async () => {
25
+ try {
26
+ const res = await fetch(bridgeUrl('/health'));
27
+ const body = await res.json();
28
+ if (res.ok) {
29
+ return { content: [{ type: 'text', text: JSON.stringify(body, null, 2) }] };
30
+ }
31
+ return { content: [{ type: 'text', text: `Bridge unhealthy: status ${res.status}` }] };
32
+ } catch (e) {
33
+ const msg = e instanceof Error ? e.message : String(e);
34
+ return { content: [{ type: 'text', text: `Cannot reach bridge: ${msg}` }] };
35
+ }
36
+ },
37
+ );
38
+
39
+ server.registerTool(
40
+ 'list_models',
41
+ { description: 'List available models from the active provider.' },
42
+ async () => {
43
+ try {
44
+ const res = await fetch(bridgeUrl('/v1/models'));
45
+ const body = await res.json();
46
+ if (res.ok) {
47
+ const modelIds = body.data?.map((m: any) => m.id) ?? [];
48
+ return { content: [{ type: 'text', text: `Available models: ${modelIds.join(', ')}` }] };
49
+ }
50
+ return {
51
+ content: [{ type: 'text', text: `Failed to list models: ${JSON.stringify(body)}` }],
52
+ };
53
+ } catch (e) {
54
+ const msg = e instanceof Error ? e.message : String(e);
55
+ return { content: [{ type: 'text', text: `Cannot reach bridge: ${msg}` }] };
56
+ }
57
+ },
58
+ );
59
+
60
+ server.registerTool(
61
+ 'generate_opencode_config',
62
+ {
63
+ description: 'Generate an OpenCode provider fragment for the bridge.',
64
+ inputSchema: {
65
+ providerId: z.string().optional().describe('Provider key (default: llm-bridge).'),
66
+ modelId: z.string().optional().describe('Model id (default: composer-2).'),
67
+ },
68
+ },
69
+ async ({ providerId, modelId }) => {
70
+ const pid = providerId ?? 'llm-bridge';
71
+ const mid = modelId ?? 'composer-2';
72
+ const fragment = {
73
+ provider: {
74
+ [pid]: {
75
+ npm: '@ai-sdk/openai-compatible',
76
+ name: 'LLM Bridge',
77
+ options: {
78
+ apiKey: 'bridge-local',
79
+ baseURL: bridgeUrl('/v1'),
80
+ },
81
+ models: { [mid]: { name: mid } },
82
+ },
83
+ },
84
+ };
85
+ return {
86
+ content: [
87
+ {
88
+ type: 'text',
89
+ text: `Merge into opencode.json:\n\n${JSON.stringify(fragment, null, 2)}`,
90
+ },
91
+ ],
92
+ };
93
+ },
94
+ );
95
+
96
+ return server;
97
+ }
98
+
99
+ async function main(): Promise<void> {
100
+ const server = createMcpServer();
101
+ const transport = new StdioServerTransport();
102
+ await server.connect(transport);
103
+ }
104
+
105
+ const entry = process.argv[1];
106
+ if (entry && new URL(import.meta.url).pathname.endsWith(entry.split('/').pop()!)) {
107
+ void main();
108
+ }
@@ -0,0 +1,14 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { createMcpServer } from '../src/server.js';
3
+
4
+ describe('MCP Server', () => {
5
+ it('creates server instance', () => {
6
+ const server = createMcpServer();
7
+ expect(server).toBeDefined();
8
+ });
9
+
10
+ it('has correct name and version', () => {
11
+ const server = createMcpServer();
12
+ expect(server).toBeDefined();
13
+ });
14
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src"
6
+ },
7
+ "include": ["src/**/*.ts"]
8
+ }