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_emailsorsalesforce__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.
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 withgmail__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 anhttps://origin. The TypeScript client and the CLI refuse any other scheme; only the rawcurlexamples can reach a loopbackhttp://localhostorigin.
curl and jq and share these variables. The first line
keeps an API origin you already exported:
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’sname, 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:
veryfront integration tools gmail --project "$VERYFRONT_PROJECT" --json.
Connect the provider account
The first call without a connection returns a tool result withisError: 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--timeoutseconds (default 300), and confirms the new connection from inventory. Add--scope projectto create a shared connection instead of a personal one. - REST: Call the tool without a connection selector, as shown below, and
open
connectUrlin a browser that is signed in to Veryfront. - Studio: Use the connect card that appears in the run, or the project’s integration settings.
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:
Select the connection and check readiness
Read the project’s Gmail connections. Each row has anid, a scope (user or
project), a status (connected, expired, or disconnected), and a
connection_generation_id that changes when the account is reconnected:
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:
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 inarguments. 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. Theintegration 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:
.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:
first-call.ts in that directory and run it:
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 yourveryfront 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:
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: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:Narrow capabilities in source configuration
veryfront.config.ts can apply an optional allowlist to every agent running
from that exact source target:
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.
Authentication flow
When an agent calls an OAuth integration tool and no valid connection exists:- The tool returns an
authentication_requiredresult with a connect URL. - The agent surfaces the connect action to the user.
- The user completes provider consent and the OAuth callback.
- The control plane stores the connection for the selected project or user scope.
- The run calls the tool again with the new connection. This is safe because
authentication_requiredmeans no provider request was sent. - Later calls reuse or refresh that connection according to the provider’s token lifecycle.
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:Credential-based integrations
Some connectors use static credentials instead of interactive OAuth. Store those credentials in project environment variables named by the connector metadata: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
Eachveryfront 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, andteams. - Experimental.
VERYFRONT_EXPERIMENTAL_INTEGRATIONSenables other declared connectors. Set it to a comma-separated list such asstripe,adyen, or toall. - Host adapter.
box,clickup,freshdesk,intercom,mailchimp,monday,pipedrive,quickbooks,salesforce,shopify,trello, andxeroneed a provider adapter. The experimental flag never enables them, includingall. A host that drives one with its own client names it inVERYFRONT_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
- Confirm the integration tool name is present in the agent source.
- Start a new agent run and request an action that uses the tool.
- If an OAuth connection is absent, complete the connect action and callback.
- Confirm the next tool call receives a result with
isErrorunset orfalse. - Reload the project and confirm connection inventory still reports the connection independently of agent source and source configuration.
Next
- Recover integration connections
- Integration credentials and scopes
- Set up GitHub
- Set up Jira
- Set up Salesforce
Related
- veryfront/integrations: Connector catalog and helper API.