node-red-contrib-mcp-server

node-red-contrib-mcp-server

Exposes Node-RED flows as MCP tools for AI assistants, with OAuth protection and optional admin tools for flow management.

Category
访问服务器

README

@frtnbach/node-red-contrib-mcp-server

Generic Model Context Protocol (MCP) server nodes for Node-RED: expose any flow as an MCP tool behind an OAuth-protected endpoint, with optional Node-RED admin (flow read/deploy) tools. No home-automation or other domain coupling — this is a bare building block for turning Node-RED flows into MCP tools that AI assistants (Claude, etc.) can call.

Nodes

  • mcp-server (config node) — hosts a standalone MCP JSON-RPC endpoint at POST /mcp/<path>, OAuth 2.0 protected-resource discovery (RFC 9728), authorization-server discovery (RFC 8414) proxying a real OIDC identity provider, and a dynamic client registration shim, so OAuth-aware MCP clients (e.g. Claude.ai) can self-register and authenticate. Multiple mcp-server nodes can coexist, each with its own path and its own independent auth configuration.
  • mcp-in — defines one MCP tool (name, description, JSON-Schema parameters). When an MCP client calls the tool, the node emits a message carrying the call arguments; wire the rest of the flow to do the actual work.
  • mcp-out — resolves a pending tool call. Wire the end of your flow here with msg._mcpCallId intact (from the originating mcp-in message) and msg.payload set to the result.

A single mcp-in → ... → mcp-out chain is one MCP tool. Build as many chains as you want against the same mcp-server node to expose a whole toolset.

Admin tools

Enable Admin tools on an mcp-server node to additionally expose two tools that operate on Node-RED's own Admin HTTP API, gated by a configurable JWT claim (default: groups contains admin):

  • get_flow — lists all flow tabs (id, label, node count), or returns the full JSON of one tab when called with an id.
  • deploy_flow — creates or updates a flow tab.

Configuring an mcp-server node

  • General: name, path (→ registers POST /mcp/<path>), the public Server URL this Node-RED instance is reachable at, optional server name/instructions shown to the model, and an optional hostname filter (see below).
  • Auth: an OIDC Identity provider issuer URL (required — endpoints auto-discovered from /.well-known/openid-configuration, with PocketID-style fallback paths; leaving this empty produces a broken OAuth discovery document with relative-path endpoints and no working auth, so the editor won't let you deploy without it), client id/secret (leave the secret empty to run as a public/PKCE client — recommended), required redirect URIs (defaults to Claude.ai's callback), scopes, token audience, an optional local debug token that bypasses the IdP entirely for local testing (put any placeholder URL in Identity provider and rely on the debug token — it's never contacted when the debug token matches), and a whole-server required claim/value gate (see below, unrelated despite the similar name).
  • Admin: enable/disable admin tools, admin token (for the Node-RED Admin API), admin API port, and the required claim/value gate that additionally restricts just the admin tools.

Access control

Two independent, optional gates:

  • Whole-server gate (Auth tab, Required claim/Required value): when a value is set, the validated token's claim must contain it for any of this server's tools — including admin tools — to be usable. Callers who fail the check still connect (initialize succeeds) but see no tools and any tools/call is refused with a human-readable reason. Leave the value empty (the default) to allow all authenticated users.
  • Admin-only gate (Admin tab): the same shape, but only gates get_flow/deploy_flow — ordinary tools defined by mcp-in/mcp-out remain usable by anyone who passes the whole-server gate above.

Both denials are returned as an MCP tool result with isError: true and an explanatory message (not a raw JSON-RPC protocol error), so the reason reaches the calling model instead of being collapsed into a generic "tool execution failed".

Hostname filtering

Off by default. When Only serve requests for this hostname is enabled, the node only answers requests whose Host header matches the hostname in its Server URL. This lets several mcp-server nodes share the same path on one Node-RED instance, each answering only its own virtual host — useful behind a reverse proxy that fronts multiple hostnames for one Node-RED backend. Leave it off for a single server, or when a reverse proxy rewrites the Host header.

Reverse proxy

Each mcp-server node is its own OAuth resource — unlike a single shared MCP endpoint, every instance registers its own discovery and registration routes, scoped under its path. For a node with path: docker and Server URL: https://mcp.example.com, these six routes exist:

Method & path Purpose
POST /mcp/docker The JSON-RPC MCP endpoint (bearer-token protected)
GET /mcp/docker/.well-known/oauth-protected-resource Resource metadata (RFC 9728), path-inserted form
GET /.well-known/oauth-protected-resource/mcp/docker Resource metadata (RFC 9728), RFC 8414 form
GET /mcp/docker/.well-known/oauth-authorization-server Auth-server metadata (RFC 8414), path-inserted form
GET /.well-known/oauth-authorization-server/mcp/docker Auth-server metadata (RFC 8414), RFC 8414 form
POST /mcp/docker/oauth/register Dynamic client registration shim

Both well-known forms are advertised because different MCP clients probe different ones — expose both. Since every instance's routes share the /mcp/<path> and /.well-known/*/mcp/<path> shapes, one set of wildcard rules covers every current and future mcp-server node (as long as they're all reachable through the same domain/upstream) — no reverse-proxy change needed when adding a new path. Example, using Caddy via caddy-docker-proxy labels:

labels:
  caddy_1: mcp.example.com
  caddy_1.reverse_proxy_0: /mcp/* "{{upstreams 1880}}"
  caddy_1.reverse_proxy_1: /.well-known/oauth-protected-resource/mcp/* "{{upstreams 1880}}"
  caddy_1.reverse_proxy_2: /.well-known/oauth-authorization-server/mcp/* "{{upstreams 1880}}"

Node-RED itself 404s any path that isn't an actual registered route, so the wildcard doesn't expose anything beyond what each deployed mcp-server node already registers. If a path needs to be reachable on a different domain than the others, give it its own caddy_N site block (or combine with hostname filtering above).

What the identity provider needs to support (same requirements as lib/mcp-auth.js):

  • An OIDC provider with discovery — endpoints are read from ‹issuerUrl›/.well-known/openid-configuration, falling back to PocketID's path layout if discovery is unavailable.
  • JWT access tokens signed with a key published on the provider's JWKS (tokens are verified locally; opaque/introspection-only access tokens are not supported).
  • A client configured with the redirect URI(s) from the node's Redirect URIs setting, grant types authorization_code + refresh_token, PKCE (S256), and — if a client secret is set — client_secret_post auth. Leave the secret empty to run as a public/PKCE client (recommended).

Tested with Caddy (reverse proxy) + PocketID (identity provider) + Claude.ai (MCP client). Any spec-compliant OIDC provider issuing JWT access tokens, behind any reverse proxy that forwards the routes above, should work the same way.

Examples

See examples/ for nine ready-to-import flows (Jellyfin, Calibre, Docker, Music Assistant, Radarr, iRobot/rest980, Overseerr, Sonarr, Spotify), each with its own mcp-server node (server description pre-filled, Server URL/Identity provider left blank for you to fill in) and mcp-in/mcp-out tools — a good reference for wiring up your own tools.

Development

npm install
npm test

License

ISC

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选