Backend API Tool Integration
The backend auto-generates MCP tools from its Elysia admin API routes and exposes them via the built-in MCP endpoint at /mcp.
Overview
All admin API routes (under /admin/*) are automatically discovered at startup and converted into MCP tool definitions. External MCP clients (VS Code, Claude Desktop, etc.) can call these tools after authenticating via OAuth 2.0.
Architecture
┌─────────────────┐
│ MCP Clients │ (VS Code, Claude Desktop, etc.)
└────────┬────────┘
│ Streamable HTTP
▼
┌─────────────────────────────────────┐
│ Proxy Smart Backend (Elysia/Bun) │
│ │
│ /mcp endpoint │
│ ├─ tools/list → auto-generated │
│ ├─ tools/call → route dispatch │
│ └─ OAuth 2.0 token validation │
└─────────────────────────────────────┘Auto-Generated Tools
At startup the backend introspects its registered Elysia routes and derives a tool definition from each one: a name from the HTTP method and path, an input schema merged from the route's body, params and query validation, and behavioural annotations from the method. Only routes under the configured prefix (/admin/) are considered, so a route is never exposed merely by existing.
Names are generated by pathToToolName, which prefixes the flattened path with a verb: GET becomes get, POST becomes create, PUT and PATCH become update, DELETE becomes delete. Slashes become underscores, : is dropped from parameters, and hyphens in a path segment are kept.
| Route | Tool |
|---|---|
GET /admin/healthcare-users | get_admin_healthcare-users |
GET /admin/healthcare-users/:userId | get_admin_healthcare-users_userId |
POST /admin/healthcare-users | create_admin_healthcare-users |
PUT /admin/smart-apps/:clientId | update_admin_smart-apps_clientId |
DELETE /admin/roles/:roleName | delete_admin_roles_roleName |
The generation rules live in @proxy-smart/elysia-mcp, which also documents resource naming and the MCP annotations derived from each method.
Regenerating Tools
When backend API routes change, tools are regenerated automatically on next startup. To export the OpenAPI spec:
cd backend && bun run export-openapiThe generated spec can also be used by bun run generate:ui to regenerate the frontend API client.
Security
Every call carries an OAuth 2.0 access token, validated against Keycloak for signature, expiry, and audience. Audience is fail-closed: the token must be bound to the MCP endpoint resource (RFC 8707) or to one of the proxy's own admin clients, so a SMART app token aimed at the FHIR base is rejected.
Which tools a caller sees is decided at registration time, per request, from that token. A route not marked meta.public is registered only for callers holding the admin realm role, so a non-admin does not merely fail the call — the tool is absent from tools/list. On top of that, the admin-configured allowlist or blocklist filters the set further.
Toggling a tool
PUT /admin/mcp-endpoint/tools/:toolName with { "exposed": false } hides a single tool. It writes to whichever list is active: enabledTools when the endpoint is in allowlist mode, disabledTools otherwise. Three tools ignore this and stay exposed, so the endpoint that would let you undo the change is always reachable: get_admin_mcp-endpoint, update_admin_mcp-endpoint, update_admin_mcp-endpoint_tools_toolName.
Client Configuration
See MCP HTTP Server for transport details, OAuth discovery, and client setup (VS Code, Claude Desktop, etc.).