[BUG] Cannot import library in browser environments #25

Closed
opened 2026-02-16 08:17:18 -05:00 by yindo · 2 comments
Owner

Originally created by @cephalization on GitHub (Apr 15, 2025).

Bug Description

Library is not importable in browser environments, despite the documentation claiming so.

Reproduction Steps

Steps to reproduce the behavior:

  1. Install the library in a browser-like package
  2. Get errors at bundle-time or runtime about node:stream import in client.ts

Expected Behavior

I should at least be able to import the contents of tools.ts in browser environments, as that does not depend on any node code. client.ts could also support browsers if it were refactored to support stdio via dependency injection or config, delaying import of node:stream until necessary.

I was able to successfully fork tools.ts without any changes, and connect to an sse transport per-tool, and then convert those tools and use them in the ReactAgent from a browser.

Possible Solution

Minimally, I propose adding an exports field to package.json, and allow users to directly import applicable files, treeshaking files with node dependencies out of the bundle.

Longer term, I think the multi-server Client would be very valuable in browser contexts if node libs were only used when stdio servers provided in the config.

Environment

  • OS: macOS
  • Node.js version: v23
  • Package version: 0.4.2
  • MCP SDK version: 1.9.0
Originally created by @cephalization on GitHub (Apr 15, 2025). ## Bug Description Library is not importable in browser environments, despite the documentation claiming so. ## Reproduction Steps Steps to reproduce the behavior: 1. Install the library in a browser-like package 2. Get errors at bundle-time or runtime about node:stream import in `client.ts` ## Expected Behavior I should at least be able to import the contents of `tools.ts` in browser environments, as that does not depend on any node code. `client.ts` could also support browsers if it were refactored to support stdio via dependency injection or config, delaying import of node:stream until necessary. I was able to successfully fork tools.ts without any changes, and connect to an sse transport per-tool, and then convert those tools and use them in the ReactAgent from a browser. ## Possible Solution Minimally, I propose adding an exports field to package.json, and allow users to directly import applicable files, treeshaking files with node dependencies out of the bundle. Longer term, I think the multi-server Client would be very valuable in browser contexts if node libs were only used when stdio servers provided in the config. ## Environment - OS: macOS - Node.js version: v23 - Package version: 0.4.2 - MCP SDK version: 1.9.0
yindo added the bug label 2026-02-16 08:17:18 -05:00
yindo closed this issue 2026-02-16 08:17:18 -05:00
Author
Owner

@cephalization commented on GitHub (Apr 15, 2025):

This abridged code executes in the browser just fine

import { loadMcpTools } from "./langchain/mcpTools"; // my fork of tools.ts
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
import { StructuredToolInterface } from "@langchain/core/tools";
// ...rest

    const disconnectCallbacks: (() => Promise<void>)[] = [];
    const mcpServers = await Promise.all(
      Object.entries(servers.servers).map(async ([name, server]) => {
        const transport = new SSEClientTransport(new URL(server.url));

        console.log("connecting to server", name, server.url);

        const mcpClient = new Client({
          name: `example`,
          version: "1.0.0",
        });

        await mcpClient.connect(transport);

        disconnectCallbacks.push(async () => {
          console.log("disconnecting from server", name);
          await mcpClient.close();
          await transport.close();
        });

        return (await loadMcpTools(
          name,
          mcpClient,
        )) as StructuredToolInterface[];
      }),
    );

    // Create the React agent
    const agent = createReactAgent({
      llm: client,
      tools: mcpServers.flat(),
    });

// ... rest

// eventually

    await Promise.all(disconnectCallbacks.map((cb) => cb()));
@cephalization commented on GitHub (Apr 15, 2025): This abridged code executes in the browser just fine ```ts import { loadMcpTools } from "./langchain/mcpTools"; // my fork of tools.ts import { createReactAgent } from "@langchain/langgraph/prebuilt"; import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js"; import { StructuredToolInterface } from "@langchain/core/tools"; // ...rest const disconnectCallbacks: (() => Promise<void>)[] = []; const mcpServers = await Promise.all( Object.entries(servers.servers).map(async ([name, server]) => { const transport = new SSEClientTransport(new URL(server.url)); console.log("connecting to server", name, server.url); const mcpClient = new Client({ name: `example`, version: "1.0.0", }); await mcpClient.connect(transport); disconnectCallbacks.push(async () => { console.log("disconnecting from server", name); await mcpClient.close(); await transport.close(); }); return (await loadMcpTools( name, mcpClient, )) as StructuredToolInterface[]; }), ); // Create the React agent const agent = createReactAgent({ llm: client, tools: mcpServers.flat(), }); // ... rest // eventually await Promise.all(disconnectCallbacks.map((cb) => cb())); ```
Author
Owner

@benjamincburns commented on GitHub (May 13, 2025):

@cephalization There are dozens of bundlers out there, each with dozens of versions, each with their own complex configuration options. If you need help troubleshooting this, you'll need to share a complete and executable minimal reproducible example for us to work off of.

I'll push a change that drops our usage of the node:stream package. If you're still having troubles after this please raise a new issue that includes an MRE.

@benjamincburns commented on GitHub (May 13, 2025): @cephalization There are dozens of bundlers out there, each with dozens of versions, each with their own complex configuration options. If you need help troubleshooting this, you'll need to share a complete and executable [minimal reproducible example](https://en.wikipedia.org/wiki/Minimal_reproducible_example) for us to work off of. I'll push a change that drops our usage of the `node:stream` package. If you're still having troubles after this please raise a new issue that includes an MRE.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langchainjs-mcp-adapters#25