@felan-ai/ext-mcp
v0.3.2
Published
Portable OAuth-only MCP gateway for Felan
Readme
@felan-ai/ext-mcp
Portable OAuth-only remote MCP support for Felan. The package registers one
token-efficient mcp gateway for status, reconnection, discovery, calls,
authentication, and logout. It also registers /mcp for interactive status,
tool listing, reconnection, authentication, and logout. The command remains
available with an empty config so consumers can show setup guidance. The
package intentionally does not load ambient MCP files, launch browsers, or
store credentials.
The model-facing gateway exposes status, reconnect, list, search,
describe, call, authenticate, and logout. Its capability and tool
description identify the validated configured server names. Connections are
session-scoped and lazy: disconnected means there is no live transport in the
current session; it does not indicate whether the consumer's OAuth host has
credentials available or persists them. Discovery and call actions connect
automatically, while reconnect explicitly replaces a live connection or
connects a disconnected server:
mcp({ action: 'reconnect', server: 'docs' });If reconnecting reports needs-auth, use the model-facing authenticate
action. For other failures, retry once and then inspect the consumer-owned MCP
configuration and network policy rather than starting OAuth unnecessarily.
Interactive /mcp messages include bounded, sanitized diagnostics when the
SDK provides a structured OAuth, HTTP, timeout, or network error. Model-facing
errors expose only the safe category, provider error code, and HTTP status;
remote error text is not copied into model context.
Consumer-owned OAuth
Create the extension with an immutable server snapshot and an injected OAuth host:
import { createMcpExtension } from '@felan-ai/ext-mcp';
const extension = createMcpExtension({
config: {
mcpServers: {
notion: {
url: 'https://mcp.notion.com/mcp',
auth: 'oauth',
},
},
},
oauthHost,
});McpOAuthHost creates a session-scoped adapter that supplies an MCP SDK OAuth
provider and owns the complete OAuth implementation: client configuration,
token and dynamic-client persistence, PKCE/state, callbacks, browser or web-app
presentation, refresh behavior, and logout. An interactive local host can wait
for a loopback callback, while a cloud host can return a persistent pending
interaction completed by its web application.
pending messages and interaction IDs are returned through the tool and may be
persisted in session history. They must be non-secret: never place OAuth state,
authorization codes, PKCE material, tokens, or credential-bearing URLs in
either field.
Cloud hosts must also apply their tenant identity and outbound network policy
to MCP and OAuth configuration before constructing the extension. In
particular, protect OAuth discovery/registration/token requests from private
network access and DNS rebinding, persist flow state and PKCE material across
instances, and bind credentials to tenant, server URL, issuer, client, and
redirect URI. Pass a policy-enforcing fetch in createMcpExtension options so
transport-driven MCP and OAuth requests use the consumer's network boundary.
The extension accepts only explicit { url, auth: "oauth" } servers. It does
not support stdio, Unix sockets, bearer tokens, custom headers, embedded OAuth
secrets, direct MCP tools, resources/prompts, MCP Apps, scripting, sampling, or
ambient host config discovery.
All MCP metadata and tool output is bounded and returned inside an explicit untrusted-content boundary. OAuth credentials and provider state are never included in tool results or details.
Package boundary and requirements
The package owns configuration validation, the OAuth-only gateway, transport
lifecycle, bounded untrusted results, and the model-facing command. A consumer
must provide McpOAuthHost, credential persistence, callback/browser
presentation, and network policy. The package intentionally has no default
token store, callback listener, browser launcher, or ambient configuration
discovery.
It requires a compatible @felan-ai/agent-core peer, MCP SDK client, and
TypeBox. Only explicit remote HTTP servers with auth: 'oauth' are accepted;
stdio, sockets, bearer tokens, custom headers, direct tools/resources/prompts,
MCP Apps, and embedded OAuth secrets are rejected.
Development
Source: packages/ext-mcp in https://github.com/felan-ai/felan.
corepack enable
pnpm install --frozen-lockfile
pnpm --filter @felan-ai/ext-mcp build
pnpm --filter @felan-ai/ext-mcp type-check
pnpm --filter @felan-ai/ext-mcp testRelated documentation
Attribution
Selected gateway behavior is adapted from the reviewed MIT-licensed
pi-mcp-adapter releases. See NOTICE and LICENSE for
source commits and MCP SDK attribution.
