mcp-prompt-bridge 1.0.0

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.
package/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # mcp-prompt-bridge
2
+
3
+ **MCPのpromptsをtoolsとして再公開するMCPサーバー**
4
+
5
+ Claude CodeがMCPサーバーのpromptsを認識しない問題([#11054](https://github.com/anthropics/claude-code/issues/11054), [#3210](https://github.com/anthropics/claude-code/issues/3210))のワークアラウンドです。
6
+
7
+ ## 仕組み
8
+
9
+ ```
10
+ [Claude Code]
11
+ ↓ tools として呼び出し
12
+ [mcp-prompt-bridge] ← このサーバー
13
+ ↓ MCP client として接続(オンデマンド)
14
+ [既存のMCPサーバーA] [MCPサーバーB] ...
15
+ prompts/list → 一覧取得
16
+ prompts/get → 内容取得して返却
17
+ ```
18
+
19
+ 上流サーバーへの接続は常時ではなく、`list` / `get` が呼ばれたときだけ接続→取得→切断します。
20
+
21
+ ## セットアップ
22
+
23
+ ```bash
24
+ npm install
25
+ npm run build
26
+ ```
27
+
28
+ ## 使い方
29
+
30
+ Claude Codeの設定ファイル(`.mcp.json`, `~/.claude.json` 等)から
31
+ MCPサーバーを自動的に発見し、プロンプトをツールとして公開します。
32
+
33
+ ### Claude Codeへの登録
34
+
35
+ `.mcp.json` に追加:
36
+
37
+ ```json
38
+ {
39
+ "mcpServers": {
40
+ "prompt-bridge": {
41
+ "command": "node",
42
+ "args": ["/path/to/mcp-prompt-bridge/dist/index.js"]
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ CLIから:
49
+
50
+ ```bash
51
+ claude mcp add prompt-bridge -- node /path/to/mcp-prompt-bridge/dist/index.js
52
+ ```
53
+
54
+ ### 特定のサーバーを除外
55
+
56
+ ```bash
57
+ node dist/index.js --exclude slow-server --exclude broken-server
58
+ ```
59
+
60
+ ### サーバー発見の仕組み
61
+
62
+ 以下の設定ファイルを順番に読み込みます(後のものが優先):
63
+
64
+ 1. `~/.claude.json` — ユーザースコープ(cwdに対応するプロジェクト設定も読み込み)
65
+ 2. `~/.claude/settings.local.json` — ユーザーローカル
66
+ 3. `./.mcp.json` — プロジェクトスコープ
67
+ 4. `./.claude/settings.local.json` — プロジェクトローカル
68
+
69
+ 設定ファイルが見つからない場合は `claude mcp list` の出力をパースします。
70
+
71
+ ### 安全機能
72
+
73
+ - **自己排除**: 自身と同じ実行パスを持つサーバーを自動スキップ(循環接続防止)
74
+ - **HTTP除外**: HTTPトランスポートのサーバーはスキップ(stdioのみ対応)
75
+ - **プロンプト非対応サーバー**: エラーにならず静かにスキップ
76
+ - **タイムアウト**: 接続は10秒でタイムアウト
77
+ - **オンデマンド接続**: 起動時にサーバーを立ち上げず、ツール呼び出し時のみ接続
78
+
79
+ ## 公開されるツール
80
+
81
+ ### `list`
82
+
83
+ 全サーバーの全プロンプト一覧を返します(サーバー名、プロンプト名、説明、引数を含む)。
84
+
85
+ ### `get`
86
+
87
+ 特定のプロンプトを取得します。
88
+
89
+ | 引数 | 説明 |
90
+ |------|------|
91
+ | `server` | MCPサーバー名 |
92
+ | `prompt` | プロンプト名 |
93
+ | `arguments` | プロンプト引数(key-valueペア、省略可) |
94
+
95
+ ## CLI オプション
96
+
97
+ | オプション | 説明 |
98
+ |-----------|------|
99
+ | `--exclude <name>` | 除外するサーバー名(複数指定可) |
100
+ | `--help`, `-h` | ヘルプ表示 |
101
+
102
+ ## 制限事項
103
+
104
+ - stdioトランスポートのみ対応(HTTP/SSEサーバーは非対応)
105
+ - プロンプトの動的更新には未対応(再起動が必要)
106
+ - バイナリリソースを含むプロンプトはメタデータのみ表示
107
+
108
+ ## ライセンス
109
+
110
+ MIT
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Auto-discovery of MCP servers from Claude Code configuration.
3
+ *
4
+ * Reads from multiple sources:
5
+ * 1. Claude Code config files (.mcp.json, ~/.claude.json, ~/.claude/settings.local.json)
6
+ * 2. `claude mcp list` CLI output (fallback)
7
+ *
8
+ * Excludes self (mcp-prompt-bridge) to avoid circular connections.
9
+ */
10
+ import type { UpstreamServerConfig } from "./types.js";
11
+ /**
12
+ * Discover MCP servers from all available sources.
13
+ * @param excludeNames Additional server names to exclude
14
+ * @param cwd Working directory to search for project configs
15
+ */
16
+ export declare function discoverServers(excludeNames?: string[], cwd?: string): UpstreamServerConfig[];
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Auto-discovery of MCP servers from Claude Code configuration.
3
+ *
4
+ * Reads from multiple sources:
5
+ * 1. Claude Code config files (.mcp.json, ~/.claude.json, ~/.claude/settings.local.json)
6
+ * 2. `claude mcp list` CLI output (fallback)
7
+ *
8
+ * Excludes self (mcp-prompt-bridge) to avoid circular connections.
9
+ */
10
+ import { readFileSync, existsSync } from "node:fs";
11
+ import { resolve, join } from "node:path";
12
+ import { homedir } from "node:os";
13
+ import { execSync } from "node:child_process";
14
+ /**
15
+ * Get the resolved path of our own entry point, used to detect self.
16
+ */
17
+ function getSelfPath() {
18
+ // process.argv[1] is our dist/index.js
19
+ try {
20
+ return resolve(process.argv[1]);
21
+ }
22
+ catch {
23
+ return undefined;
24
+ }
25
+ }
26
+ /**
27
+ * Check if a server config points to ourselves.
28
+ */
29
+ function isSelf(server, selfPath) {
30
+ if (!selfPath)
31
+ return false;
32
+ // Check if any of the server's args resolve to our own entry point
33
+ for (const arg of server.args ?? []) {
34
+ try {
35
+ if (resolve(arg) === selfPath)
36
+ return true;
37
+ }
38
+ catch {
39
+ // ignore
40
+ }
41
+ }
42
+ return false;
43
+ }
44
+ /**
45
+ * Discover MCP servers from all available sources.
46
+ * @param excludeNames Additional server names to exclude
47
+ * @param cwd Working directory to search for project configs
48
+ */
49
+ export function discoverServers(excludeNames = [], cwd = process.cwd()) {
50
+ const excludeSet = new Set(excludeNames);
51
+ const selfPath = getSelfPath();
52
+ const servers = new Map();
53
+ // 1. Read config files (lower priority first, higher priority overwrites)
54
+ const configPaths = getConfigPaths(cwd);
55
+ for (const configPath of configPaths) {
56
+ const discovered = readConfigFile(configPath, cwd);
57
+ for (const server of discovered) {
58
+ if (excludeSet.has(server.name))
59
+ continue;
60
+ if (isSelf(server, selfPath)) {
61
+ console.error(`[auto-discover] Skipping "${server.name}" (self)`);
62
+ continue;
63
+ }
64
+ servers.set(server.name, server);
65
+ }
66
+ }
67
+ // 2. If no servers found from config files, try CLI
68
+ if (servers.size === 0) {
69
+ console.error("[auto-discover] No servers found in config files, trying claude mcp list...");
70
+ const cliServers = parseClaudeMcpList();
71
+ for (const server of cliServers) {
72
+ if (excludeSet.has(server.name))
73
+ continue;
74
+ if (isSelf(server, selfPath))
75
+ continue;
76
+ servers.set(server.name, server);
77
+ }
78
+ }
79
+ return Array.from(servers.values());
80
+ }
81
+ /**
82
+ * Get all config file paths to check, in order of priority (low → high).
83
+ */
84
+ function getConfigPaths(cwd) {
85
+ const home = homedir();
86
+ const paths = [];
87
+ // User-level configs (lowest priority)
88
+ paths.push(join(home, ".claude.json"));
89
+ paths.push(join(home, ".claude", "settings.local.json"));
90
+ // Project-level configs (higher priority)
91
+ paths.push(join(cwd, ".mcp.json"));
92
+ paths.push(join(cwd, ".claude", "settings.local.json"));
93
+ paths.push(join(cwd, ".claude", ".mcp.json"));
94
+ return paths;
95
+ }
96
+ /**
97
+ * Read and parse a single Claude Code config file.
98
+ * For ~/.claude.json, also reads the project-scoped mcpServers under projects[cwd].
99
+ */
100
+ function readConfigFile(filePath, cwd) {
101
+ if (!existsSync(filePath)) {
102
+ return [];
103
+ }
104
+ try {
105
+ const raw = readFileSync(filePath, "utf-8");
106
+ const parsed = JSON.parse(raw);
107
+ const servers = [];
108
+ // Top-level mcpServers
109
+ if (parsed.mcpServers) {
110
+ servers.push(...extractServers(parsed.mcpServers, filePath));
111
+ }
112
+ // Project-scoped mcpServers (e.g. ~/.claude.json projects[cwd].mcpServers)
113
+ if (parsed.projects) {
114
+ const resolvedCwd = resolve(cwd);
115
+ const projectConfig = parsed.projects[resolvedCwd];
116
+ if (projectConfig?.mcpServers) {
117
+ servers.push(...extractServers(projectConfig.mcpServers, `${filePath} [project: ${resolvedCwd}]`));
118
+ }
119
+ }
120
+ if (servers.length > 0) {
121
+ console.error(`[auto-discover] Found ${servers.length} server(s) in ${filePath}`);
122
+ }
123
+ return servers;
124
+ }
125
+ catch (err) {
126
+ console.error(`[auto-discover] Failed to read ${filePath}:`, err instanceof Error ? err.message : err);
127
+ return [];
128
+ }
129
+ }
130
+ function extractServers(mcpServers, source) {
131
+ const servers = [];
132
+ for (const [name, entry] of Object.entries(mcpServers)) {
133
+ if (entry.type === "http" || entry.url) {
134
+ console.error(`[auto-discover] Skipping "${name}" (HTTP transport not supported)`);
135
+ continue;
136
+ }
137
+ if (!entry.command) {
138
+ console.error(`[auto-discover] Skipping "${name}" (no command specified)`);
139
+ continue;
140
+ }
141
+ servers.push({
142
+ name,
143
+ command: entry.command,
144
+ args: entry.args,
145
+ env: entry.env,
146
+ cwd: entry.cwd,
147
+ });
148
+ }
149
+ return servers;
150
+ }
151
+ /**
152
+ * Parse `claude mcp list` output as a fallback.
153
+ *
154
+ * Expected format:
155
+ * server-name (scope): command args - ✓ Connected
156
+ * server-name: command args - ✓ Connected
157
+ */
158
+ function parseClaudeMcpList() {
159
+ try {
160
+ const output = execSync("claude mcp list 2>/dev/null", {
161
+ encoding: "utf-8",
162
+ timeout: 15000,
163
+ });
164
+ const servers = [];
165
+ // Match lines like: name (scope): command args - ✓ Connected
166
+ // or: name: command args - ✓ Connected
167
+ const lineRegex = /^(\S+?)(?:\s+\([^)]+\))?:\s+(.+?)\s+-\s+[✓✗]/;
168
+ for (const line of output.split("\n")) {
169
+ const match = line.match(lineRegex);
170
+ if (!match)
171
+ continue;
172
+ const name = match[1].trim();
173
+ const commandLine = match[2].trim();
174
+ const parts = commandLine.split(/\s+/);
175
+ const command = parts[0];
176
+ const args = parts.slice(1);
177
+ if (command) {
178
+ servers.push({ name, command, args });
179
+ }
180
+ }
181
+ if (servers.length > 0) {
182
+ console.error(`[auto-discover] Found ${servers.length} server(s) from claude mcp list`);
183
+ }
184
+ return servers;
185
+ }
186
+ catch (err) {
187
+ console.error("[auto-discover] claude mcp list failed:", err instanceof Error ? err.message : "command not found or timed out");
188
+ return [];
189
+ }
190
+ }
191
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * mcp-prompt-bridge
4
+ *
5
+ * An MCP server that connects to other MCP servers on demand,
6
+ * discovers their prompts, and re-exposes them as tools.
7
+ *
8
+ * This works around the issue where Claude Code cannot see MCP prompts
9
+ * but can see and use MCP tools.
10
+ *
11
+ * Usage:
12
+ * mcp-prompt-bridge
13
+ * mcp-prompt-bridge --exclude my-broken-server
14
+ */
15
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,336 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * mcp-prompt-bridge
4
+ *
5
+ * An MCP server that connects to other MCP servers on demand,
6
+ * discovers their prompts, and re-exposes them as tools.
7
+ *
8
+ * This works around the issue where Claude Code cannot see MCP prompts
9
+ * but can see and use MCP tools.
10
+ *
11
+ * Usage:
12
+ * mcp-prompt-bridge
13
+ * mcp-prompt-bridge --exclude my-broken-server
14
+ */
15
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
16
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
17
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
18
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
19
+ import { z } from "zod";
20
+ import { discoverServers } from "./discover.js";
21
+ /**
22
+ * Parse CLI arguments.
23
+ */
24
+ function parseArgs() {
25
+ const args = process.argv.slice(2);
26
+ const excludeNames = [];
27
+ for (let i = 0; i < args.length; i++) {
28
+ const arg = args[i];
29
+ if (arg === "--exclude" && args[i + 1]) {
30
+ excludeNames.push(args[++i]);
31
+ }
32
+ else if (arg === "--help" || arg === "-h") {
33
+ printUsage();
34
+ process.exit(0);
35
+ }
36
+ }
37
+ const servers = discoverServers(excludeNames);
38
+ if (servers.length === 0) {
39
+ console.error("Error: No upstream servers found.");
40
+ console.error("No MCP servers discovered from Claude Code config files.");
41
+ console.error("Run with --help for usage information.");
42
+ process.exit(1);
43
+ }
44
+ return { servers };
45
+ }
46
+ function printUsage() {
47
+ console.error(`
48
+ mcp-prompt-bridge - Expose MCP prompts as tools
49
+
50
+ Usage:
51
+ mcp-prompt-bridge Discover and bridge all MCP servers
52
+ mcp-prompt-bridge --exclude <name> Exclude specific servers
53
+
54
+ Options:
55
+ --exclude <name> Exclude a server by name (can be repeated)
56
+ --help, -h Show this help
57
+
58
+ Discovery Sources (in priority order):
59
+ 1. ~/.claude.json (user scope)
60
+ 2. ~/.claude/settings.local.json (user scope)
61
+ 3. ./.mcp.json (project scope)
62
+ 4. ./.claude/settings.local.json (project local scope)
63
+
64
+ If no config files found, falls back to parsing "claude mcp list" output.
65
+
66
+ Note: HTTP/remote servers are skipped (only stdio servers supported).
67
+ Note: "mcp-prompt-bridge" / "prompt-bridge" are auto-excluded to prevent loops.
68
+
69
+ Examples:
70
+ mcp-prompt-bridge
71
+ mcp-prompt-bridge --exclude slow-server --exclude broken-server
72
+ `);
73
+ }
74
+ // ─── On-demand upstream connection ──────────────────────────────────────────
75
+ /**
76
+ * Connect to an upstream server, run a callback, then disconnect.
77
+ */
78
+ async function withUpstream(serverConfig, fn, timeoutMs = 10000) {
79
+ const transport = new StdioClientTransport({
80
+ command: serverConfig.command,
81
+ args: serverConfig.args,
82
+ env: serverConfig.env
83
+ ? { ...process.env, ...serverConfig.env }
84
+ : undefined,
85
+ cwd: serverConfig.cwd,
86
+ stderr: "ignore",
87
+ });
88
+ const client = new Client({ name: "mcp-prompt-bridge", version: "1.0.0" }, { capabilities: {} });
89
+ await Promise.race([
90
+ client.connect(transport),
91
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Connection timed out after ${timeoutMs}ms`)), timeoutMs)),
92
+ ]);
93
+ try {
94
+ return await fn(client);
95
+ }
96
+ finally {
97
+ try {
98
+ await client.close();
99
+ }
100
+ catch {
101
+ // ignore
102
+ }
103
+ }
104
+ }
105
+ /**
106
+ * Discover prompts from a single server (connect → listPrompts → disconnect).
107
+ * Returns empty array if server doesn't support prompts.
108
+ */
109
+ async function discoverPrompts(serverConfig) {
110
+ return withUpstream(serverConfig, async (client) => {
111
+ try {
112
+ const result = await client.listPrompts();
113
+ return (result.prompts || []).map((p) => ({
114
+ name: p.name,
115
+ description: p.description,
116
+ arguments: p.arguments?.map((a) => ({
117
+ name: a.name,
118
+ description: a.description,
119
+ required: a.required,
120
+ })),
121
+ serverName: serverConfig.name,
122
+ }));
123
+ }
124
+ catch (err) {
125
+ const msg = err instanceof Error ? err.message : String(err);
126
+ if (msg.includes("Method not found") || msg.includes("-32601")) {
127
+ return [];
128
+ }
129
+ throw err;
130
+ }
131
+ });
132
+ }
133
+ // ─── Main ──────────────────────────────────────────────────────────────────────
134
+ async function main() {
135
+ const { servers } = parseArgs();
136
+ const serversByName = new Map();
137
+ for (const s of servers) {
138
+ serversByName.set(s.name, s);
139
+ }
140
+ console.error(`[bridge] Discovered ${servers.length} upstream server(s):`);
141
+ for (const s of servers) {
142
+ console.error(`[bridge] - ${s.name}: ${s.command} ${(s.args ?? []).join(" ")}`);
143
+ }
144
+ // Cache for discovered prompts (populated on first list(server) call)
145
+ const promptCache = new Map();
146
+ // Create the bridge MCP server
147
+ const server = new McpServer({
148
+ name: "mcp-prompt-bridge",
149
+ version: "1.0.0",
150
+ });
151
+ // ── Tool: list ──
152
+ server.registerTool("list", {
153
+ title: "List Prompts",
154
+ description: "Without arguments: list available MCP server names (no connection needed). " +
155
+ "With server argument: connect to that server, list its prompts, then disconnect. " +
156
+ "Use get() with server and prompt to fetch a specific prompt.",
157
+ inputSchema: {
158
+ server: z
159
+ .string()
160
+ .optional()
161
+ .describe("MCP server name. Omit to list server names only."),
162
+ },
163
+ annotations: {
164
+ readOnlyHint: true,
165
+ destructiveHint: false,
166
+ idempotentHint: true,
167
+ openWorldHint: false,
168
+ },
169
+ }, async (params) => {
170
+ // No server specified: return server names only (no connections)
171
+ if (!params.server) {
172
+ const names = Array.from(serversByName.keys());
173
+ return {
174
+ content: [
175
+ {
176
+ type: "text",
177
+ text: names.map((n) => `- ${n}`).join("\n"),
178
+ },
179
+ ],
180
+ };
181
+ }
182
+ // Server specified: connect and list its prompts
183
+ const serverConfig = serversByName.get(params.server);
184
+ if (!serverConfig) {
185
+ const available = Array.from(serversByName.keys()).join(", ");
186
+ return {
187
+ content: [
188
+ {
189
+ type: "text",
190
+ text: `Server "${params.server}" not found. Available: ${available}`,
191
+ },
192
+ ],
193
+ isError: true,
194
+ };
195
+ }
196
+ try {
197
+ let prompts = promptCache.get(params.server);
198
+ if (!prompts) {
199
+ prompts = await discoverPrompts(serverConfig);
200
+ promptCache.set(params.server, prompts);
201
+ }
202
+ if (prompts.length === 0) {
203
+ return {
204
+ content: [
205
+ {
206
+ type: "text",
207
+ text: `Server "${params.server}" has no prompts.`,
208
+ },
209
+ ],
210
+ };
211
+ }
212
+ const lines = [];
213
+ for (const p of prompts) {
214
+ lines.push(`- **${p.name}**${p.description ? `: ${p.description}` : ""}`);
215
+ if (p.arguments && p.arguments.length > 0) {
216
+ for (const a of p.arguments) {
217
+ const req = a.required ? "required" : "optional";
218
+ lines.push(` - \`${a.name}\` (${req})${a.description ? `: ${a.description}` : ""}`);
219
+ }
220
+ }
221
+ }
222
+ return {
223
+ content: [{ type: "text", text: lines.join("\n") }],
224
+ };
225
+ }
226
+ catch (err) {
227
+ const msg = err instanceof Error ? err.message : String(err);
228
+ return {
229
+ content: [
230
+ {
231
+ type: "text",
232
+ text: `Error connecting to "${params.server}": ${msg}`,
233
+ },
234
+ ],
235
+ isError: true,
236
+ };
237
+ }
238
+ });
239
+ // ── Tool: get ──
240
+ server.registerTool("get", {
241
+ title: "Get Prompt",
242
+ description: "Fetch a specific prompt from an upstream MCP server. " +
243
+ "Connects on demand, fetches the prompt, then disconnects. " +
244
+ "Use list() first to discover available server and prompt names.",
245
+ inputSchema: {
246
+ server: z.string().describe("MCP server name"),
247
+ prompt: z.string().describe("Prompt name"),
248
+ arguments: z
249
+ .record(z.string())
250
+ .optional()
251
+ .describe("Prompt arguments as key-value pairs"),
252
+ },
253
+ annotations: {
254
+ readOnlyHint: true,
255
+ destructiveHint: false,
256
+ idempotentHint: true,
257
+ openWorldHint: false,
258
+ },
259
+ }, async (params) => {
260
+ const serverConfig = serversByName.get(params.server);
261
+ if (!serverConfig) {
262
+ const available = Array.from(serversByName.keys()).join(", ");
263
+ return {
264
+ content: [
265
+ {
266
+ type: "text",
267
+ text: `Server "${params.server}" not found. Available: ${available}`,
268
+ },
269
+ ],
270
+ isError: true,
271
+ };
272
+ }
273
+ try {
274
+ return await withUpstream(serverConfig, async (client) => {
275
+ const result = await client.getPrompt({
276
+ name: params.prompt,
277
+ arguments: params.arguments ?? {},
278
+ });
279
+ const parts = [];
280
+ if (result.description) {
281
+ parts.push(`# ${result.description}\n`);
282
+ }
283
+ for (const msg of result.messages) {
284
+ const role = msg.role.toUpperCase();
285
+ if (msg.content.type === "text") {
286
+ parts.push(`[${role}]\n${msg.content.text}`);
287
+ }
288
+ else if (msg.content.type === "resource") {
289
+ const res = msg.content.resource;
290
+ if ("text" in res && typeof res.text === "string") {
291
+ parts.push(`[${role} - Resource: ${res.uri}]\n${res.text}`);
292
+ }
293
+ else {
294
+ parts.push(`[${role} - Resource: ${res.uri}] (binary content, ${res.mimeType ?? "unknown type"})`);
295
+ }
296
+ }
297
+ else {
298
+ parts.push(`[${role}]\n${JSON.stringify(msg.content)}`);
299
+ }
300
+ }
301
+ return {
302
+ content: [{ type: "text", text: parts.join("\n\n") }],
303
+ };
304
+ });
305
+ }
306
+ catch (err) {
307
+ const message = err instanceof Error ? err.message : String(err);
308
+ return {
309
+ content: [
310
+ {
311
+ type: "text",
312
+ text: `Error fetching prompt "${params.prompt}" from "${params.server}": ${message}`,
313
+ },
314
+ ],
315
+ isError: true,
316
+ };
317
+ }
318
+ });
319
+ // Start the bridge server over stdio
320
+ const transport = new StdioServerTransport();
321
+ await server.connect(transport);
322
+ console.error(`[bridge] mcp-prompt-bridge running (${servers.length} server(s) available)`);
323
+ // Graceful shutdown
324
+ const shutdown = async () => {
325
+ console.error("[bridge] Shutting down...");
326
+ await server.close();
327
+ process.exit(0);
328
+ };
329
+ process.on("SIGINT", shutdown);
330
+ process.on("SIGTERM", shutdown);
331
+ }
332
+ main().catch((err) => {
333
+ console.error("[bridge] Fatal error:", err);
334
+ process.exit(1);
335
+ });
336
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Configuration for an upstream MCP server to proxy prompts from.
3
+ */
4
+ export interface UpstreamServerConfig {
5
+ /** Display name for this server */
6
+ name: string;
7
+ /** Command to launch the MCP server */
8
+ command: string;
9
+ /** Arguments to pass to the command */
10
+ args?: string[];
11
+ /** Environment variables for the server process */
12
+ env?: Record<string, string>;
13
+ /** Working directory for the server process */
14
+ cwd?: string;
15
+ }
16
+ /**
17
+ * Top-level configuration for the proxy.
18
+ */
19
+ export interface ProxyConfig {
20
+ /** List of upstream MCP servers whose prompts will be exposed as tools */
21
+ servers: UpstreamServerConfig[];
22
+ }
23
+ /**
24
+ * Information about a prompt discovered from an upstream server.
25
+ */
26
+ export interface PromptInfo {
27
+ /** Original prompt name */
28
+ name: string;
29
+ /** Description of the prompt */
30
+ description?: string;
31
+ /** Arguments the prompt accepts */
32
+ arguments?: PromptArgument[];
33
+ /** Which server this prompt came from */
34
+ serverName: string;
35
+ }
36
+ export interface PromptArgument {
37
+ name: string;
38
+ description?: string;
39
+ required?: boolean;
40
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "mcp-prompt-bridge",
3
+ "version": "1.0.0",
4
+ "description": "MCP server that re-exposes upstream MCP prompts as tools",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "mcp-prompt-bridge": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "start": "node dist/index.js",
16
+ "dev": "tsc --watch"
17
+ },
18
+ "type": "module",
19
+ "dependencies": {
20
+ "@modelcontextprotocol/sdk": "^1.12.1",
21
+ "zod": "^3.24.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^22.0.0",
25
+ "tsx": "^4.21.0",
26
+ "typescript": "^5.7.0"
27
+ }
28
+ }