@littlebigbrain/mcp 0.2.4 → 0.2.5

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 CHANGED
@@ -41,7 +41,7 @@ Run against any data-plane endpoint with a stack API key:
41
41
  "command": "npx",
42
42
  "args": ["-y", "@littlebigbrain/mcp"],
43
43
  "env": {
44
- "LBB_BASE_URL": "https://db.eu.littlebigbrain.com",
44
+ "LBB_BASE_URL": "https://0abc1def--production.db.eu.littlebigbrain.com",
45
45
  "LBB_API_KEY": "lbb_sk_live_..."
46
46
  }
47
47
  }
@@ -50,6 +50,9 @@ Run against any data-plane endpoint with a stack API key:
50
50
  ```
51
51
 
52
52
  Set `LBB_GRAPH` or `LBB_BRANCH` to target a scope other than `main`.
53
+ `LBB_BASE_URL` has no hosted default: copy `endpoint_url` from the stack's
54
+ Connect page. The MCP process exits with a configuration error when it is
55
+ missing.
53
56
 
54
57
  ## Tools
55
58
 
@@ -77,7 +80,7 @@ For self-hosting behind your own auth, the package also serves the tools over HT
77
80
  import { createMcpHttpServer } from "@littlebigbrain/mcp";
78
81
 
79
82
  createMcpHttpServer({
80
- baseUrl: "https://db.eu.littlebigbrain.com",
83
+ baseUrl: "https://0abc1def--production.db.eu.littlebigbrain.com",
81
84
  mcpPath: "/mcp",
82
85
  allowedHosts: ["127.0.0.1", "localhost", "::1"],
83
86
  }).listen(8080, "127.0.0.1");
@@ -1,7 +1,8 @@
1
1
  import { type IncomingMessage, type Server } from "node:http";
2
2
  import { LbbClient } from "@littlebigbrain/client";
3
3
  export interface McpHttpServerOptions {
4
- baseUrl?: string;
4
+ /** Required Little Big Brain stack endpoint (`endpoint_url` from Connect). */
5
+ baseUrl: string;
5
6
  mcpPath?: string;
6
7
  maxBodyBytes?: number;
7
8
  requestTimeoutMs?: number;
@@ -30,4 +31,4 @@ export declare function readJsonBody(req: IncomingMessage, maxBodyBytes?: number
30
31
  * Build the key-bearer streamable-HTTP MCP edge without starting a listener.
31
32
  * The hosted multi-tenant OAuth endpoint remains in the SaaS API.
32
33
  */
33
- export declare function createMcpHttpServer(options?: McpHttpServerOptions): Server;
34
+ export declare function createMcpHttpServer(options: McpHttpServerOptions): Server;
@@ -96,13 +96,16 @@ export function readJsonBody(req, maxBodyBytes = DEFAULT_MAX_BODY_BYTES) {
96
96
  * Build the key-bearer streamable-HTTP MCP edge without starting a listener.
97
97
  * The hosted multi-tenant OAuth endpoint remains in the SaaS API.
98
98
  */
99
- export function createMcpHttpServer(options = {}) {
100
- const baseUrl = options.baseUrl ?? "https://db.eu.littlebigbrain.com";
99
+ export function createMcpHttpServer(options) {
100
+ const baseUrl = options.baseUrl.trim();
101
101
  const mcpPath = options.mcpPath ?? "/mcp";
102
102
  const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
103
103
  const requestTimeoutMs = options.requestTimeoutMs ?? 30_000;
104
104
  const allowedHosts = options.allowedHosts;
105
105
  const allowedOrigins = options.allowedOrigins ?? [];
106
+ if (!baseUrl) {
107
+ throw new Error("baseUrl is required; copy endpoint_url from the stack's Connect page");
108
+ }
106
109
  if (!mcpPath.startsWith("/"))
107
110
  throw new Error("mcpPath must start with /");
108
111
  if (!Number.isInteger(maxBodyBytes) || maxBodyBytes <= 0) {
package/dist/http.js CHANGED
@@ -20,8 +20,12 @@ function csv(value) {
20
20
  return items && items.length > 0 ? items : undefined;
21
21
  }
22
22
  const mcpPath = process.env.LBB_MCP_PATH ?? "/mcp";
23
+ const baseUrl = process.env.LBB_BASE_URL?.trim();
24
+ if (!baseUrl) {
25
+ throw new Error("LBB_BASE_URL is required. Copy endpoint_url from your stack's Connect page, for example https://<tenant-short-id>--<stack-slug>.db.eu.littlebigbrain.com");
26
+ }
23
27
  const httpServer = createMcpHttpServer({
24
- baseUrl: process.env.LBB_BASE_URL ?? "https://db.eu.littlebigbrain.com",
28
+ baseUrl,
25
29
  mcpPath,
26
30
  allowedHosts: csv(process.env.LBB_MCP_ALLOWED_HOSTS) ??
27
31
  (isLoopback ? LOOPBACK_HOSTS : undefined),
package/dist/stdio.js CHANGED
@@ -1,27 +1,75 @@
1
1
  #!/usr/bin/env node
2
+ import { realpathSync } from "node:fs";
3
+ import { pathToFileURL } from "node:url";
2
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
5
  import { LbbClient } from "@littlebigbrain/client";
4
6
  import { buildLbbServer } from "./server.js";
7
+ const BASE_URL_HELP = "LBB_BASE_URL is required. Copy endpoint_url from your Little Big Brain stack's Connect page.";
5
8
  /**
6
9
  * Local stdio entrypoint (`npx @littlebigbrain/mcp`). Reads the connection from the
7
10
  * environment and serves the little big brain tools over stdio, the transport every
8
11
  * editor (Claude Code, Cursor, Codex) supports.
9
12
  *
10
- * LBB_BASE_URL (default http://127.0.0.1:7400)
13
+ * LBB_BASE_URL (required for tool calls; copy endpoint_url from the stack Connect page)
11
14
  * LBB_API_KEY stack API key (lbb_sk_live_…) or single-mode token
12
15
  * LBB_GRAPH / LBB_BRANCH (optional; server defaults to main/main)
16
+ *
17
+ * The base URL is required lazily, at the first tool invocation, not at
18
+ * process start: MCP hosts launch servers to complete the initialize
19
+ * handshake and list tools before the user has finished configuring them,
20
+ * and a startup crash surfaces as an opaque "server failed to start" in
21
+ * every editor. An unconfigured server therefore boots, handshakes, and
22
+ * lists tools normally — and every tool call fails with the actionable
23
+ * message above until LBB_BASE_URL is set. (There is deliberately no
24
+ * localhost default: pointing production tool calls at 127.0.0.1 silently
25
+ * was worse than failing loudly.)
13
26
  */
14
- async function main() {
15
- const client = new LbbClient({
16
- baseUrl: process.env.LBB_BASE_URL ?? "http://127.0.0.1:7400",
17
- apiKey: process.env.LBB_API_KEY,
18
- graph: process.env.LBB_GRAPH,
19
- branch: process.env.LBB_BRANCH,
27
+ export function unconfiguredClient() {
28
+ return new Proxy({}, {
29
+ get(_target, property) {
30
+ // Allow the runtime's duck-typing probes without exploding.
31
+ if (property === "then" || typeof property === "symbol")
32
+ return undefined;
33
+ throw new Error(BASE_URL_HELP);
34
+ },
20
35
  });
36
+ }
37
+ async function main() {
38
+ const baseUrl = process.env.LBB_BASE_URL?.trim();
39
+ if (!baseUrl) {
40
+ console.error(`warning: ${BASE_URL_HELP} Tool calls will fail until it is set.`);
41
+ }
42
+ const client = baseUrl
43
+ ? new LbbClient({
44
+ baseUrl,
45
+ apiKey: process.env.LBB_API_KEY,
46
+ graph: process.env.LBB_GRAPH,
47
+ branch: process.env.LBB_BRANCH,
48
+ })
49
+ : unconfiguredClient();
21
50
  const server = buildLbbServer(client);
22
51
  await server.connect(new StdioServerTransport());
23
52
  }
24
- main().catch((error) => {
25
- console.error(error);
26
- process.exit(1);
27
- });
53
+ // Only start the server when executed as the bin entrypoint — importing this
54
+ // module (e.g. the unconfiguredClient unit tests) must not attach a stdio
55
+ // transport to the host process, which would hold its stdin open forever.
56
+ // npm installs bins as symlinks, so argv[1] must be realpath'd before
57
+ // comparing against import.meta.url (which is always the resolved file).
58
+ function entrypointHref() {
59
+ const argv1 = process.argv[1];
60
+ if (argv1 === undefined)
61
+ return undefined;
62
+ try {
63
+ return pathToFileURL(realpathSync(argv1)).href;
64
+ }
65
+ catch {
66
+ return pathToFileURL(argv1).href;
67
+ }
68
+ }
69
+ const invokedAsBin = import.meta.url === entrypointHref();
70
+ if (invokedAsBin) {
71
+ main().catch((error) => {
72
+ console.error(error);
73
+ process.exit(1);
74
+ });
75
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@littlebigbrain/mcp",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "MCP server for little big brain — graph and hybrid search tools for agents",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {