create-multicast 0.1.0 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +118 -0
  2. package/dist/cli.js +67 -24
  3. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # create-multicast
2
+
3
+ One command to set up [Multicast](https://github.com/mayankbohra/multicast) — an MCP gateway that gives Claude.ai access to all your MCP servers through a single integration, with parallel execution.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npx create-multicast
9
+ ```
10
+
11
+ ## What It Does
12
+
13
+ 1. **Scans your machine** for existing MCP configurations
14
+ - Claude Code (`~/.claude.json`)
15
+ - Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`)
16
+ - Cursor (`~/.cursor/mcp.json`)
17
+ - VS Code (`.vscode/mcp.json`)
18
+
19
+ 2. **Classifies your servers**
20
+ - HTTP servers (compatible with Multicast)
21
+ - stdio servers (local only, not compatible)
22
+
23
+ 3. **Lets you select** which servers to register
24
+
25
+ 4. **Auto-detects credentials** from existing configs
26
+ - Authorization headers
27
+ - API keys, tokens, secrets from env vars
28
+
29
+ 5. **Deploys to Cloudflare Workers**
30
+ - Creates D1 database for tool discovery cache
31
+ - Sets encrypted env vars for server credentials
32
+ - Deploys the Worker
33
+
34
+ 6. **Outputs the URL** to add to Claude.ai
35
+
36
+ ## Example
37
+
38
+ ```
39
+ $ npx create-multicast
40
+
41
+ create-multicast
42
+
43
+ MCP gateway for Claude.ai — one integration, all your servers, parallel execution.
44
+ Runs on Cloudflare Workers (free tier). Costs $0/month.
45
+
46
+ Scanning for existing MCP configurations...
47
+
48
+ Found 5 MCP servers:
49
+
50
+ ✓ context-hub https://context-hub.user.workers.dev [HTTP]
51
+ ✓ supabase-mcp https://supabase-mcp.example.com [HTTP]
52
+ ✗ filesystem command: npx @mcp/filesystem [stdio — skipped]
53
+ ✗ git command: npx @mcp/git [stdio — skipped]
54
+ ✓ github-mcp https://github-mcp.example.com [HTTP]
55
+
56
+ 2 stdio servers skipped — they run locally and can't be called from a cloud worker.
57
+
58
+ Select servers to register with Multicast:
59
+ ◼ context-hub
60
+ ◼ supabase-mcp
61
+ ◼ github-mcp
62
+
63
+ ...deploying...
64
+
65
+ Deployed! https://multicast.user.workers.dev/mcp
66
+
67
+ Add to Claude.ai:
68
+ → Settings → Integrations → Add MCP Server
69
+ → Paste the URL above
70
+ ```
71
+
72
+ ## What is Multicast?
73
+
74
+ Multicast is a free, open-source MCP gateway on Cloudflare Workers.
75
+
76
+ **The problem:** Claude.ai requires a separate integration for each MCP server. 5 servers = 5 integrations, 5 OAuth setups, and sequential tool execution.
77
+
78
+ **The solution:** Add Multicast once. It connects to all your MCP servers and calls them in parallel.
79
+
80
+ - One integration instead of many
81
+ - Parallel execution instead of sequential
82
+ - Unified tool discovery
83
+ - $0/month on Cloudflare Workers free tier
84
+
85
+ ## How Credentials Work
86
+
87
+ - You deploy your **own** Multicast instance on your Cloudflare account
88
+ - Server URLs and auth tokens are stored as **encrypted environment variables**
89
+ - Credentials never leave your infrastructure
90
+ - No shared servers, no central authority
91
+
92
+ ## Adding Servers After Setup
93
+
94
+ ```bash
95
+ # Add a new server
96
+ npx wrangler secret put MCP_SERVER_NEWSERVICE
97
+ npx wrangler secret put MCP_AUTH_NEWSERVICE # if auth needed
98
+ npx wrangler deploy
99
+ ```
100
+
101
+ ## Requirements
102
+
103
+ - Node.js 18+
104
+ - Free Cloudflare account
105
+ - At least one HTTP-accessible MCP server
106
+
107
+ ## stdio vs HTTP
108
+
109
+ Multicast runs in the cloud. It can only call MCP servers with HTTP endpoints. Local stdio servers (filesystem, git, sqlite) are detected but skipped with an explanation.
110
+
111
+ ## Links
112
+
113
+ - [GitHub](https://github.com/mayankbohra/multicast)
114
+ - [Cloudflare Workers](https://workers.cloudflare.com/)
115
+
116
+ ## License
117
+
118
+ MIT
package/dist/cli.js CHANGED
@@ -256,45 +256,88 @@ async function main() {
256
256
  process.exit(0);
257
257
  }
258
258
  const selectedNames = selections;
259
- // Confirm/collect auth for each selected server
259
+ // Auto-detect auth for each selected server
260
+ // Strategy:
261
+ // 1. If auth found in config → use it silently
262
+ // 2. If no auth → probe the server to check if it needs auth
263
+ // 3. Only ask the user if we can't determine automatically
264
+ const authSpinner = p.spinner();
265
+ authSpinner.start("Detecting authentication requirements...");
260
266
  for (const name of selectedNames) {
261
267
  const server = httpServers.find((s) => s.name === name);
262
268
  let auth = server.auth;
269
+ let authStatus;
263
270
  if (auth) {
264
- const useExisting = await p.confirm({
265
- message: `${name} found auth credentials. Use them?`,
266
- initialValue: true,
267
- });
268
- if (p.isCancel(useExisting)) {
269
- p.cancel("Setup cancelled.");
270
- process.exit(0);
271
- }
272
- if (!useExisting)
273
- auth = undefined;
271
+ // Auth found in existing config — use it
272
+ authStatus = "credentials found in config";
274
273
  }
275
- if (!auth) {
276
- const needsAuth = await p.confirm({
277
- message: `${name} — does this server require authentication?`,
278
- initialValue: false,
279
- });
280
- if (!p.isCancel(needsAuth) && needsAuth) {
281
- const authResult = await p.text({
282
- message: `Enter auth header for ${name}:`,
283
- placeholder: "Bearer your-token-here",
274
+ else {
275
+ // No auth in config — probe the server
276
+ try {
277
+ const probe = await fetch(server.url, {
278
+ method: "POST",
279
+ headers: { "Content-Type": "application/json" },
280
+ body: JSON.stringify({
281
+ jsonrpc: "2.0",
282
+ method: "initialize",
283
+ params: {
284
+ protocolVersion: "2024-11-05",
285
+ capabilities: {},
286
+ clientInfo: { name: "multicast-probe", version: "0.1.0" },
287
+ },
288
+ id: "probe",
289
+ }),
290
+ signal: AbortSignal.timeout(5000),
284
291
  });
285
- if (p.isCancel(authResult)) {
286
- p.cancel("Setup cancelled.");
287
- process.exit(0);
292
+ if (probe.status === 401 || probe.status === 403) {
293
+ // Server requires auth but we don't have it — need to ask
294
+ authStatus = "needs-auth";
295
+ }
296
+ else {
297
+ // Server responded without auth — no auth needed
298
+ authStatus = "no auth required";
288
299
  }
289
- auth = authResult;
300
+ }
301
+ catch {
302
+ // Can't reach server — assume no auth (will fail later with clear error)
303
+ authStatus = "unreachable (skipping auth)";
290
304
  }
291
305
  }
306
+ if (authStatus === "needs-auth") {
307
+ // Only ask when we KNOW the server needs auth but we don't have it
308
+ authSpinner.stop(`${pc.yellow("!")} ${name} requires authentication.`);
309
+ const authResult = await p.text({
310
+ message: `Enter auth header for ${pc.bold(name)}:`,
311
+ placeholder: "Bearer your-token-here",
312
+ validate: (v) => {
313
+ if (!v.trim())
314
+ return "Auth header is required — server returned 401";
315
+ return undefined;
316
+ },
317
+ });
318
+ if (p.isCancel(authResult)) {
319
+ p.cancel("Setup cancelled.");
320
+ process.exit(0);
321
+ }
322
+ auth = authResult;
323
+ authSpinner.start("Detecting authentication requirements...");
324
+ }
292
325
  selectedServers.push({
293
326
  name,
294
327
  url: server.url,
295
328
  auth: auth || undefined,
296
329
  });
297
330
  }
331
+ authSpinner.stop("Authentication configured.");
332
+ // Show auth summary
333
+ for (const s of selectedServers) {
334
+ if (s.auth) {
335
+ p.log.message(` ${pc.green("✓")} ${pc.bold(s.name)} — auth configured`);
336
+ }
337
+ else {
338
+ p.log.message(` ${pc.green("✓")} ${pc.bold(s.name)} — no auth needed`);
339
+ }
340
+ }
298
341
  }
299
342
  // Option to add servers manually
300
343
  let addMore = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-multicast",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Create a Multicast MCP gateway — one command to scaffold, configure, and deploy your parallel MCP server.",
5
5
  "type": "module",
6
6
  "bin": "./dist/cli.js",