Skip to content

Integrations (MCP)

Available since v0.51.0

The Model Context Protocol (MCP) is an open standard for giving AI and apps access to external services. On Maypop, an integration is an MCP server you connect to your account and then link to an app: a calendar, a search engine, a project tracker, your own API.

Credentials stay with Maypop. The app and the people using it call the service’s tools; nobody ever sees the token.

In your settings, open Integrations:

  • Pick a service from the catalog and sign in to it, or
  • Add a Custom MCP server by URL.

You can connect several accounts of the same service and name each one (“Name this account”). Disconnect removes a connection and its links to apps. You can also connect from the new-tab composer’s + menu while describing an app, or from the command line with maypop mcp connect.

Connections are yours; an app only uses the ones you add to it. Add an integration from the app’s panel or from Studio. Only the app’s owner and people with Can manage can link integrations.

Once linked:

  • Studio can use it while building, so the agent can wire it into the app for you.
  • The app can call it at runtime through maypop.mcp, for everyone using it, on your connection.
interface MaypopMcpServer {
id: string;
name: string;
url: string;
account?: string | null;
}
interface MaypopMcpToolResult {
content?: Array<{ type: string; text?: string; [k: string]: unknown }>;
structuredContent?: unknown;
isError?: boolean;
}
interface MaypopMcp {
servers(): Promise<MaypopMcpServer[]>;
call(
serverId: string,
name: string,
args?: Record<string, unknown>,
): Promise<MaypopMcpToolResult>;
tools(serverId?: string): Promise<MaypopAgentToolDef[]>;
}

Which servers are linked can change at any time, and a remix of your app starts with none. Look them up at runtime and hide the feature when nothing fits — never hard-code an id:

await maypop.ready();
const [server] = await maypop.mcp.servers();
const tool =
server && (await maypop.mcp.tools(server.id)).find((t) => /search/i.test(t.name));
if (tool) {
const result = await maypop.mcp.call(server.id, tool.name, { query });
if (!result.isError) render(result.structuredContent ?? result.content);
}
  • servers() resolves to [] when nothing is linked.
  • call() returns the raw MCP result; check isError.
  • tools() returns the tools as agent tool definitions, ready to hand to maypop.agent.create({ tools }). Their execute throws when a call fails.
  • Anonymous visitors can list servers and tools, but call() fails with maypop/sign-in-required.
const session = await maypop.agent.create({
systemPrompt: "You help the team triage new issues.",
tools: await maypop.mcp.tools(),
});

The local dev host can serve mock MCP servers from .maypop/local/mcp.json, or — in hybrid mode — the real integrations linked to your app. Try a tool from the terminal first with maypop mcp tools and maypop mcp call.