Integrations

Connections

Set up GitHub, Slack, Linear, databases, email, Stripe, Zendesk, GitLab and every other connection, and the tools each one provides.

Connections hold the credentials for the systems your workflows use. Workflows refer to them by slug, and every tool is namespaced by that slug, e.g. github.create_comment. A few tools need no connection at all — see built-in tools.

GitHub

  1. Create a fine-grained personal access token with access to the repositories your workflows need. Grant Contents: read, Pull requests: read & write and Issues: read & write as needed.
  2. Paste it as the connection's Access token. Optionally limit the connection to specific repositories.
  3. To trigger workflows from repository events, set a Webhook secret, then add a webhook in GitHub using the request URL shown on the connection page, content type application/json, and the same secret.

Tools: get_repository, list_pull_requests, get_pull_request (optionally with the diff), get_issue, search_issues, get_file, create_issue, create_pull_request, create_comment, add_labels.

A GitHub connection is also what a workspace clones and pushes with, and the same allowed repositories list applies there — so a run that writes code can only write to repositories you already listed here.

Trigger events: pull_request, pull_request_review, pull_request_review_comment, issues, issue_comment, push, release, workflow_run, check_run.

Slack

  1. Create a Slack app, add the bot scopes your workflows need (chat:write, reactions:write, channels:history, users:read) and install it to your workspace.
  2. Paste the Bot token (xoxb-…). Optionally restrict which channels it may post to.
  3. To trigger workflows from Slack, paste the app's Signing secret, enable Event Subscriptions with the request URL shown on the connection page, and subscribe to app_mention, message.channels or reaction_added.

Tools: post_message, update_message, add_reaction, get_thread, channel_history, get_user.

Linear

  1. Create a personal API key under Settings → Account → Security & access in Linear. Workflows act as the person who made it, so consider a dedicated user for automation.
  2. Paste it as the connection's API key. Optionally limit the connection to specific teams by key, such as ENG, OPS.
  3. To trigger workflows from Linear, add a webhook under Settings → API → Webhooks using the request URL shown on the connection page, choose the data change events you need, and paste its signing secret on the connection.

Tools: get_issue (with its comments), search_issues (by text, team, state or assignee), list_teams (with their workflow states), create_issue, update_issue, create_comment. Issues are named by identifier, like ENG-123. Teams, states, labels and assignees are given by key, name or email address, and the connection looks up Linear's IDs for you.

Trigger events: Issue, Comment, IssueLabel, Reaction, Project, ProjectUpdate, Cycle, Document, Attachment.

PostgreSQL

  1. Create a database role with the least privileges your workflows need — usually read-only access to a reporting schema.
  2. Paste a connection URL: postgres://user:password@host:5432/database.
  3. Queries run inside read-only transactions with a 15 second statement timeout and a 1,000 row cap. Enable Allow writes only if a workflow must modify data; it adds an execute tool.

Tools: query, list_tables, describe_table, and execute when writes are allowed.

MySQL

Works with MySQL 5.7 and later, and with MariaDB.

  1. Create a user with the least privileges your workflows need — usually SELECT on one database.
  2. Paste a connection URL: mysql://user:password@host:3306/database. Percent-encode any @, : or / in the password.
  3. Pick an SSL mode: preferred (the default) uses TLS when the server offers it, required insists on it, and verify-ca and verify-identity also check the server's certificate.
  4. Queries run inside read-only transactions with a 15 second time limit and a 1,000 row cap, one statement at a time. Enable Allow writes only if a workflow must modify data; it adds an execute tool.

Tools: query, list_tables, describe_table, and execute when writes are allowed. Use ? placeholders and pass the values in params, e.g. sql: "select * from orders where customer_id = ?" with params: [42]. Values are escaped by the driver, never pasted into the SQL as-is.

Amazon Redshift

Works with provisioned clusters and Redshift Serverless.

  1. Create a database user with the least privileges your workflows need — usually SELECT on one schema.
  2. Paste a connection URL: postgres://user:password@examplecluster.abc123.us-east-1.redshift.amazonaws.com:5439/dev. The port defaults to 5439.
  3. Pick an SSL mode: require (the default) encrypts the connection, and verify-full also checks Redshift's certificate against the system's trusted certificate authorities.
  4. Queries run inside BEGIN READ ONLY transactions with a 15 second statement timeout and a 1,000 row cap. Enable Allow writes only if a workflow must modify data; it adds an execute tool.

Tools: query, list_tables, describe_table, and execute when writes are allowed. Use $1, $2 placeholders and pass the values in params. list_tables and describe_table read svv_tables and svv_columns, so they include external (Spectrum) schemas.

CockroachDB

  1. Create a SQL user with the least privileges your workflows need — usually SELECT on one database.
  2. Paste the connection URL from the cluster's Connect dialog: postgresql://user:password@my-cluster-1234.abc.cockroachlabs.cloud:26257/defaultdb. The port defaults to 26257.
  3. Pick an SSL mode: verify-full (the default) checks the cluster's certificate against the system's trusted certificate authorities, which works for CockroachDB Cloud Basic and Standard. Use require for a cluster signed by its own CA.
  4. Queries run inside read-only transactions with a 15 second statement timeout and a 1,000 row cap. Enable Allow writes only if a workflow must modify data; it adds an execute tool.

Tools: query, list_tables, describe_table, and execute when writes are allowed. Use $1, $2 placeholders and pass the values in params.

ClickHouse

Connects over the HTTP interface, so it works with ClickHouse Cloud and self-hosted servers alike.

  1. Create a user with the least privileges your workflows need — usually SELECT on one database — and paste its Username and Password.
  2. Enter the Host, such as abc123.us-east-1.aws.clickhouse.cloud, and optionally a Database. The port defaults to 8443 over HTTPS, or 8123 if you pick HTTP for a server on a private network.
  3. Queries run with ClickHouse's readonly=1 setting, which refuses writes, DDL and attempts to change settings, plus a 15 second max_execution_time and a 1,000 row cap. Enable Allow writes only if a workflow must modify data; it adds an execute tool.

Tools: query, list_tables, describe_table, and execute when writes are allowed. Write params as typed placeholders and pass the values by name, e.g. sql: "select * from orders where customer_id = {id:UInt64}" with params: { "id": 42 }. ClickHouse substitutes them itself, so values are never pasted into the SQL.

Snowflake

Connects through the Snowflake SQL API with a programmatic access token.

  1. Create a role that can only read what your workflows need, and a user with that role. This role is the real safeguard: Snowflake has no read-only transactions.
  2. In Snowsight, generate a programmatic access token for that user, restricted to the role. By default Snowflake only accepts these tokens from users covered by a network policy.
  3. Paste the token, and enter your Account identifier — the part before .snowflakecomputing.com, such as myorg-myaccount. Optionally set the Warehouse, Database, Schema and Role queries run with.
  4. Statements run one at a time with a 15 second timeout and a 1,000 row cap; a statement still running at 15 seconds is cancelled. query refuses anything that doesn't start with SELECT, WITH, SHOW, DESCRIBE, EXPLAIN or LIST, but that check can't see what a function does, so rely on the role. Enable Allow writes only if a workflow must modify data; it adds an execute tool.

Tools: query, list_tables, describe_table, and execute when writes are allowed. Use ? placeholders and pass the values in params, e.g. sql: "select * from orders where customer_id = ?" with params: [42]. They are sent as bind variables, never pasted into the SQL.

Databricks

Connects to a SQL warehouse through the Statement Execution API.

  1. Use a user or service principal with only the Unity Catalog grants your workflows need — usually USE CATALOG, USE SCHEMA and SELECT. Those grants are the real safeguard.
  2. Generate a personal access token for it under Settings → Developer → Access tokens and paste it.
  3. Enter the Workspace host, such as dbc-a1b2c3d4-e5f6.cloud.databricks.com, and the SQL warehouse ID from the warehouse's Connection details tab. Optionally set a Catalog and Schema.
  4. Statements run with a 15 second limit, after which Databricks cancels them, and a 1,000 row cap. A stopped warehouse has to start within that time, so keep it running or use a serverless warehouse. query refuses anything that doesn't start with SELECT, WITH, SHOW, DESCRIBE, EXPLAIN or LIST, but that check can't see what a function does, so rely on the grants. Enable Allow writes only if a workflow must modify data; it adds an execute tool.

Tools: query, list_tables, describe_table, and execute when writes are allowed. Write params as :name markers and pass the values by name, e.g. sql: "select * from orders where customer_id = :id" with params: { "id": 42 }. list_tables and describe_table read the catalog's information_schema, which Unity Catalog provides.

BigQuery

  1. Create a service account with the BigQuery Job User role on the project that runs queries, and BigQuery Data Viewer on the datasets workflows read.
  2. Create a JSON key for it and paste the whole file as the Service account key.
  3. Optionally set the Project ID (it defaults to the key's project), a Location such as US or EU, and a Default dataset so queries can name tables without their dataset.
  4. query first dry-runs the statement and only runs it if BigQuery reports a SELECT. Jobs have a 15 second limit, after which they are cancelled, and a 1,000 row cap. Enable Allow writes only if a workflow must modify data; it adds an execute tool.

Tools: query, list_tables, describe_table, and execute when writes are allowed. Write params as @name and pass the values by name, e.g. sql: "select * from shop.orders where customer_id = @id" with params: { "id": 42 }. They are sent as named query parameters, never pasted into the SQL.

Catalog connections

Stripe, Shopify, Zendesk, Jira, GitLab, PagerDuty and dozens more all work the same way:

  1. Add the connection and paste the key the form asks for. Each form says where to find it in the provider's settings, and some also ask for a setting such as your subdomain or site.
  2. Test connection makes one read-only call to prove the key works.
  3. Named tools cover the common jobs, such as stripe.create_refund or zendesk.update_ticket, with responses trimmed to what a workflow needs. For anything else, api_get sends a GET to any path of the provider's API with the same key. Tick Allow raw writes to add api_request for POST, PUT, PATCH and DELETE. The named write tools work either way.
  4. Connections marked Triggers on the integrations page can start workflows from the provider's webhooks. Paste the webhook signing secret on the connection, and in the provider add a webhook pointing at the request URL on the connection page. Every delivery's signature is checked, and its timestamp too where the provider sends one, before anything runs. See catalog triggers.

The integrations page lists each connection's tools, trigger events and setup steps.

Connecting with OAuth

Google, Microsoft, Salesforce, QuickBooks, Xero and other providers that don't hand out API keys connect with OAuth instead:

  1. Add the connection. If your Murmurator administrator has set up an app for that provider, leave Client ID and Client secret blank. Otherwise create an app in the provider's developer console, register the Redirect URL shown on the connection page, and paste the app's client ID and secret.
  2. Press Connect on the connection page. You're sent to the provider to approve access, then back to the connection, which runs its test call.
  3. Access tokens are kept encrypted and renewed automatically before they expire. If the provider refuses a renewal, because access was revoked or the app changed, the connection is marked failing and Reconnect starts over.

Only owners and admins can connect or reconnect. A connection made by the assistant or over MCP comes back with an authorize_url to open in a browser.

Some providers, such as Zoom, Help Scout and Shopify's Dev Dashboard apps, use an app's client ID and secret without a browser step. Paste them, and Murmurator fetches and renews tokens on its own.

To offer one app to every account, set OAUTH_<KIND>_CLIENT_ID and OAUTH_<KIND>_CLIENT_SECRET (for example OAUTH_SALESFORCE_CLIENT_ID), or oauth.<kind>.client_id and client_secret in the Rails credentials, and register https://<your host>/oauth/callback as its redirect URL.

HTTP API

For a service that has no connection of its own yet, or an internal service with an HTTP API and a key.

  1. Set the Base URL, e.g. https://api.stripe.com/v1. Every request goes to a path under it, and a request can't be pointed anywhere else.
  2. Paste the API key or token and pick the Auth scheme: bearer (the default) sends Authorization: Bearer <key>, header sends it in a header you name (default X-API-Key), query as a parameter you name (default api_key), and basic with a username and the key as its password. Use none for an API that needs no key.
  3. Optionally list Allowed paths, such as /customers, /invoices, to keep the connection to part of the API, and a Test path such as /me for Test connection to call.
  4. Requests are GET only until you tick Allow writes, which adds a request tool for POST, PUT, PATCH and DELETE.

Tools: get (path, params, headers), and request (method, path, params, body, form, headers) when writes are allowed. JSON responses come back parsed. Set form: true for APIs such as Stripe that take form-encoded bodies. A step can add headers such as Notion-Version, but not replace the one carrying the key.

Email

Send email through the provider you already use. Each one needs only an API key:

Provider Key Also needs
Postmark A Server token from the server's API Tokens tab Optionally a Message stream (default outbound)
Resend An API key (re_…); sending access is enough
SendGrid An API key (SG.…) with Mail Send
Mailgun A domain sending key or your private API key The Sending domain, and the Region (us or eu)
  1. Add the connection and paste the key.
  2. Set From to a sender the provider has verified, as an address or with a name: Acme Alerts <alerts@acme.com>.
  3. Optionally list Allowed recipients — addresses such as ops@acme.com or whole domains such as @acme.com — so a workflow can only ever email the people you meant it to.

Tools: send_email (to, cc, bcc, subject, text, html, reply_to), the same for every provider, so switching providers doesn't change a workflow. Pass text, html or both. A message can have up to 50 recipients.

Exposing tools over MCP

Tick Expose tools over MCP on a connection to let agents connected with your API token call its tools directly, in addition to running workflows.