Skip to main content
Connect upstream MCP servers with high-level transport helpers
This page is kept for older links. The current concepts entrypoint is Servers and transports.

Quick Start

Use stdio(...) for local upstream MCP servers:
import { fentaris, mcp, stdio } from "@fentaris/core";

const proxy = fentaris({
  servers: [
    mcp("filesystem", {
      transport: stdio({
        command: "npx",
        args: ["-y", "@modelcontextprotocol/server-filesystem", "./demo-files"],
        stderr: "inherit",
      }),
    }),
  ],
});
Use streamableHttp(...) for native remote MCP HTTP endpoints:
import { fentaris, mcp, streamableHttp } from "@fentaris/core";

const proxy = fentaris({
  servers: [
    mcp("remote", {
      transport: streamableHttp({
        url: "https://mcp.example.com/mcp",
        auth: {
          headers: { "x-tenant": "acme" },
          bearerToken: "service-token",
        },
      }),
    }),
  ],
});

Transport Matrix

DirectionHelperUse case
Upstreamstdio(...)Local MCP process over stdin/stdout.
UpstreamstreamableHttp(...)Remote native MCP Streamable HTTP endpoint.
UpstreamSseMcpTransportLegacy SSE-capable MCP servers.
UpstreamHttpTransportCompatibility adapter for REST-like /listTools and /callTool endpoints.
Downstreamproxy.start()Default Streamable HTTP exposure for MCP clients.

Stdio Options

command

Executable to spawn.

args

Arguments passed to the upstream process.

env

Environment variables passed to the upstream process.

stderr

How to handle stderr from the upstream process. Use inherit during local development to see upstream logs.

HTTP-Family Auth

streamableHttp(...) supports static headers, bearer tokens, API keys, and per-user header resolvers.
streamableHttp({
  url: "https://mcp.example.com/mcp",
  auth: {
    resolveHeaders: ({ user }) => ({
      "x-user-id": user.id ?? "anonymous",
      authorization: `Bearer ${user.tokens?.remote ?? ""}`,
    }),
  },
})
Fentaris does not acquire or refresh OAuth tokens. Pass an already-valid access token through a resolver when the upstream needs one.

Close Cleanly

Close the proxy on shutdown so upstream transports can release processes, sockets, and sessions.
process.on("SIGTERM", async () => {
  await proxy.close();
  process.exit(0);
});

Low-Level API

Transport classes such as StdioTransport, StreamableHttpMcpTransport, SseMcpTransport, and exposure transports remain available for advanced integrations. New application docs should prefer stdio(...), streamableHttp(...), and proxy.start().