Skip to main content
Veryfront integrations let applications and agents call third-party services on behalf of users. An integration has four parts: a catalog, a connection, tools, and transport surfaces.

The four parts

  • Catalog: Provider metadata, setup requirements, available tools, input schemas, and side-effect information.
  • Connection: The authenticated provider account used by managed execution. A connection can be personal to a user or shared with a project. Local connector credentials are resolved by the host for account-free execution and are not recorded in connection inventory.
  • Tools: Provider operations such as gmail__list_emails or salesforce__find_customer. The catalog defines their names and schemas; managed connections supply provider access, while local tools use host- resolved credentials.
  • Transport: REST, GraphQL, MCP, the TypeScript client, and the Veryfront CLI all call the same hosted tools. REST, the TypeScript client, and the CLI also read connection inventory and start OAuth. GraphQL and MCP discover and call tools but do not list connections.
The hosted API flow is discover → connect → status → call. No integration policy setup is required. Every surface can select an exact connection when a project has multiple accessible accounts. Framework tool calls inside an agent run use the connection selected by the hosted runtime, and a connection_id passed inside tool arguments is provider input rather than an account selector.

Make your first call

This walkthrough reads one Gmail message summary with gmail__list_emails and the arguments {"q":"in:inbox","maxResults":1}. Each surface below runs the same tool with the same arguments against the same connection, so you can pick the one that fits your application. The tool is read-only. For other failures and non-OAuth connectors, see Recover integration connections and Integration credentials and scopes.

Before you start

You need three things. None of them is created implicitly:
  • A platform credential. A Veryfront API key or login token for a user who can read the project. It authenticates you to Veryfront, not to Gmail. Keep it server-side and never place it in prompts, tool arguments, or URLs.
  • A project. Pass the project slug or UUID on every request. Veryfront never picks a project for you.
  • The API origin. Use https://api.veryfront.com, or your own API origin for a self-hosted or non-production deployment. Every request carries the platform credential, so use an https:// origin. The TypeScript client and the CLI refuse any other scheme; only the raw curl examples can reach a loopback http://localhost origin.
The shell examples use curl and jq and share these variables. The first line keeps an API origin you already exported:
The TypeScript client and the CLI refuse API origins that resolve to private network addresses, such as a VPN or self-hosted API. On a host you control, set VERYFRONT_HOST_ALLOW_INTERNAL_EGRESS=1 in the process environment to allow them. Project environment variables cannot set it.

Discover the tool

Tool discovery works before any connection exists. The response lists each tool’s name, description, and inputSchema. Its x-veryfront-project-id header carries the project UUID that Veryfront resolved from the slug; the second command keeps it for the call precondition:
The CLI equivalent is veryfront integration tools gmail --project "$VERYFRONT_PROJECT" --json.

Connect the provider account

The first call without a connection returns a tool result with isError: true, structuredContent.error set to authentication_required, and a structuredContent.connectUrl. No provider request is sent. Provider consent is a separate login to Gmail and always needs a person in a browser:
  • CLI: Run veryfront integration connect gmail --project "$VERYFRONT_PROJECT". It opens the browser, waits at most --timeout seconds (default 300), and confirms the new connection from inventory. Add --scope project to create a shared connection instead of a personal one.
  • REST: Call the tool without a connection selector, as shown below, and open connectUrl in a browser that is signed in to Veryfront.
  • Studio: Use the connect card that appears in the run, or the project’s integration settings.
The REST call below keeps connectUrl only when the result is authentication_required. If an accessible account is already connected, the call runs the read instead and CONNECT_URL stays empty. The URL is single-use and expires, so do not log or share it:
The call is not retried for you. After consent, read the connection inventory and call again. If consent is denied, cancelled, or expires, see Recover integration connections.

Select the connection and check readiness

Read the project’s Gmail connections. Each row has an id, a scope (user or project), a status (connected, expired, or disconnected), and a connection_generation_id that changes when the account is reconnected:
The inventory is paginated. While page_info.next is not null, repeat the request with cursor set to that value, so that you see every row before you choose. veryfront integration connections and the TypeScript client follow every page for you. Copy the id and connection_generation_id of the connected row you want to use:
Readiness reports whether that selection can run the tool. It reads metadata only and never contacts Gmail:
Continue when selection is selected and local is eligible. A stale selection means the account was reconnected after you read inventory: read inventory again rather than choosing another account.

Call with REST

Send provider arguments in arguments. connection_id selects the account and expected_connection_generation_id rejects the call before any provider request if that account was replaced. x-veryfront-expected-project-id rejects the call if the slug now resolves to a different project. All three are optional in the API, but keep them: they make the call fail instead of running against an account, generation, or project you did not inspect.

Call with GraphQL

GraphQL has no connection inventory; take the IDs from the REST inventory or the CLI. The integration query returns the tool list and readiness, and the executeIntegrationTool mutation runs the tool. projectReference accepts the slug or UUID:
executeIntegrationTool is a mutation because it can run write tools. A read-only tool needs only read access to the project. Tool failures return isError: true; request failures such as a stale generation return GraphQL errors.

Call with TypeScript

createIntegrationClient from veryfront/integrations takes every credential explicitly and never reads them from the environment. It sends the project precondition headers for you. Replace the placeholders with the same values as the shell variables:
To run the script with Node.js 22.18+, 23.6+ or 24 and later, which run .ts files without flags, create an ES module project. Recent npm versions write "type": "commonjs" in npm init -y, and Node then rejects the script’s import with SyntaxError: Cannot use import statement outside a module:
Save the script as first-call.ts in that directory and run it:
If you keep the project as CommonJS, name the file first-call.mts and run node first-call.mts instead. With Deno, run deno run --allow-net first-call.ts from the same directory. client.connect("gmail", { redirectUri }) starts the same OAuth handoff as the CLI and returns a one-time connect_url with an expires_at deadline.

Call with the CLI

The CLI uses your veryfront login session or VERYFRONT_API_TOKEN, and VERYFRONT_API_URL when it is set in your shell:
--expected-generation requires --connection. status --tool rejects --scope because the selected connection determines its scope.

Call with MCP

Point MCP clients at the project endpoint /projects/<PROJECT_SLUG>/mcp. The unscoped /mcp endpoint serves platform tools but cannot call integration tools because it has no project. Integration tools are listed by their canonical names. Select a connection with _meta, not with tool arguments. The example requests protocol revision 2025-11-25, which the API supports, and sends it as MCP-Protocol-Version on every request. When initialize returns an Mcp-Session-Id header, send it on later requests, and send notifications/initialized before other requests:
An MCP client configuration uses the same URL and bearer token:

Read the result

Every surface carries the same native tool result: content, structuredContent, isError, and optional _meta. For gmail__list_emails, structuredContent has messages, pagination, and summary. Each surface places that result at a different path: A tool failure keeps the native result and sets isError: true, with a code in structuredContent.error: Selection and precondition failures, such as a stale generation or a connection that belongs to another project, are request errors: REST returns an HTTP problem, GraphQL returns errors, and MCP returns an isError result with _meta.condition.slug. They fail before credentials are read. See Recover integration connections for each case.

Connection generation preconditions

local_eligibility.state === "eligible" means the evaluated local metadata checks passed. It does not establish provider permission. Key presence cannot prove usable credential values, and recorded shared-account metadata is not provider-verified identity. Inspect pending_checks and blockers; provider_verification.state remains not_checked. A later tool call still requires current authorization. A reconnect can replace a generation between inventory and execution. The API rejects a mismatched generation before reading credentials or calling the provider. A generation match does not establish provider permission or prevent a later provider-side revocation. The selected account and generation are metadata, not a reusable grant. The TypeScript client requires the API deployment to advertise generation precondition support in x-veryfront-tool-preconditions. If it does not, the client throws IntegrationApiError with kind === "unsupported_precondition" and outcomeUnknown === false before sending the call. If support is no longer confirmed on a successful call response, the error has outcomeUnknown === true: the operation may already have run. Inspect the provider outcome before retrying. The client never automatically replays the call. A missing or malformed readiness projection, or a response for another project, tool, or connection, throws IntegrationApiError with kind === "invalid_response". Changing project or platform credentials requires a new bound client. See the integration API reference for the public types.

Run account-free local integration tools

Use the catalog-backed local source to call supported REST integrations from a local or self-hosted project without a Veryfront account or project token:
The exact canonical IDs passed to tools are the source’s capability grant. Source configuration is monotonic. It is source-qualified and monotonic: integrations.allow only narrows that grant when the source runs inside a Veryfront project runtime. It never enables another tool or selects a credential. The runtime resolves each credential immediately before the request and never sends local credentials to Veryfront, the model, tool arguments, logs, or request URLs. The host must explicitly allow local credential use. Set VERYFRONT_HOST_ALLOW_LOCAL_INTEGRATION_CREDENTIALS=1 on a local or dedicated self-hosted runtime. Leave it unset on shared, hosted, and proxy runtimes. Project environment variables cannot grant this host-owned capability. Veryfront does not infer the deployment shape. Setting the exact host variable authorizes local credential use for the current non-proxy process. By default, the source reads the credential environment variables declared by the connector catalog from the active project environment. An application can instead pass a credentialProvider that resolves those names from its own secret manager. The provider receives credential names only. This first local execution path supports fixed HTTPS REST endpoints with header API keys, Basic authentication, OAuth 2.0 client credentials, and the Salesforce service-account specialization. It rejects authorization-code OAuth, query-string credentials, GraphQL, response enrichment, multipart bodies, raw bodies, dynamic endpoint origins, and tools outside the exact grant. Use managed execution for per-user OAuth and other unsupported connector features.

Prerequisites for agent tools

  • A Veryfront project with a configured agent (see Agents).
  • The integration tool names the agent needs.
  • For managed execution, a project token or hosted runtime that can reach the Veryfront integration tool endpoints.
  • For local execution, provider credentials in the project environment.
  • Project environment credentials only for static-credential connectors or an explicitly selected custom OAuth app override (see OAuth).

Declare agent tool access

List integration tools alongside the agent’s other tools:
The agent source is the capability declaration. Its tool list determines which remote integration tools the agent can call. Removing a tool from agent source removes it from that agent without changing connections or credentials.

Narrow capabilities in source configuration

veryfront.config.ts can apply an optional allowlist to every agent running from that exact source target:
Omitting integrations applies no source-level restriction. An empty integrations.allow map denies every integration tool while leaving local project tools unchanged. A listed integration with no allowedTools value keeps all of its tools eligible; an empty array keeps none. Integration keys must be canonical connector names, and tool entries are exact connector-local IDs. The integration__tool namespace is reserved for integration tools, so restricted runs treat every name in that namespace as an integration even when the running framework build does not yet know its connector. This source configuration is local capability selection. The runtime loads it from the same branch, release, or environment as the agent and intersects it with the agent declaration and connector catalog. It cannot enable an integration, select a credential scope, create a connection, or grant access to an account. The removed scope, perUser, and tools fields are rejected rather than normalized or silently ignored. Source configuration intentionally has no credential, provider-configuration, or execution-mode fields. The project runtime establishes this restriction once per request. Direct agent.generate, agent.stream, and agent.respond calls made by project routes inherit it, as do AG-UI handlers and in-process agent delegation. Hosted or durable child processes receive the already-narrowed manifest explicitly at their execution boundary. A standalone agent() invoked outside a Veryfront project runtime has no project source configuration to load.

Connection state

There is no project integration policy or policy setup step. These are the independent contracts:
  • Agent source controls which tools belong to an agent.
  • Source configuration can narrow integrations and tools for an exact source target.
  • Connection inventory records which project or user has authenticated.
The agent source and source configuration select eligible tools from the catalog. Managed OAuth tools additionally require an authenticated connection to run. Local static-credential tools resolve their credentials from the host environment or credential provider and do not use connection inventory. Adding a tool does not create a connection. Connecting OAuth does not rewrite agent source or source configuration. If a project has several accessible accounts, a REST, GraphQL, MCP, TypeScript client, or CLI call can select an exact connection; Veryfront validates that it belongs to the project and is visible to the caller, and never falls back to another account. Framework tool calls use the runtime-selected connection.

Authentication flow

When an agent calls an OAuth integration tool and no valid connection exists:
  1. The tool returns an authentication_required result with a connect URL.
  2. The agent surfaces the connect action to the user.
  3. The user completes provider consent and the OAuth callback.
  4. The control plane stores the connection for the selected project or user scope.
  5. The run calls the tool again with the new connection. This is safe because authentication_required means no provider request was sent.
  6. Later calls reuse or refresh that connection according to the provider’s token lifecycle.
OAuth connection happens during use. Adding a tool to agent source does not require a connection in advance. A call that failed with any other error is not retried automatically. See Recover integration connections.

Managed OAuth and custom app overrides

Managed OAuth connectors do not require project OAuth client credentials. Set client ID and client secret environment variables only when the connector supports and the project selects a custom OAuth app override:
The integration catalog metadata identifies these variables as OAuth client overrides and reports whether managed OAuth is available.

Credential-based integrations

Some connectors use static credentials instead of interactive OAuth. Store those credentials in project environment variables named by the connector metadata:
No OAuth connect step is shown for these connectors. The integration runtime resolves their credentials during tool execution; agents do not receive raw secrets. See Integration credentials and scopes for the setup of each authentication type and where each one runs.

Test without provider access

Keep local tests and evals provider-free by supplying explicit mock tools. The mock map replaces the live integration for that run; it does not create a connection or change hosted behavior. See mock tools for local evals.

Set up a provider

Use a provider guide when a connector needs provider-specific installation, permissions, OAuth configuration, or service-account credentials. For credential types, scopes, and recovery that apply to every provider, see Integration credentials and scopes and Recover integration connections.

Available integrations

The built-in connector catalog contains 205 connectors. Whether you can use one depends on three availability states. Each state narrows the one before it.

Package-declared

Each veryfront release declares a fixed set of connector names. A declared name is not visible until the environment enables it.

Environment-enabled

A declared connector is enabled in one of three ways:
  • Default. The supported set is enabled everywhere: airtable, asana, calendar, confluence, docs-google, drive, figma, github, gitlab, gmail, harvest, hubspot, jira, linear, notion, onedrive, outlook, sentry, sharepoint, sheets, slack, and teams.
  • Experimental. VERYFRONT_EXPERIMENTAL_INTEGRATIONS enables other declared connectors. Set it to a comma-separated list such as stripe,adyen, or to all.
  • Host adapter. box, clickup, freshdesk, intercom, mailchimp, monday, pipedrive, quickbooks, salesforce, shopify, trello, and xero need a provider adapter. The experimental flag never enables them, including all. A host that drives one with its own client names it in VERYFRONT_HOST_ADAPTER_INTEGRATIONS, which exposes the connector definitions for catalog lookup only. Scaffolding still refuses them, because generated routes run on the generic runtime.

Hosted and local limits

Qualification record

Unit tests exercise the header, Basic, and client-credential wiring against fixtures. Fixture coverage shows the request is built correctly; it does not qualify a provider. A connector counts as operationally qualified only when a representative read has run against the real provider on a recorded release. Every other connector is package-declared and, where enabled, environment-enabled, but not operationally qualified. Use the generated integration metadata reference when you need exact exported names or icon metadata:

Verify it worked

  1. Confirm the integration tool name is present in the agent source.
  2. Start a new agent run and request an action that uses the tool.
  3. If an OAuth connection is absent, complete the connect action and callback.
  4. Confirm the next tool call receives a result with isError unset or false.
  5. Reload the project and confirm connection inventory still reports the connection independently of agent source and source configuration.

Next