Fentaris/fentaris

Fentaris is a centralized MCP proxy that unifies multiple MCP servers behind a single controlled endpoint, with stable routing, policies, identity, middleware, and rate limiting.

TypeScript

4

615 commits

updated Sep 19, 2026

See the code
framework
mcp
proxy

See what people are saying (1)

README


Table of contents

About

Fentaris is a control plane for your MCP servers — one place to run, route, and manage every MCP server behind a single, stable endpoint.

  • Unify stdio, Streamable HTTP, SSE, and HTTP upstream MCP servers behind one proxy.
  • Manage which servers and tools are exposed, to whom, and how they behave — without touching client configs.
  • Observe every proxied operation with structured logging, lifecycle events, and per-request context.
  • Protect tool calls, resources, prompts, and completions with policy, identity, middleware, hooks, and rate limits.
  • Authenticate clients and upstream MCP servers with API keys, bearer tokens, custom headers, and OAuth 2.1.

Fentaris is designed for teams that want MCP servers to behave like production infrastructure: stable names, centralized management, auditable calls, and predictable client-facing endpoints.

Documentation

Visit our docs or jump to a quickstart

Skills for Coding Agents

Using Claude Code, Codex, Cursor or other AI coding agents?

Install the Fentaris skill for coding agents

For a complete runnable project with API-key users, groups, allow-list policy, a remote MCP upstream, and app-owned local tools, see examples/team-governed-proxy.

Getting Started

Use the CLI to start a new Fentaris proxy project:

npm install -g @fentaris/cli
fentaris init my-proxy
cd my-proxy
fentaris dev

The generated proxy listens on http://localhost:4000/mcp by default. Point your MCP client to that endpoint.

Under the hood, a Fentaris proxy is just a few lines of code:

import {
  approval,
  fentaris,
  oauth,
  policy,
  stdio,
  streamableHttp,
  user,
} from "@fentaris/core";

const app = fentaris();

app.mcp("filesystem", {
  transport: stdio({
    command: "npx",
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
  }),
});

await app.start();

Upstream tool names stay stable and namespaced by server, no matter how many servers you add. A filesystem tool is exposed to clients with a proxy name such as:

filesystem__list_directory

→ Full documentation

Examples

Add another server behind the same endpoint:

app.mcp("github", {
  transport: stdio({ command: "npx", args: ["-y", "@modelcontextprotocol/server-github"] }),
});

Restrict who can call what:

app.policy("read-only")
  .mcp("filesystem")
  .allow("list_directory");

app.group("operators")
  .users(user("alice", { email: "alice@example.com" }))
  .policy("read-only");

Require approval before a risky action runs:

const deploy = policy("deploy")
  .mcp("github")
  .allow("deploy_production", approval.manual({
    reason: "Production deploy requires approval",
  }));

Observe every tool call:

app.on("tool:success", ({ ctx, durationMs }) => {
  ctx.log.info("tool.success", { tool: ctx.tool?.name, durationMs });
});

Runtime routes can deny, approve, hide, log, or transform calls to any tool, resource, prompt, or completion.

Authenticate clients with an API key, and let Fentaris handle OAuth 2.1 for upstream servers automatically:

fentaris auth api-key add alice --generate
app.mcp("linear", {
  transport: streamableHttp({ url: "https://mcp.linear.app/mcp" }),
  auth: oauth(),
});

Credential values are never exposed to middleware, hooks, logs, or policy callbacks.

Packages

PackageDescription
@fentaris/coreProxy runtime, MCP server wrapper, transports, policy, auth, logging, and middleware APIs.
@fentaris/cliProject generator and local development commands.
@fentaris/approval-telegramTelegram approval adapter for Fentaris policies.

Development

Run the project for development:

fentaris dev

From a clean clone, install the locked dependency graph and run the same validation used by CI:

pnpm install --frozen-lockfile
pnpm verify

pnpm verify runs lint, typecheck, build, and every package test in that order.

Before promoting a release, verify the exact npm tarballs in clean projects:

pnpm verify:release

This packs Core, CLI, Edge, and Telegram approval, validates their manifests and entrypoints, installs them in an empty project, generates and builds a real CLI project, and exercises upgrade, downgrade, reinstall, and re-upgrade from the previous published package set. It requires access to the npm registry.

Generate docs reference:

pnpm docs:generate

License

MIT, as declared by the published Fentaris packages.

Contributors

Gabry848

528 commits

cursoragent

49 commits

cursor[bot]

5 commits

Fentaris/fentaris

Fentaris is a centralized MCP proxy that unifies multiple MCP servers behind a single controlled endpoint, with stable routing, policies, identity, middleware, and rate limiting.

TypeScript

4

615 commits

updated Sep 19, 2026

See the code
framework
mcp
proxy

See what people are saying (1)

README


Table of contents

About

Fentaris is a control plane for your MCP servers — one place to run, route, and manage every MCP server behind a single, stable endpoint.

  • Unify stdio, Streamable HTTP, SSE, and HTTP upstream MCP servers behind one proxy.
  • Manage which servers and tools are exposed, to whom, and how they behave — without touching client configs.
  • Observe every proxied operation with structured logging, lifecycle events, and per-request context.
  • Protect tool calls, resources, prompts, and completions with policy, identity, middleware, hooks, and rate limits.
  • Authenticate clients and upstream MCP servers with API keys, bearer tokens, custom headers, and OAuth 2.1.

Fentaris is designed for teams that want MCP servers to behave like production infrastructure: stable names, centralized management, auditable calls, and predictable client-facing endpoints.

Documentation

Visit our docs or jump to a quickstart

Skills for Coding Agents

Using Claude Code, Codex, Cursor or other AI coding agents?

Install the Fentaris skill for coding agents

For a complete runnable project with API-key users, groups, allow-list policy, a remote MCP upstream, and app-owned local tools, see examples/team-governed-proxy.

Getting Started

Use the CLI to start a new Fentaris proxy project:

npm install -g @fentaris/cli
fentaris init my-proxy
cd my-proxy
fentaris dev

The generated proxy listens on http://localhost:4000/mcp by default. Point your MCP client to that endpoint.

Under the hood, a Fentaris proxy is just a few lines of code:

import {
  approval,
  fentaris,
  oauth,
  policy,
  stdio,
  streamableHttp,
  user,
} from "@fentaris/core";

const app = fentaris();

app.mcp("filesystem", {
  transport: stdio({
    command: "npx",
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
  }),
});

await app.start();

Upstream tool names stay stable and namespaced by server, no matter how many servers you add. A filesystem tool is exposed to clients with a proxy name such as:

filesystem__list_directory

→ Full documentation

Examples

Add another server behind the same endpoint:

app.mcp("github", {
  transport: stdio({ command: "npx", args: ["-y", "@modelcontextprotocol/server-github"] }),
});

Restrict who can call what:

app.policy("read-only")
  .mcp("filesystem")
  .allow("list_directory");

app.group("operators")
  .users(user("alice", { email: "alice@example.com" }))
  .policy("read-only");

Require approval before a risky action runs:

const deploy = policy("deploy")
  .mcp("github")
  .allow("deploy_production", approval.manual({
    reason: "Production deploy requires approval",
  }));

Observe every tool call:

app.on("tool:success", ({ ctx, durationMs }) => {
  ctx.log.info("tool.success", { tool: ctx.tool?.name, durationMs });
});

Runtime routes can deny, approve, hide, log, or transform calls to any tool, resource, prompt, or completion.

Authenticate clients with an API key, and let Fentaris handle OAuth 2.1 for upstream servers automatically:

fentaris auth api-key add alice --generate
app.mcp("linear", {
  transport: streamableHttp({ url: "https://mcp.linear.app/mcp" }),
  auth: oauth(),
});

Credential values are never exposed to middleware, hooks, logs, or policy callbacks.

Packages

PackageDescription
@fentaris/coreProxy runtime, MCP server wrapper, transports, policy, auth, logging, and middleware APIs.
@fentaris/cliProject generator and local development commands.
@fentaris/approval-telegramTelegram approval adapter for Fentaris policies.

Development

Run the project for development:

fentaris dev

From a clean clone, install the locked dependency graph and run the same validation used by CI:

pnpm install --frozen-lockfile
pnpm verify

pnpm verify runs lint, typecheck, build, and every package test in that order.

Before promoting a release, verify the exact npm tarballs in clean projects:

pnpm verify:release

This packs Core, CLI, Edge, and Telegram approval, validates their manifests and entrypoints, installs them in an empty project, generates and builds a real CLI project, and exercises upgrade, downgrade, reinstall, and re-upgrade from the previous published package set. It requires access to the npm registry.

Generate docs reference:

pnpm docs:generate

License

MIT, as declared by the published Fentaris packages.

Contributors

Gabry848

528 commits

cursoragent

49 commits

cursor[bot]

5 commits

Languages

TypeScript

96.1%

JavaScript

3.7%