MCP support

Your project includes a Model Context Protocol (MCP) server that allows AI clients like Claude Code and Claude Desktop to interact with your application data. Authentication uses OAuth2 via Better Auth.

How it works

  1. AI client connects to the MCP endpoint with OAuth2 authentication.
  2. Client calls tools/list to discover available tools (CRUD operations for each entity).
  3. Client calls tools/call to execute tools — listing, creating, updating, or deleting records.
  4. Tools respect user permissions — only tools the authenticated user has access to are available.

Endpoint

POST /api/mcp/:language/:organizationId

The endpoint accepts JSON-RPC requests implementing the MCP specification (version 2024-11-05).

MethodDescription
initializeReturns server info and capabilities
tools/listLists available tools with JSON schemas
tools/callExecutes a tool by name with arguments
notifications/initializedAcknowledgment (returns 204)

Connecting an AI client

The MCP docs page (/mcp) shows users how to connect their AI client. It displays the endpoint URL with the correct organization and language parameters, along with step-by-step instructions.

Claude Code

Add the MCP server to your Claude Code configuration:

{
  "mcpServers": {
    "your-app": {
      "type": "url",
      "url": "https://your-backend-url/api/mcp/en/your-org-id"
    }
  }
}

Claude Code handles the OAuth2 flow automatically.

Authentication

The MCP server uses Better Auth's MCP plugin with OAuth2/OIDC:

  • Auto-registered OAuth endpoints: /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource
  • Dynamic client registration is enabled
  • Users authenticate via the sign-in page, then the OAuth flow grants access to the MCP server

Tool structure

Each feature defines tools in [feature]Mcp.ts files. Tools follow a standard pattern:

export const memberFindManyMcpTool = (dictionary: Dictionary): McpTool => ({
  name: 'member_list',
  description: dictionary.member.mcpDescription.list,
  requiredPermissions: { member: ['read'] },
  schema: toMcpJsonSchema(memberFindManyInputSchema),
  handler: async (params, context) => {
    return await memberFindManyController(params, context);
  },
});

Tools are aggregated in mcp.ts via getAllMcpTools(), which is also used by the chatbot feature.

Error mapping

HTTP errors are mapped to JSON-RPC codes:

HTTPJSON-RPCMeaning
400-32602Invalid params
401-32001Unauthorized
403-32002Forbidden
404-32003Not found
Other-32603Internal error

Permissions

The MCP docs page requires the mcp:use permission. Both admin and member roles have this permission by default.

Key files

FileDescription
backend/src/features/mcp/mcp.tsMain router + tool aggregator
backend/src/features/mcp/mcpTypes.tsMcpTool interface
backend/src/features/mcp/mcpSchemaConverter.tsZod to JSON Schema converter
backend/src/features/[entity]/[entity]Mcp.tsPer-feature tool definitions
frontend/src/features/mcp/pages/McpDocsPage.tsxConnection docs page