> ## Documentation Index
> Fetch the complete documentation index at: https://docs.breakingtrailtech.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connections

> Every connector Scout has: how a brand connects it, what it can read, what it can change, and what it costs.

A connector registers for a session only when that brand's credentials for it
resolve. A connector a brand has not connected is absent from its sessions
entirely. Credentials are resolved per connector, in this order:

1. The brand's own stored connection.
2. A connection the account owner has shared with this brand (the brand must be
   a real member of the account **and** be ticked for that connector).
3. For the deployment owner's own brand only, the server's host environment.

No other brand ever inherits the host environment. A brand whose credentials
cannot be read gets no connections for that session rather than someone
else's.

Source: `src/engine/credentials.ts` (`resolveConnectors`), `src/server/http.ts` (`connectorEnvFor`)

## Summary

| Connector | How it connects | Reads | Writes | Who approves a write | Cost |
| - | - | - | - | - | - |
| Shopify | Pasted store domain and app credentials, or an Admin token | Shop, products, orders, Admin GraphQL queries | Admin GraphQL mutations | A person, per mutation, and only with `SHOPIFY_ALLOW_WRITES` | Free to Scout |
| DataForSEO | Pasted login and password | Keywords, SERPs, competitors, audits, trends | None | A person approves spends above a threshold | Billed per call in dollars |
| Firecrawl | Pasted API key | Scrape, search, map, crawl | None | A person approves spends above a threshold | Billed per call in credits |
| Google Ads | One-click Google sign-in | Accounts, campaigns, reports, search terms | None | Not applicable | Daily operation caps |
| Search Console | One-click Google sign-in | Properties, queries, pages, URL inspection | None | Not applicable | Free |
| Google Analytics | One-click Google sign-in | Properties, reports | None | Not applicable | Free |
| Google Sheets | One-click Google sign-in | Sheets this app created | New sheet, append rows | A person, every call | Free |
| Microsoft Ads | One-click sign-in through Nango | Accounts, campaigns, reports | None | Not applicable | Daily call caps |
| Figma | One-click sign-in through Nango | Files, nodes, images, comments, components and styles, team projects | None | Not applicable | Figma's own per-seat rate limits |
| GitHub | Pasted fine-grained token | Files, branches, issues, pull requests | Branch, commit, pull request, comment | A person, per write, and only with `GITHUB_ALLOW_WRITES` | Free |
| AgentMail | Pasted API key and inbox | Threads, messages, drafts | Drafts; sends | Sends: a person, per send, and only with `AGENTMAIL_ALLOW_SENDS` | Monthly recipient cap |
| Cloudflare | One-click OAuth, or a pasted API token | Cloudflare docs and API search | The `execute` tool | A person, every call | Free to Scout |
| Contentsquare | Pasted server URL, then OAuth | Whatever its server offers | None known | No gate in this code | Not metered here |
| Railway | "Login with Railway", or a pasted token | Projects, deployments, variable names, logs | Reveal variable values; redeploy | A person, every call, and only with each switch | Free to Scout |
| Browser (E2B or Browserbase) | Operator configuration | Page text and screenshots | None | Not applicable | Browser minutes |

## Shopify

**Connects with** a pasted store domain plus either the app's client id and
secret (exchanged for a token that lasts about a day) or an Admin API token.

**Tools.** `mcp__shopify__shopify_shop_info`, `mcp__shopify__shopify_search_products`
and `mcp__shopify__shopify_recent_orders` read. `mcp__shopify__shopify_admin_graphql`
runs any Admin GraphQL query freely; a **mutation** through it needs all of:

* the operator's switch `SHOPIFY_ALLOW_WRITES` (`true`, `1` or `yes`);
* a plain-sentence `intent` naming what will change;
* a person approving that specific change, when approvals are on.

<Warning>
  With approvals switched off (`REQUIRE_WRITE_APPROVAL=false`), every mutation
  is refused and reads keep working. Until 2026-10-11 a mutation ran on the
  switch alone in that case; that was a hole and it is closed. Coworkers cannot
  hold the Admin GraphQL tool in any configuration.
</Warning>

A specialist granted Shopify gets the three read tools, and a profile that asks
for them, the content writer tools, which write drafts into the project folder
and never to the store.

Source: `src/engine/shopify.ts`, `src/engine/writer.ts`

## DataForSEO

**Connects with** a pasted DataForSEO login and password.

**Tools.** Twelve tools: `mcp__dataforseo__dataforseo_account`,
`mcp__dataforseo__dataforseo_keyword_ideas`, `mcp__dataforseo__dataforseo_search_volume`,
`mcp__dataforseo__dataforseo_keyword_overview`, `mcp__dataforseo__dataforseo_ranked_keywords`,
`mcp__dataforseo__dataforseo_serp_organic`, `mcp__dataforseo__dataforseo_competitors`,
`mcp__dataforseo__dataforseo_page_audit`, `mcp__dataforseo__dataforseo_keyword_difficulty`,
`mcp__dataforseo__dataforseo_search_intent`, `mcp__dataforseo__dataforseo_rank_history`,
`mcp__dataforseo__dataforseo_trends`. A thirteenth,
`mcp__dataforseo__seo_page_opportunities`, registers only when Shopify and
Search Console are connected too, because it reads all three.

**Cost.** Each call's cost is estimated before it is made.

| Limit | Default | Variable |
| - | - | - |
| Ask a person at or above | \$0.25 per call | `DATAFORSEO_APPROVAL_THRESHOLD_USD` |
| Refuse above | \$2 per call | `DATAFORSEO_MAX_CALL_USD` |
| Monthly budget | \$25 | `DATAFORSEO_MONTHLY_BUDGET_USD` |

Source: `src/engine/dataforseo.ts`

## Firecrawl

**Connects with** a pasted Firecrawl API key.

**Tools.** `mcp__firecrawl__firecrawl_account`, `mcp__firecrawl__firecrawl_scrape`,
`mcp__firecrawl__firecrawl_search`, `mcp__firecrawl__firecrawl_map`,
`mcp__firecrawl__firecrawl_crawl`. Firecrawl's browser interaction, monitors,
agent jobs and research tools are not built: monitors bill on a schedule that
outlives the session, and agent jobs cannot be priced in advance.

**Cost.** In Firecrawl credits, counted at \$0.002 per credit
(`FIRECRAWL_USD_PER_CREDIT`).

| Limit | Default | Variable |
| - | - | - |
| Ask a person at or above | 25 credits per call | `FIRECRAWL_APPROVAL_THRESHOLD_CREDITS` |
| Refuse above | 100 credits per call | `FIRECRAWL_MAX_CALL_CREDITS` |
| Monthly budget | 2000 credits | `FIRECRAWL_MONTHLY_BUDGET_CREDITS` |

Spend is counted against the credential, not the brand: brands sharing one
account's key share one monthly counter.

Source: `src/engine/firecrawl.ts`, `src/engine/credentials.ts`

## Google: Ads, Search Console, Analytics and Sheets

**Connects with** one Google sign-in per brand, through the deployment's own
OAuth client or through Nango when the operator configures `NANGO_SECRET_KEY`.
Google Ads also needs the operator's Google Ads developer token on the server.
The scopes asked for are Google Ads, Search Console read-only, Analytics
read-only, and `drive.file` (files this app creates).

### Google Ads

`mcp__googleads__googleads_accounts`, `mcp__googleads__googleads_report`,
`mcp__googleads__googleads_campaigns`, `mcp__googleads__googleads_search_terms`,
`mcp__googleads__googleads_account_hierarchy`, `mcp__googleads__googleads_compare_periods`,
`mcp__googleads__googleads_summarize`, `mcp__googleads__googleads_search_term_audit`.

Read-only **by what is built**: the Google Ads scope itself would allow
changes, and no tool makes one. Bids, budgets, campaign status,
recommendations, assets, users and billing are not built.

Daily caps on API operations: 2500 for the deployment (`GOOGLE_ADS_DAILY_OPS`)
and 300 per brand (`GOOGLE_ADS_DAILY_OPS_PER_TENANT`).

### Search Console

`mcp__searchconsole__searchconsole_properties`, `mcp__searchconsole__searchconsole_totals`,
`mcp__searchconsole__searchconsole_queries`, `mcp__searchconsole__searchconsole_pages`,
`mcp__searchconsole__searchconsole_breakdown`, `mcp__searchconsole__searchconsole_inspect_url`.
Read-only by scope.

### Google Analytics

`mcp__analytics__analytics_properties`, `mcp__analytics__analytics_use_property`,
`mcp__analytics__analytics_overview`, `mcp__analytics__analytics_trend`,
`mcp__analytics__analytics_traffic_sources`, `mcp__analytics__analytics_landing_pages`,
`mcp__analytics__analytics_report`. Read-only by scope.
`mcp__analytics__analytics_use_property` is not grantable to a coworker.

### Google Sheets

`mcp__sheets__sheets_list` lists sheets this app created.
`mcp__sheets__sheets_export` creates a new sheet and `mcp__sheets__sheets_append`
adds rows to one this app created. Both ask a person on every call and refuse
when nobody can be asked. Reading other files, deleting, sharing and
overwriting cells are not built.

Source: `src/engine/googleads.ts`, `src/engine/searchconsole.ts`, `src/engine/analytics.ts`, `src/engine/sheets.ts`

## Microsoft Ads

**Connects with** a sign-in through Nango. The deployment offers Microsoft Ads
only when the operator has set both `NANGO_SECRET_KEY` and
`MICROSOFT_ADS_DEVELOPER_TOKEN`; otherwise it is absent everywhere.

**Tools.** `mcp__microsoftads__microsoftads_accounts`,
`mcp__microsoftads__microsoftads_campaigns`,
`mcp__microsoftads__microsoftads_performance_report`,
`mcp__microsoftads__microsoftads_report_fetch`. Read-only.

Daily call caps: 200 per brand (`MICROSOFT_ADS_DAILY_CALLS_PER_TENANT`) and
2000 for the deployment (`MICROSOFT_ADS_DAILY_CALLS`).

Source: `src/engine/microsoftads.ts`

## Figma

**Connects with** a sign-in through Nango. The deployment offers Figma whenever
Nango is configured (`NANGO_SECRET_KEY`; the integration id defaults to `figma`,
override with `NANGO_FIGMA_INTEGRATION`). The brand keeps one value, its Nango
connection id; the token is read from Nango per call and never enters the
agent's sandbox.

**Tools.** `mcp__figma__figma_whoami`, `mcp__figma__figma_file_outline`, `mcp__figma__figma_read_nodes`, `mcp__figma__figma_export_images`, `mcp__figma__figma_comments`, `mcp__figma__figma_components_styles`, `mcp__figma__figma_team_projects`, `mcp__figma__figma_project_files`. Read-only: only Figma's six read
scopes are requested, so there is no write tool to withhold. Not built: posting
or deleting comments and reactions, variables, dev resources and webhooks, and
library analytics.

**Cost.** Figma's API is free, but it rations calls by the connected person's
seat. Reading a file, reading nodes and rendering images can be as few as about
20 calls a month on a View or Collab seat. Each tool result carries the
session's call count by tier, and a rate-limit refusal is explained rather than
retried. A specialist granted Figma draws from the same pool.

<Note>
  Figma has never been called from this code: every URL and response shape is
  read from Figma's and Nango's documentation (`FIGMA_UNVERIFIED`).
</Note>

Source: `src/engine/figma.ts` (`FIGMA_SCOPES`, `FIGMA_WITHHELD`, `FIGMA_UNVERIFIED`)

## GitHub

**Connects with** a pasted fine-grained personal access token.

**Read tools.** `mcp__github__github_read_file`, `mcp__github__github_list_path`,
`mcp__github__github_list_branches`, `mcp__github__github_list_issues`,
`mcp__github__github_read_issue`, `mcp__github__github_list_pull_requests`,
`mcp__github__github_read_pull_request`.

**Write tools.** `mcp__github__github_create_branch`, `mcp__github__github_commit_files`,
`mcp__github__github_open_pull_request`, `mcp__github__github_comment`. Each write
needs the operator's `GITHUB_ALLOW_WRITES` switch, a plain-sentence `intent`,
and a person approving that write. Without an approval channel every write
refuses; there is no fallback to the switch alone.

Refused in code even when approved: any commit to the repository's default
branch, and any file under `.github/workflows/`. Not built: merging, deleting,
force-pushing, settings, collaborators, secrets, and triggering workflows. The
agent's work ends at a pull request a person reviews and merges.

The token's own permissions at GitHub are a further limit nobody in Scout can
widen.

Source: `src/engine/github.ts` (`GITHUB_WITHHELD`, `preflight`)

## AgentMail

**Connects with** a pasted AgentMail API key and an inbox.

**Read tools.** `mcp__agentmail__agentmail_list_threads`, `mcp__agentmail__agentmail_search_threads`,
`mcp__agentmail__agentmail_get_thread`, `mcp__agentmail__agentmail_list_messages`,
`mcp__agentmail__agentmail_search_messages`, `mcp__agentmail__agentmail_get_message`,
`mcp__agentmail__agentmail_get_attachment`, `mcp__agentmail__agentmail_whoami`,
`mcp__agentmail__agentmail_list_drafts`, `mcp__agentmail__agentmail_get_draft`.

**Drafts.** `mcp__agentmail__agentmail_create_draft` writes a draft without
asking; nothing is sent.

**Sends.** `mcp__agentmail__agentmail_send_message`, `mcp__agentmail__agentmail_reply_to_message`,
`mcp__agentmail__agentmail_forward_message`, `mcp__agentmail__agentmail_send_draft`
exist only when `AGENTMAIL_ALLOW_SENDS` is exactly `true`, and each send asks a
person. A session with no one to ask cannot send, so no coworker can send mail.

Sends are capped at 200 recipients a month (`AGENTMAIL_MONTHLY_SEND_LIMIT`).
Deleting and creating inboxes, threads, drafts or messages is not built.

**Inbound email.** When the operator sets `AGENTMAIL_WEBHOOK_URL_SECRET`, mail
arriving in the inbox starts an unattended turn. See
[Tool permissions](/security/tool-permissions#inbound-email-turn) for what that
turn holds.

<Note>
  Creating a draft and receiving a webhook delivery are recorded as observed
  against the real service in `AGENTMAIL_CAPTURED`. A send is not.
</Note>

Source: `src/engine/agentmail.ts`, `src/engine/agentmail-inbound.ts`

## Cloudflare

**Connects with** one-click OAuth, or a pasted API token. Scout talks to
Cloudflare's own remote MCP server.

**Tools.** `mcp__cloudflare__docs` and `mcp__cloudflare__search` read
Cloudflare's documentation and API reference. `mcp__cloudflare__execute` calls
the Cloudflare API and can both read and change the account, so it asks a
person **on every call**, and it is absent when approvals are switched off.

Cloudflare is not grantable to a coworker.

<Note>
  The OAuth discovery, client registration and authorisation steps were
  observed on 2026-09-22 (`MCP_OAUTH_CAPTURED`). A full MCP handshake with a
  real account has not been (`CLOUDFLARE_UNVERIFIED.live_handshake`).
</Note>

Source: `src/engine/cloudflare.ts`, `src/engine/mcp-oauth.ts`

## Contentsquare

**Connects with** the brand pasting its Contentsquare MCP server address, then
signing in with OAuth.

**Tools.** Every tool that server offers, allowed by the pattern
`mcp__contentsquare__*`. The names are not known when Scout is built, so
Contentsquare is not grantable to a coworker.

<Warning>
  This code puts no approval gate on Contentsquare tools. Contentsquare's own
  description is that its server has no write tools; that is the vendor's
  claim, not something this code checks.
</Warning>

Source: `src/engine/contentsquare.ts` (`CONTENTSQUARE_TOOL_PATTERN`)

## Railway

**Connects with** "Login with Railway" (OAuth), or a pasted Railway token.

**Read tools.** `mcp__railway__railway_workspaces`, `mcp__railway__railway_project`,
`mcp__railway__railway_deployments`, `mcp__railway__railway_variable_names`,
`mcp__railway__railway_logs`. Variable **names** only; values are not read.

**Gated tools.** `mcp__railway__railway_reveal_variables` exists only with
`RAILWAY_ALLOW_VARIABLE_VALUES`, and `mcp__railway__railway_redeploy` only
with `RAILWAY_ALLOW_REDEPLOY` (`true`, `1` or `yes`), and either one only when
the session has an approval channel. Each call asks a person. A coworker never
holds them.

Not built: changing variables, creating or deleting services, projects,
domains or volumes, rollbacks, service settings, members, tokens and
networking.

<Note>
  No authenticated Railway request has been made from this connector
  (`RAILWAY_UNVERIFIED.live_calls`). Its response shapes are read from
  Railway's schema.
</Note>

Source: `src/engine/railway.ts`

## Browser

Not connected per brand: the operator configures it. Under E2B, browsing runs
in the sandbox when `SANDBOX_ALLOW_BROWSER` is exactly `true`. With
`BROWSER_PROVIDER` set to Browserbase, `BROWSERBASE_MONTHLY_MINUTES_LIMIT` is
required, and a per-brand share can be set with
`BROWSERBASE_TENANT_MONTHLY_MINUTES_LIMIT`.

**Tools.** `mcp__browser__browse_text` and `mcp__browser__browse_screenshot`.
With Browserbase and `BROWSERBASE_PERSISTENT_LOGINS` exactly `true`, also
`mcp__browser__list_logins`, `mcp__browser__start_login` and
`mcp__browser__finish_login`, which do not ask for approval.

The browser reads only. Clicking, typing, form filling, scripts, downloads,
PDFs and cookies are not built.

<Note>
  Browsing on E2B was exercised through the deployed app on 2026-08-26
  (`BROWSER_CAPTURED`). Browserbase has never been exercised from this code
  (`BROWSERBASE_UNVERIFIED`).
</Note>

Source: `src/engine/browser.ts`, `src/engine/browser-config.ts`, `src/engine/browser-tools.ts`

## Model accounts

Each brand adds its own model credentials under Settings: an Anthropic API
key, a Claude subscription token, or an OpenRouter key. A session uses the
backend its model route names and never falls back to another one, so a
missing key stops the session with a message rather than billing someone else.

Source: `src/engine/backends.ts`, `src/engine/credentials.ts`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.