docs/enterprise/mcp/extending.md
New in reflex-enterprise v0.9.4.
Beyond the built-in tools and reflex:// resources, you can register your own
tools, resources, and prompts on the underlying
FastMCP server. There are two ways in, and
both hand you the same instance.
configure=Pass MCPPlugin(configure=...) a callable (or a "module.function" import
path). It is invoked as configure(server) once the built-in tools and
resources are registered and before the server is mounted, so whatever you
add is serving from the first request:
import reflex_enterprise as rxe
def customize(server):
@server.tool()
def ping() -> str:
"""Health check."""
return "pong"
@server.resource("config://version")
def version() -> str:
"""The deployed app version."""
return "1.0.0"
config = rxe.Config(
app_name="my_app",
plugins=[rxe.MCPPlugin(configure=customize)],
)
A tool or resource that declares a Context-typed parameter has it injected by
FastMCP, giving you the active request and session — the same mechanism the
built-in tools use to resolve the caller's session from their bearer token.
get_mcp_server()To register from application code instead, grab the active server with
rxe.get_mcp_server(). The server is built when the app is compiled, so
this has to run after that — a
lifespan task is the natural home,
since it starts once the backend comes up:
from contextlib import asynccontextmanager
import reflex_enterprise as rxe
@asynccontextmanager
async def register_mcp_tools(app):
"""Add app-defined tools to the MCP server at startup."""
server = rxe.get_mcp_server()
@server.tool()
def ping() -> str:
"""Health check."""
return "pong"
yield
app = rxe.App()
app.register_lifespan_task(register_mcp_tools)
# `get_mcp_server()` raises a `RuntimeError` until the app has compiled.
That rules out calling it at module scope, including as a bare `@rxe.get_mcp_server().tool()` decorator — at import time there is no server yet. Register from a lifespan task as above, or use `configure=` for setup-time customization. The same applies to the equivalent `plugin.get_mcp_server()` instance method.
If you register tools after the transport is already serving, connected clients
pick them up on their next tools/list.