yatta/mcp
An MCP server whose tools come from your collections.
9 exported symbols and 20 members, read from src/func/mcp.ts.
Construct
createMCPHandler
functionBuild the HTTP handler for the MCP endpoint.
createMCPHandler(options: McpOptions)Returns A `(req) => Promise<Response>` for a router or `Bun.serve`.
isSensitiveCollection
functionWhether a collection name is on the never-expose list.
Case and punctuation are ignored, so `verification_tokens` is refused for the same reason `verificationTokens` is.
isSensitiveCollection(name: string): booleansurfaceFromTables
functionBuild a surface from raw collections, leaving the sensitive ones out.
This is the safe default: a table not named here cannot be exposed by accident, because exposure is opt-in per collection rather than a filter applied afterwards.
surfaceFromTables(tables: Record<string, McpTable>, functions?: McpFunction[]): McpSurface- functions
- Tools to add alongside the generated collection tools.
Types
McpFunction
interfaceA tool you write yourself.
Use one when a collection tool is too blunt: a function gets the caller's user id, so it can enforce who may see what.
interface McpFunction4 members
namepropertyname: stringdescriptionpropertydescription: stringinputSchemapropertyinputSchema: Record<string, unknown>callpropertycall: (args: Record<string, unknown>, ctx: { userId: string; }) => Promise<unknown> | unknown
McpOptions
interfaceinterface McpOptions8 members
resolveUserpropertyresolveUser: (req: Request) => Promise<string | null>Finds the signed-in user for a request, or null when nobody is signed
getSurfacepropertygetSurface: () => Promise<McpSurface> | McpSurfaceThe app surface, read fresh on every request, so a collection added
authorizepropertyauthorize?: (info: { userId: string; collection: string; action: CollectionAction; }) => Promise<boolean> | booleanDecide per call whether this user may do this to this collection.
This is the only place row-level rules can live; the generated tools themselves have no idea who owns what.
allowedOriginspropertyallowedOrigins?: string[]Browser origins allowed to call /mcp, like `["https://app.example.com"]`.
pathpropertypath?: stringWhere the handler is mounted. Default `/mcp`.
serverNamepropertyserverName?: stringReported to clients in `initialize`. Default `yatta`.
serverVersionpropertyserverVersion?: stringReported to clients in `initialize`. Default is the framework version.
instructionspropertyinstructions?: stringSent to clients in `initialize`, and worth using: a sentence about what the tools are for.
McpSurface
interfaceEverything this app exposes to MCP: collections plus hand-written tools.
interface McpSurface2 members
tablespropertytables: Record<string, McpTable>functionspropertyfunctions: McpFunction[]
McpTable
interfaceThe slice of a database collection MCP needs.
Yatta's own collections satisfy this as they are; anything else with the same five methods can be exposed. Nothing here is called unless a client invokes the matching tool.
interface McpTable6 members
primaryKeyColumnpropertyprimaryKeyColumn?: stringfindManyfindMany(options: { take?: number; skip?: number; }): Promise<unknown[]> | unknown[]findFirstfindFirst(options: { where: Record<string, unknown>; }): Promise<unknown | null> | unknown | nullinsertinsert(data: Record<string, unknown>): Promise<unknown> | unknownupdateupdate(options: { where: Record<string, unknown>; data: Record<string, unknown>; }): Promise<{ changes: number; }> | { changes: number; }deletedelete(options: { where: Record<string, unknown>; }): Promise<{ changes: number; }> | { changes: number; }
CollectionAction
typeThe five operations a collection gets, as seen by `authorize`.
type CollectionAction = "list" | "get" | "create" | "update" | "delete"MCPHandler
typeThe handler `createMCPHandler` returns.
type MCPHandler = ReturnType<typeof createMCPHandler>AuthConfig or JobPayload — declaring your schema once is enough for the rest to follow. See Typed keys.