Skip to content

Tools, MCP & Connectors

The AI agent's "abilities" come from tools. A tool is a JSON-schema function the model can call. Doable assembles a tool list for every chat message from three layers:

  1. Built-in tools: file I/O, shell, fetch, package install. Always present.
  2. Connectors (MCP servers): locally running Model Context Protocol servers, e.g. an in-house knowledge base.
  3. Integrations: third-party SaaS (Notion, Slack, Linear, Stripe, Supabase, ...) exposed as tools via OAuth.

Built-in tools

Implemented under services/api/src/ai/tools/ and registered by copilot-tool-loader.ts.

Tool What it does
read_file Read a file from the project tree
write_file Create / replace a file
edit_file Patch a file (string-replace)
list_dir List a directory
grep Regex search across the project
shell Run a shell command (policy-gated)
install_package pnpm add with auto-detect for npm/yarn projects
fetch HTTP GET with URL allow-list
screenshot_preview Capture the live preview as PNG (Puppeteer)
restart_dev_server Cycle the project's Vite process

Every call passes through the policy sandbox. Filesystem operations are confined to the project root via dovault.

Adding an MCP connector

MCP is a standard for talking to AI tool servers over JSON-RPC.

  1. Run any MCP server (your own, or one from the catalog).
  2. In Doable: Workspace Settings → AI → Connectors → Add MCP server. Provide the URL or stdio command.
  3. The connector manager (services/api/src/mcp/connector-manager.ts) connects, lists tools, and stores the metadata in the connectors table.
  4. Workspace admins toggle individual tools on/off; the policy is persisted.

The next chat session will see the MCP tools alongside the built-ins.

Integrations (third-party SaaS)

Doable ships with connectors to dozens of SaaS products. The catalog lives in services/api/src/integrations/registry/ and is grouped by domain:

Group Examples
ai-ml OpenAI, Anthropic, Together, Replicate, Hugging Face
communication Slack, Discord, Telegram, Teams
crm-marketing-social HubSpot, Mailchimp, Twitter/X, LinkedIn
developer-tools GitHub, GitLab, Linear, Sentry, Vercel
finance-ecommerce Stripe, PayPal, Shopify, QuickBooks
productivity Notion, Google Drive, Airtable, Asana

Adding a connection:

  1. Workspace Settings → Integrations → Browse.
  2. Pick a service, click Connect, OAuth in.
  3. Doable encrypts and stores the token (ENCRYPTION_KEY).
  4. The integration's tools become available to the agent in the next message.

The runtime that executes integration tool calls is services/api/src/integrations/runner.ts. It normalizes the wide variety of REST/SOAP/webhook conventions into a single tool.call interface.

Using MCP tools in generated apps (published sites)

MCP tools and integrations aren't just for the AI agent. Your generated apps can call them at runtime too. The @doable/sdk provides a secure proxy client:

import { createDoableClient } from "@doable/sdk";

const doable = createDoableClient(); // auto-configures in both preview and production

// Call an MCP tool
const custodians = await doable.mcp.call("mcp_hpca_list_custodians", { limit: 50 });

// Call an integration action
const result = await doable.integrations.run("slack", "send_message", { channel: "#alerts", text: "Done!" });

When you publish the app, Doable auto-provisions a scoped API key that restricts the published site to only the tools it uses. See API Keys & Auto-Provisioning for the full flow.

Re-publish after adding new MCP tools

If you connect a new MCP server to your workspace and the AI generates code using its tools, you must re-publish for the live site to access them. The key scope is set at build time. Learn more

Tool selection per mode

Different modes get different tool subsets. For example, Plan mode only allows read-only tools so the agent can analyze the codebase without modifying it. Configure under Workspace Settings → AI → Modes.

The mapping is stored in mode_tool_config (migration 050_mode_tool_config.sql) and edited by routes/admin-tools.ts.

Audit trail

Every tool call generates a SandboxAuditEntry:

  • timestamp
  • tool name + args
  • decision (allow / deny / ask)
  • result or error
  • session, workspace, user

View under Workspace Settings → Audit or query the activity_events table directly.

MCP Apps Compatibility

Doable speaks the MCP Apps extension protocol. When a connected MCP server declares a _meta.ui.resourceUri field on a tool description (a ui://... resource), Doable treats that tool as an MCP App: the host fetches the ui:// resource and renders its HTML + JS inside a sandboxed iframe, so the model can hand off an interactive surface (chart, form, picker) instead of a JSON blob.

The implementation lives in services/api/src/mcp/apps-resource.ts:

  • detectAppsInToolList(connectorId, tools): scans a freshly listed tool catalog, counts tools that carry a _meta.ui.resourceUri starting with ui://, and emits an OpenTelemetry mcp.app.detect span with one mcp.app.detected event per tool. The event records the resource URI, the requested permissions, and the CSP entry count, so a connector that ships UIs is visible in the trace timeline.
  • tracedAppResourceFetch({ connectorId, resourceUri }, fetcher): wraps the actual resources/read round-trip in an mcp.app.resource_fetch span. The span records mcp.app.bytes, mcp.app.content_count, and mcp.app.fetch.duration_ms so latency and payload size show up in the same trace as the tool call that triggered the fetch.

What this means in practice:

  • Any MCP server you connect through Workspace Settings → AI → Connectors that exposes _meta.ui on its tools will have its UI resources discovered automatically; no per-connector configuration is needed.
  • The ToolMetaUi shape used by Doable is { resourceUri?, permissions?, csp?, ... }. Permissions and CSP entries are forwarded to the iframe sandbox; only resources whose URI starts with ui:// are treated as apps (the prefix check protects against arbitrary URLs being rendered as trusted UIs).
  • The detect + fetch events flow through the same OTel pipeline as the rest of the tool-call telemetry, so you can search the trace UI for mcp.app.* spans when debugging a misbehaving app.

There is currently no Doable-side UI builder that emits ui:// resources; the compatibility is consumer-side. If you write your own MCP server and add _meta.ui.resourceUri to a tool's description, Doable will render it without code changes on the platform side.

Writing your own integration

See Contributing → Add an Integration.

See also