Skip to main content
The MCP plugin exposes your app’s collections and tools to external MCP clients such as Claude Desktop and Cursor. It signs requests in with FrogBot’s hashed, revocable API keys, so your app has one key system.

Install

Configure

Add mcpPlugin() and apiKeysPlugin() to the plugin array, in any order. MCP needs apiKeysPlugin() and fails at startup without it. It runs with order: 10.
Configure your MCP client to send Streamable HTTP requests to /api/mcp with a key from the API Keys admin collection:
Revoked, malformed, and unknown keys are rejected with 401. The MCP endpoint only accepts users signed in by the API keys plugin.

What clients can reach

Every app collection is exposed by default, through shared tools (getConfigInfo, findDocuments, createDocuments, updateDocument, deleteDocuments, getCollectionSchema and more). Each call runs as the key’s owner, with your collections’ access control: a key reaches nothing over MCP its owner can’t reach over REST. A ?overrideAccess=true query is ignored in development and rejected with 400 elsewhere. FrogBot’s own collections (chats, messages, API keys, connections, logs and the like) are never exposed. To narrow a collection, turn off its built-in tools or reword them:

Tools

Pass tools the same list an agent’s tools takes: tools, piece actions and piece instances (every action). Each one is served under its slug, with its inputSchema as the JSON Schema clients see. Root tools and agents’ tools aren’t served unless listed here.
  • Input. A call is checked against inputSchema before execute runs; invalid input returns an error result.
  • Context. ctx.req is the request, signed in as the key’s owner, so collection access applies to Local API calls made with it. ctx.agent is { slug: 'mcp', runId }, with a new runId per call and no chatId.
  • Result. A string becomes one text block. Anything else becomes its JSON text, and a plain object is also sent as structuredContent. hooks.afterToolCall sees the result.
  • Errors. A thrown error becomes an error result with its message; the server keeps serving.
  • Refused. mcpPlugin throws for a client tool such as question, a duplicate slug, a slug that a built-in tool already uses (getConfigInfo, findDocuments, login and the rest), or an input schema that isn’t an object or can’t be written as JSON Schema (such as z.date()), since one such schema would break tools/list for every tool.
Piece tools resolve credentials as they do in an agent: a piece without auth in its config, like slack above, acts with the key owner’s connected account. Tools that need a chat, such as write_todos and read_todos, always fail over MCP.
Every listed tool is available to every valid key. To limit a tool to some users, check ctx.req.user in execute and throw. definePrompt comes from @frogbotai/plugin-mcp and infers the handler’s input from argsSchema.

Options

FrogBot handles authorization itself, so there’s no option to replace it. Prompts and resources take an optional access({ req, permissions }) that hides them from keys it returns false for. Without one, any signed-in key can use them. SSE is not supported.