Skip to content

MCP Connectors

MCP connectors let Mako’s AI agent use tools from external Model Context Protocol servers. Where SaaS Sync (Connectors) pulls data into your warehouse for querying, MCP connectors let the agent act in other systems — search leads, create contacts, log activities, and more — directly from chat.

MCP servers are agent-runtime tooling, deliberately separate from data-sync connectors: they have a different lifecycle, credentials, and permission model.

Go to Settings → MCP Servers (workspace admins only) and choose a preset:

  • Close CRM — the official mcp.close.com server. Lets the agent search leads, manage opportunities, create contacts, and log activities in your Close organization. Defaults to OAuth login; API-key auth is also supported.
  • Slack — the official mcp.slack.com server. Lets the agent search messages, read channel and thread history, look up users, and (with write access) send messages and reactions. OAuth only; requires a pre-registered Slack app (see below).
  • GitHub — the official api.githubcopilot.com/mcp/ server. Lets the agent browse repositories, read code and issues, search across GitHub, and (with write access) create issues, branches, and pull requests. OAuth (pre-registered GitHub OAuth App, see below) or a personal access token.
  • Custom MCP server — connect any MCP server reachable over Streamable HTTP. Provide the server URL and choose OAuth, API-key, or no authentication.

After adding a server, use Test connection to verify credentials and discover the server’s tool list. Discovered tools are cached in the workspace so chat startup never blocks on an MCP round-trip.

Two credential modes, both encrypted at rest (AES-256-CBC):

  • OAuth 2.0 personal login — each user signs in with their own account. Mako uses Dynamic Client Registration + PKCE against the server’s OAuth metadata, then persists per-user refresh tokens and auto-refreshes them. This is the recommended mode for Close.
  • API key / headers — for preset servers, fill in the provider’s credential fields (e.g. Close’s Close-API-Key, or a GitHub personal access token — paste just the token, the Bearer prefix is added automatically). For custom servers, supply free-form HTTP headers. Credentials can be shared across the workspace or per-user.

OAuth client registration: DCR vs. pre-registered apps

Section titled “OAuth client registration: DCR vs. pre-registered apps”

Providers register Mako as an OAuth client in one of two ways:

  • Dynamic Client Registration (DCR) — the MCP-spec default (Close). Mako registers itself automatically on the first connect; no admin setup beyond adding the server.
  • Pre-registered app (Slack, GitHub) — the provider only accepts confidential OAuth apps registered in advance. There are two ways to supply one:
    • Deployment-wide app (recommended, one-click) — the Mako operator registers a single provider app and sets its client in the server environment (SLACK_MCP_CLIENT_ID / SLACK_MCP_CLIENT_SECRET, GITHUB_MCP_CLIENT_ID / GITHUB_MCP_CLIENT_SECRET). Every workspace then connects Claude-style: add the connector, click Connect, approve on the provider’s site. No form, no per-workspace app.
    • Per-workspace app (self-host fallback) — when no environment client is configured, a workspace admin creates the app with the provider and saves its Client ID and Client Secret on the connection before members can sign in. Rotating the app credentials invalidates previously issued member tokens; everyone reconnects.

Slack app setup (operators / self-hosters)

Section titled “Slack app setup (operators / self-hosters)”
  1. Create a Slack app at api.slack.com/apps (internal to your org, or Marketplace-published — Slack requires one of the two for MCP).
  2. Enable MCP under Agents & AI Apps in the app settings.
  3. Add Mako’s OAuth callback as a redirect URL. It must match what the API sends: ${PUBLIC_URL || CLIENT_URL}/api/mcp/oauth/callback (shown in the connection dialog). Local default: http://localhost:5173/api/mcp/oauth/callback. Production: https://app.mako.ai/api/mcp/oauth/callback.
  4. Add the user scopes matching the write scope you’ll pick in Mako — the connection dialog requests them automatically: read-only connections request only search:read.*, history, and read scopes; write_safe adds chat:write, reactions:write, canvases:write; write_destructive adds channel/conversation management scopes.
  5. Either set SLACK_MCP_CLIENT_ID / SLACK_MCP_CLIENT_SECRET in Mako’s environment (deployment-wide, one-click for every workspace), or paste the app’s Client ID and Client Secret in Settings → MCP Servers → Slack. Each member then clicks Connect Slack account.

GitHub app setup (operators / self-hosters)

Section titled “GitHub app setup (operators / self-hosters)”

GitHub’s remote MCP server does not support Dynamic Client Registration, so OAuth needs a pre-registered app:

  1. Create a GitHub OAuth App under Settings → Developer settings → OAuth Apps (a personal account or an organization can own it).
  2. Set the Authorization callback URL to what the API sends: ${PUBLIC_URL || CLIENT_URL}/api/mcp/oauth/callback (shown in the connection dialog). Local default: http://localhost:5173/api/mcp/oauth/callback.
  3. Either set GITHUB_MCP_CLIENT_ID / GITHUB_MCP_CLIENT_SECRET in Mako’s environment (deployment-wide, one-click for every workspace), or paste the app’s Client ID and Client Secret in Settings → MCP Servers → GitHub. Each member then clicks Connect GitHub account.

No OAuth app? Members can instead authenticate with a personal access token (API-key mode): generate a token on GitHub and paste just the token — Mako sends it as Authorization: Bearer <token>. Read-only connections are enforced server-side by GitHub regardless of the token’s own permissions (via the X-MCP-Readonly header).

Each connection carries a write scope that caps what its tools can do. For Close, this maps to the provider’s Close-Scope header; for GitHub, a read-only connection sends the provider-enforced X-MCP-Readonly: true header; for Slack, it selects the OAuth scope set requested at sign-in (a read-only connection never even holds a chat:write token):

Write scopeMeaning
readRead-only. Every tool is treated as read-tier regardless of its own hints.
write_safeReads plus non-destructive writes.
write_destructiveReads plus destructive writes (deletes, irreversible changes).

Within an allowed scope, each discovered tool is assigned a risk tier:

  • read — the whole connection is read-tier when write scope is read, or the tool declares readOnlyHint: true.
  • destructive — the tool declares destructiveHint: true.
  • write — the default when hints are absent.

MCP tool calls use a Claude-style human-in-the-loop approval, surfaced as an approval card in chat with an input preview and risk badge. Three choices:

  • Allow once — run this call now.
  • Always allow — run now and persist an always_allow grant so future calls of this tool skip the prompt.
  • Deny / Block — refuse this call; a persisted always_deny grant refuses future calls at execution without prompting.

Default behavior by tier:

  • read tools auto-run (no prompt).
  • write tools prompt unless you’ve granted always allow.
  • destructive tools always prompt and can only be unlocked by a workspace admin.

Grants are per-user and per-tool. Manage or revoke them under Settings → MCP Servers.

Tools are namespaced mcp_<server>_<tool> in the agent runtime, and are treated as cross-cutting across modes. The plan gate keeps only read-tier MCP tools available during planning.

MCP tools are deferred in the agent’s tool working set: they stay registered and executable (approval flow intact) but are sent to the model only after discovery (search_tools/load_tools) or a per-turn relevance preload. This keeps workspaces with many connectors under provider tool-count caps and context budgets — adding MCP servers no longer bloats every request. Workspaces whose whole tool surface fits the budget bypass paging and behave as before.

  • Server URLs are SSRF-guarded (no internal/loopback targets).
  • Each tool execution opens a short-lived, credential-scoped MCP client — there is no cross-tenant connection pooling.
  • Credentials and OAuth client registrations are encrypted at rest with the same wire format as data-sync connector configs.

Server management lives under /api/workspaces/:workspaceId/mcp-servers (admin-gated); presets and the OAuth callback live under /api/mcp.

MethodPathPurpose
GET/api/mcp/presetsList MCP connector presets
GET/api/mcp/oauth/callbackOAuth authorization callback (redirects to /settings/mcp)
GET/api/workspaces/:workspaceId/mcp-serversList MCP servers
POST/api/workspaces/:workspaceId/mcp-serversCreate a server
PATCH/api/workspaces/:workspaceId/mcp-servers/:idUpdate a server
DELETE/api/workspaces/:workspaceId/mcp-servers/:idDelete a server
PUT/api/workspaces/:workspaceId/mcp-servers/:id/credentialsSave credentials
PUT/api/workspaces/:workspaceId/mcp-servers/:id/oauth/clientSave a pre-registered OAuth app (client ID + secret; admin)
POST/api/workspaces/:workspaceId/mcp-servers/:id/oauth/connectStart OAuth flow (returns authorization URL)
POST/api/workspaces/:workspaceId/mcp-servers/:id/testTest connection and refresh tool list
GET/api/workspaces/:workspaceId/mcp-servers/tool-infoTool metadata for the chat UI
GET/api/workspaces/:workspaceId/mcp-servers/:id/grantsList your tool grants
POST/api/workspaces/:workspaceId/mcp-servers/:id/grantsCreate/update a tool grant
DELETE/api/workspaces/:workspaceId/mcp-servers/:id/grants/:grantIdRevoke a tool grant

See the auto-generated REST API reference for full request and response schemas.