tools()
Returns a resolver for the tools of every provider connected to a Mastra platform project. Pass it to an agent's tools option, and Mastra calls it on each generate() and stream(). The resolver caches the tools for ttlMs and starts a background refresh when called after the cache expires.
import { Agent } from '@mastra/core/agent'
import { tools } from '@mastra/connect'
export const opsAgent = new Agent({
id: 'ops',
name: 'ops',
instructions: 'You help the team track work in Linear and GitHub.',
model: 'openai/gpt-5-mini',
tools: tools(),
})
Returns: ToolsResolver, a resolver producing a flat tool record keyed by tool key (for example linear_create_issue). See The resolver.
See Connect to get started and Tools for usage.
ParametersDirect link to Parameters
options?:
projectId?:
providers?:
allowTools?:
disallowTools?:
requireApproval?:
client?:
ttlMs?:
Per-provider optionsDirect link to Per-provider options
Each value in the providers record form is true, false, or a ToolsProviderOptions:
connectionId?:
allowTools?:
disallowTools?:
requireApproval?:
ConnectClientOptionsDirect link to ConnectClientOptions
Every field falls back to an environment variable, so a fully env-configured app can pass nothing.
accessToken?:
orgId?:
baseUrl?:
fetch?:
The resolverDirect link to The resolver
The returned ToolsResolver caches its tools. Within ttlMs of the last fetch, it returns the cache. The first call after expiry still returns the cache right away and starts a background fetch from the platform (stale-while-revalidate). Later calls use the updated snapshot once the fetch succeeds. The resolver doesn't poll while idle, and refresh failures preserve the cached snapshot. Use await connected.refresh() to wait for a fresh tool record.
Call the resolver directly when you need a plain tool record, for example for the toolsets option at generate time:
import { tools } from '@mastra/connect'
const connected = tools()
const response = await agent.generate('Summarize my open issues.', {
toolsets: { connect: await connected() },
})
The resolver also exposes methods for manual control:
refresh()fetches from the platform immediately, then updates the cache and returns the tool record. Rejects if the platform fetch fails.disconnect()closes MCP transports owned by this resolver and clears its cached snapshot.with(extra)returns a new resolver that merges extra tools into every resolution; extras win on key collision. It accepts a static tool record or a function (sync or async) and calls chain. Spreading the resolver's result in atoolscallback achieves the same merge; see Tools.
Errors fall into four groups:
- Configuration errors (missing project ID or token, a malformed provider ID, both
allowToolsanddisallowToolsat one level, invalidttlMs) throw when you calltools(). - An enabled provider ID that the platform catalog confirms is unknown fails the resolution with
invalid_options. An unknown tool key or zero-match glob in a per-provider filter does the same. If the catalog can't be reached, an unknown ID downgrades to a warning and is skipped. - If a background refresh fails while a snapshot is cached, the resolver keeps serving the cached toolsets and warns. It rejects only when nothing was ever cached.
- A problem with one provider, such as a connection that needs reauthorization, logs a warning and skips that provider. The other providers' tools still load.
Choosing providersDirect link to Choosing providers
The providers array form is an allowlist: only listed providers are returned. Without the option, every connected provider with a supported toolset is included. A listed provider with no connection in the project yet is skipped and included automatically once a connection is attached. In the record form, false excludes a provider and never errors, even for IDs that match nothing.
Use an array to restrict discovery to named providers. A record configures named providers without excluding the others:
const onlyLinear = tools({ providers: ['linear'] })
const allWithLinearApproval = tools({
providers: { linear: { requireApproval: true } },
})
Tool keys for allowTools and disallowTools are listed per provider in the provider toolsets reference.
Connection resolutionDirect link to Connection resolution
For each provider present in the project's connections:
- An explicit
connectionIdoption wins. - Otherwise, a single active connection is used automatically.
- Otherwise the provider is left unpinned and routed per call: the toolset gains a
<provider>__list_connectionstool, every other tool takes a requiredconnection_nameinput, and the agent picks a connection per call using the display nameslist_connectionsreturns. Aconnection_namethat matches no active connection fails that call withunknown_connection.
The synthetic list_connections helper doesn't require approval and remains available even when top-level allowTools or disallowTools filters would exclude it.
Connections in needs_reauth status are skipped with a warning until someone replaces them.
MCP providersDirect link to MCP providers
Beyond the generated toolsets, the resolver discovers any connected provider that advertises MCP capability in the platform catalog. Discovered tools use the same flat contract, namespaced as <provider-id>_<tool-name>. If a provider has both a generated toolset and an MCP capability, the MCP catalog is preferred.
The application sends only its platform token; the platform removes caller authentication before injecting the provider credential and proxying each protocol request to the provider's MCP server. MCP sessions are reused across refreshes and closed when the connection changes, the provider is detached, or disconnect() is called.
Discovered MCP tools follow the same approval policy as generated tools: none require approval unless requireApproval asks for it, for example 'neon-mcp': { requireApproval: ['neon-mcp_run_sql'] }. Passing the removed autoApproveTools key throws an invalid_options error at call time.
Environment variablesDirect link to Environment variables
tools(), channels(), and credential() read these environment variables. Options passed in code take precedence.
| Variable | Purpose |
|---|---|
MASTRA_PLATFORM_ACCESS_TOKEN | Platform access token used to authenticate every request |
MASTRA_PLATFORM_SECRET_KEY | Fallback token when MASTRA_PLATFORM_ACCESS_TOKEN is unset |
MASTRA_PROJECT_ID | Project whose connections to use |
MASTRA_ORG_ID | Organization ID, sent as the x-organization-id header when set |
MASTRA_PLATFORM_REGION | us or eu. Selects https://integrations.us.mastra.ai or https://integrations.eu.mastra.ai instead of the default https://integrations.mastra.ai |
MASTRA_INTEGRATIONS_API_URL | Connect API base URL. Overrides the region |
ErrorsDirect link to Errors
Throws MastraConnectError with a code property:
| Code | When |
|---|---|
missing_project_id | No project ID configured |
missing_access_token | No platform token configured |
invalid_options | Unknown or malformed provider ID, conflicting filters, duplicate or unmatched tool keys or globs, or invalid ttlMs |
unauthorized | The platform rejected the token (401/403) |
proxy_error | A proxied provider request failed, with status and detail carrying the provider response |
unknown_connection | A tool call supplied a connection_name that matches no active connection |
platform_error | Any other platform request failure |