Expose your app to Claude Desktop via MCP
@happyvertical/smrt-app-mcp turns your running SMRT app's objects into Model Context
Protocol tools, served over HTTP from your own routes. A small stdio bridge then connects Claude Desktop
to that HTTP surface. This guide wires both ends.
How it fits together
Claude Desktop ββstdioβββΊ smrt-mcp-bridge ββHTTPβββΊ your app
ββ GET /api/mcp/tools
ββ POST /api/mcp/call
β
βΌ
@smrt() objects β MCP toolsWhy a bridge? Claude Desktop launches MCP servers as local processes that talk over stdio. Your app speaks HTTP. The bridge is a thin stdio-to-HTTP adapter that also attaches your auth token.
Step 1 β Make objects MCP-callable
Only objects you opt in are exposed. Set mcp: true on the @smrt() decorator (the same flag that powers the generated MCP tools).
// src/lib/models/Application.ts
import { smrt, SmrtObject } from '@happyvertical/smrt-core';
@smrt({ mcp: true })
export class Application extends SmrtObject {
applicantName: string = '';
status: string = 'submitted';
approvedByUserId: string = '';
}Step 2 β Build the MCP server
createMcpAppServer() returns { listTools, callTool } wired
to your objects. You decide which classes are reachable (allowedClassNames),
which tools are public, and any per-tool guards (workflowAssertions).
// src/lib/server/mcp.ts
import { createMcpAppServer, McpAccessError } from '@happyvertical/smrt-app-mcp';
export const mcpServer = createMcpAppServer({
// Thunk returning the SMRT options (db, ai, β¦) for each call.
smrtOptions: () => ({ db: { type: 'postgres', url: process.env.DATABASE_URL! } }),
serverInfo: { name: 'my-app', version: '0.1.0' },
// Allow-list: only these classes' tools are reachable.
allowedClassNames: ['Application'],
// Tools matching these patterns are callable without auth (optional).
publicToolPatterns: () => ['application_list'],
// Per-tool guards run before a mutating tool executes.
workflowAssertions: {
application_update: (args, user) => {
if (!user?.id) throw new McpAccessError(401, 'sign in first');
args.approvedByUserId = user.id; // stamp the actor
}
}
});Step 3 β Mount the routes
The ./sveltekit subpath provides handlers for the two endpoints the bridge calls.
// src/routes/api/mcp/tools/+server.ts
import { mountMcpToolsRoute } from '@happyvertical/smrt-app-mcp/sveltekit';
import { mcpServer } from '$lib/server/mcp';
export const GET = mountMcpToolsRoute(mcpServer);// src/routes/api/mcp/call/+server.ts
import { mountMcpCallRoute } from '@happyvertical/smrt-app-mcp/sveltekit';
import { mcpServer } from '$lib/server/mcp';
export const POST = mountMcpCallRoute(mcpServer);That is the whole server side. Run your app and the MCP surface is live at /api/mcp/tools and /api/mcp/call.
Step 4 β Install and authenticate the bridge
The client side uses @happyvertical/smrt-app-cli, which ships a generic smrt-mcp-bridge bin. It resolves the app URL and bearer token from environment
variables prefixed by --env-prefix. Pick a prefix for your app (here: MYAPP) β it reads MYAPP_SERVER_URL and MYAPP_TOKEN.
pnpm add -g @happyvertical/smrt-app-cliIf your app requires auth, get a token through the device-code login flow shipped by smrt-users (this stores the token in ~/.config/<app>):
# Either log in interactively (stores a token for the bridge to read) β¦
MYAPP_SERVER_URL=https://my-app.example.com smrt-app-cli auth login
# β¦ or export the token directly for the bridge
export MYAPP_TOKEN=your-bearer-tokenStep 5 β Register with Claude Desktop
Add the bridge to Claude Desktop's config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"my-app": {
"command": "smrt-mcp-bridge",
"args": ["--env-prefix=MYAPP", "--name=my-app", "--version=0.1.0"],
"env": {
"MYAPP_SERVER_URL": "https://my-app.example.com",
"MYAPP_TOKEN": "your-bearer-token"
}
}
}
}Restart Claude Desktop. Your app's allow-listed objects now appear as tools (for example application_list, application_get, application_update),
and Claude can call them in conversation.
Defaults and overrides
| Setting | Source | Default |
|---|---|---|
| App URL | ${PREFIX}_SERVER_URL β config file β --default-server-url | local dev URL |
| Auth token | ${PREFIX}_TOKEN β stored config | none (header omitted) |
| Tools endpoint | toolsPath option | /api/mcp/tools |
| Call endpoint | callPath option | /api/mcp/call |
Related
- @happyvertical/smrt-app-mcp β the server-side module reference.
- Objects β Auto-Generated Interfaces β where MCP tools come from.
- Getting Started β set up the app the tools live in.
Verified against SMRT v0.29.34.