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:
- Built-in tools: file I/O, shell, fetch, package install. Always present.
- Connectors (MCP servers): locally running Model Context Protocol servers, e.g. an in-house knowledge base.
- 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.
- Run any MCP server (your own, or one from the catalog).
- In Doable: Workspace Settings → AI → Connectors → Add MCP server. Provide the URL or stdio command.
- The connector manager (
services/api/src/mcp/connector-manager.ts) connects, lists tools, and stores the metadata in theconnectorstable. - 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:
- Workspace Settings → Integrations → Browse.
- Pick a service, click Connect, OAuth in.
- Doable encrypts and stores the token (
ENCRYPTION_KEY). - 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.resourceUristarting withui://, and emits an OpenTelemetrymcp.app.detectspan with onemcp.app.detectedevent 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 actualresources/readround-trip in anmcp.app.resource_fetchspan. The span recordsmcp.app.bytes,mcp.app.content_count, andmcp.app.fetch.duration_msso 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.uion its tools will have its UI resources discovered automatically; no per-connector configuration is needed. - The
ToolMetaUishape used by Doable is{ resourceUri?, permissions?, csp?, ... }. Permissions and CSP entries are forwarded to the iframe sandbox; only resources whose URI starts withui://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.