New in reflex-enterprise v0.9.4.
Custom MCP Resources
queue_event drives your event handlers — the actions. For the read side,
decorate a state method with rxe.mcp.resource to publish it as a var-like,
read-only MCP resource: a computed value that can take arguments and is tied
to the caller's session state.
import reflex as rx
import reflex_enterprise as rxe
def admins_only(ctx) -> bool:
return ctx.auth_user_state.userinfo.get("role") == "admin"
class DashboardState(rx.State):
orders: list[dict] = []
@rxe.mcp.resource
def order_count(self) -> int:
"""How many orders the current user has."""
return len(self.orders)
@rxe.mcp.resource(auth=admins_only)
def revenue(self, quarter: str) -> dict:
"""Revenue for a quarter (admins only)."""
return {"quarter": quarter, "total": self._revenue_for(quarter)}The method runs against the caller's live session state and its return value is
the resource content. It is registered as a top-level resource — never an
event handler — so it does not appear in search_events or queue_event.
URIs
Each parameter becomes a URI-template variable (a required path segment), so the resources above are addressed as:
state-resource://<state>/order_count
state-resource://<state>/revenue/{quarter}<state> is the state's name as search_events reports it — the
module-prefixed name with the root State prefix stripped, and dots replaced by
slashes for nested substates. For a DashboardState defined in
my_app/my_app.py that is:
state-resource://my_app___my_app____dashboard_state/order_countResources are advertised in the server
instructions and through the
standard resources/templates/list, so a client discovers the exact URIs
without you writing them down.
Options
auth= takes the same values as ,
and its ctx carries ctx.auth_user_state (the user) plus
/ .
It is enforced whenever an AuthPlugin provides identity. An anonymous session
has no user, so only auth=False resources are readable with one.
Rules
- Decorate a plain method.
def name(self, ...)— not anrx.eventhandler and not anrx.var. Anything else raises aTypeErrorat import time. The decorated method stays callable asself.method(...)from your own code. - Async is fine. An
async defresource method is awaited. - Annotate the parameters. Their annotations become the resource's input
schema (an unannotated parameter is treated as
str). - Read-only by contract, like a computed var. Drive state changes through
queue_event. rxe_request_contextis a reserved parameter name — the wrapper appends a parameter of that name to receive the MCP request context.
Related
- Auto MCP: the built-in
reflex://resources for reading state and enumerating handlers. - Extending the server: register arbitrary
FastMCPtools, resources, and prompts. - Authentication: identity, scopes, and surface-aware checks.