Skip to main content
The Assistant is the workflow-independent agentic chat: it searches your connected integrations, picks an action, and runs it with your organization’s credentials — no workflow graph required. This page is the technical reference for the tool side of that loop: the tools the Assistant has, the parameters and outputs of each, the approval behavior, how it asks for a missing credential over human-in-the-loop, and the credit impact of every call. For the surrounding agentic loop (reason → act → observe → finish), see How the Assistant works. For pause-and-resume mechanics shared by every interrupt the Assistant raises, see Human-in-the-loop. To connect the integrations the Assistant calls, start at Integrations overview.
The Assistant runs the assistant profile of the shared agent core. It has no workflow tools at all — it cannot list, build, run, or edit a workflow. Every tool below is scoped to discovering integrations, calling integration actions, retrieving knowledge, and asking you questions.

The Assistant’s toolset

The Assistant is handed a fixed set of tools at run start. There are three discovery tools, one execution tool, one knowledge tool, and the human-in-the-loop tools (one of which is request_credential). The discovery tools and execution tool together form a deliberate two-step pattern: the Assistant first narrows the catalog, then pulls the exact parameter schema for the action it chose, then executes. The sections below document each in turn.

Tool discovery

Browse the catalog — get_available_integrations

The first discovery step returns a compact index of everything the organization could connect, so the full portfolio fits in the agent’s context without bloating it. For tools you get the integration name, a short description, categories, and action names only — no per-action descriptions or parameter schemas at this step.
string
default:"all"
One of tools, llm_providers, knowledge_providers, or all. Filters which catalog segment is returned.
string
Optional case-insensitive substring filter. It matches name, display name, description, category, and action name. A narrow query (for example query="slack") keeps the response small without risking that a relevant integration is dropped — filtering is exact-substring, not lossy truncation.
The response groups results by segment. Tool entries carry action names only; you must call get_integration_details for the parameter schema before you can configure a call.
object[]
object[]
Each entry adds a models list of {id, display_name, max_output_tokens}. See LLM providers.
object[]
Each entry carries name, display_name, description, and categories. See Knowledge providers.

Read an integration’s actions — get_integration_details

The second discovery step. Call it after choosing an integration to get the parameter schemas you need to actually configure an action.
string
required
The integration name, for example tavily, firecrawl, or github.
string
Optional. Restrict the response to a single action to keep it small. An unknown action returns {error: "Action '<name>' not found in <integration>"}.
For a tool integration, each action returns its name, a description (truncated to 300 characters), and a parameters array. Each parameter carries name, type, required, description, and — when defined in the manifest — enum and default:
Example: get_integration_details("github", "create_issue")
An unknown integration returns {error: "Integration '<name>' not found"}. The parameter type is one of string, integer, number, boolean, array, or object — the same types the manifest schema defines.

See existing credentials — get_organization_credentials

The Assistant uses this to decide whether it already has a way to authenticate before it calls an action. It returns only safe fields — never a token, key, or secret.
string
Optional. Return only credentials for this integration (for example slack). Pass it when the Assistant already knows which integration it needs so the response stays small.
object[]

Calling a tool

execute_integration_tool

This is the only tool that performs a real action. The Assistant calls it with the integration id and action name it discovered, plus the action parameters. It runs exactly one action per call.
string
required
Catalog integration id, for example github.
string
required
The action/service name, for example list_repositories.
object
default:"{}"
The action parameters, matching the schema from get_integration_details. Never include credentials or tokens — the runtime injects them automatically from the organization’s credential. Credential fields such as api_key, token, access_token, bearer_token, auth_type, and auth_data are stripped from the schema the Assistant sees, so it cannot supply them even if it tries.
Internally, the call resolves a credential, decrypts it, refreshes an OAuth token if it is within five minutes of expiry, maps the parameters, invokes the underlying action, and returns the raw action output. Credential selection follows a fixed precedence: an explicit credential, then the integration’s default credential, then the most recent valid credential — preferring your own credentials over managed ones. See Credentials & OAuth2 for the full resolution rules.

Return shape

execute_integration_tool always returns a dict with a status field. It does not raise to the agent — every failure is converted to a structured status the Assistant can react to mid-stream.
string
required
One of ok, cancelled, needs_credential, credit_limit, or error.
string
Echoes the requested integration.
string
Echoes the requested action.
object
Present when status is ok. The raw action output (a dict, list, or string), truncated to 8000 characters before it re-enters the agent loop. The credential and execution envelope around the action are stripped — the Assistant sees only the bare action result.
string
Present for needs_credential and credit_limit — a human-readable explanation the Assistant can act on (for example, “call request_credential, then retry”).
string
Present for cancelled (the user declined an approval) and credit_limit (the stable token credit_exhausted).
string
Present when status is error — the failure text, truncated to 500 characters.
status: ok
enum

The approval gate — reads run, destructive actions pause

The Assistant applies a safety gate (not an authorization gate — your org membership already authorizes the call) before it executes. The policy differs from the AI Composer in the builder, and the difference matters:
On the Assistant surface, only catastrophic actions pause for approval. Actions whose names contain delete_, _delete, drop_, truncate, purge, destroy, wipe, or raw query execution (execute_query, execute_statement, execute_raw_query, raw_query) always require your explicit yes/no. Everything else — including ordinary creates and sends, like posting a Slack message or creating a Linear issue — runs immediately. The Assistant is a “just do what I asked” surface; asking before every write is impractical. The Composer in the builder is stricter: it default-denies every write or unknown action against a frozen read-action allowlist.
When a destructive action is gated, the Assistant raises a yes/no human-in-the-loop interrupt with a redacted preview of the parameters (secret-looking keys are masked). If you answer no, the call returns status: cancelled and the action never runs.

Credential requests over human-in-the-loop

When execute_integration_tool returns needs_credential, the Assistant calls request_credential to ask you to connect the integration. This raises a credential interrupt: the run pauses, the app renders a connect popup, and the Assistant resumes once you finish.

request_credential

string
required
Canonical integration slug, for example slack or google_drive. Used to resolve OAuth and credential storage.
string
required
Human-readable name shown in the popup header, for example Slack.
object[]
required
One entry per auth type you can choose. At least one is required. Each matches the CredentialAuthOption schema below.
Optional URL to the integration’s logo for the popup.
string
Optional. Reserved for the workflow context and not used by the Assistant (Assistant chats are never workflow-bound).
boolean
default:"false"
When false (the default for the Assistant), the popup shows an inline “Skip for now” button so you can defer connecting. Set true only when the task truly cannot proceed without the credential.
object
Optional rendering hints for the app.
Each entry in auth_options is a CredentialAuthOption:
string
required
One of oauth2, api_key, bearer_token, modulex_key, custom.
string
required
The button label inside the popup.
object[]
Form-field definitions for form-based auth types such as api_key.
string
The full URL the app opens to start the OAuth flow. Required when auth_type is oauth2 — an OAuth option without it is rejected before the interrupt fires.
string[]
Optional human-readable setup steps shown beside the form or OAuth button.
boolean
default:"false"
When true, the new credential is round-trip tested before the Assistant resumes, so an invalid credential surfaces as a structured failure instead of sending the Assistant down a broken path.

How you respond, and how the run resumes

You answer a credential request in one of three ways, and the Assistant resumes with that result baked into the tool response:
1

You connect the integration

You complete the OAuth popup or fill the form. The credential is persisted and the run resumes with kind: "credential_added" carrying the new credential_id, integration_name, and auth_type. The Assistant retries the original action.
2

The connection fails

The run resumes with kind: "credential_failed" carrying an error_code — one of oauth_denied, oauth_provider_error, invalid_credentials, network_error, popup_closed, timeout, or unknown — plus a retryable flag. The Assistant can try a different auth option or report the failure.
3

You skip

When the request was not required, the inline “Skip for now” button resumes the run with kind: "skipped". The Assistant proceeds without the credential.
OAuth auto-resume. When you complete an OAuth flow that the Assistant opened, the OAuth callback resumes the chat automatically — you do not make a separate resume call. The callback re-runs the same ownership checks and continues the run, swapping your live stream to the new run id. See Human-in-the-loop for the resume contract and stream handover.
Reconnect, do not rely on token refresh. The manual OAuth token-refresh path (POST /credentials/{credential_id}/oauth2/refresh, and the equivalent UI refreshOAuth2 action) is currently broken and must not be treated as a working flow. ModuleX still refreshes OAuth tokens automatically during tool execution when a token is within five minutes of expiry. If a credential has fully expired or its refresh token is no longer valid, reconnect the integration — run the connect flow again to mint a fresh credential — rather than calling the manual refresh. This is tracked in Known limitations.

BYOK vs managed credentials

Every integration call resolves to one of two kinds of credential, and the kind decides who you pay and whether the call counts against your credits.

BYOK — your own credentials

You connect your own provider account (OAuth, API key, or bearer token). Usage is billed directly by the provider with no ModuleX markup. BYOK tool calls are not credit-limited — they are tracked for analytics only, never gated on credits.

Managed — `modulex_key`

ModuleX provides a pooled, system-managed key (auth_type: modulex_key) so you can call a tool without bringing your own account. Managed usage is billed in credits and is subject to your plan’s monthly credit ceiling. On the wire the managed provider is modulexai for tools and LLMs, and modulexdb for managed knowledge.
When both exist, resolution prefers your own credential over the managed key. So if you connect your own GitHub account, the Assistant uses it (no credits), and only falls back to a managed key when you have not connected your own.

Credit impact of a tool call

A managed tool call is metered with a per-action soft cost: The credit check runs only for managed (modulex_key) credentials: if the plan’s monthly budget is exhausted and no wallet overage is available, the call returns status: credit_limit with reason: credit_exhausted. Plans with no monthly ceiling (for example Enterprise) are never blocked here. See Credits & metering and Usage gating & limits for the full model.
The Assistant turn itself is also metered separately from the tool. Each user message charges one run credit per turn and is admitted through the billing gate before any work starts. That gate, and the LLM token usage it records, are documented in Permissions & limits and Usage gating & limits.

Errors and denials

The Assistant’s tools surface failures in two distinct places — and they look different. Tool-level results. execute_integration_tool never raises to the agent; it returns a status. Treat needs_credential, credit_limit, cancelled, and error as normal control flow the Assistant handles itself. Turn-level denials. The Assistant endpoint that starts a turn is on the billing gate. A denial there is not the {detail} shape — it is the flat DenialEnvelope:
DenialEnvelope (HTTP 402 429)
The layer maps to a status: rate429 (with Retry-After and X-RateLimit-* headers), quota403, and credit or wallet402. This is one of the four error envelopes ModuleX returns, and it is emitted on the run, Composer, Assistant, and managed-knowledge surfaces only — plain CRUD routes use the {detail} shape. See Errors & status codes and Rate limiting.

A worked example: list, then create

This shows the full sequence the Assistant runs to satisfy “create a GitHub issue titled ‘Bug’ in octocat/hello-world”, calling the API directly. Authenticate every request with Authorization: Bearer mx_live_… and X-Organization-ID — see Authentication. Owner or admin role is required for the Assistant; the retired member role cannot use it (see Roles & permissions).
1

Start the turn

Post the user message. The response returns the chat id, the run id, and the SSE stream_url to open for live events. The operation is shown once below as cURL, Python, and JavaScript.
2

The Assistant discovers and reads the action

Over the stream you see the Assistant call get_available_integrations (with query="github") and then get_integration_details("github", "create_issue") to read the parameter schema. These are read-only and never pause.
3

The Assistant executes

The Assistant calls execute_integration_tool with the action and parameters. Because create_issue is not destructive, it runs immediately on the Assistant surface — no approval prompt. The tool result arrives in the stream:
tool_result
Had no GitHub credential existed, the result would instead be {"status": "needs_credential", ...}, and the Assistant would call request_credential and pause — see the resume steps under Human-in-the-loop.

Human-in-the-loop

The pause-and-resume contract behind credential requests and approvals.

Integrations overview

Connect the services the Assistant calls and manage their credentials.

How the Assistant works

The agentic loop that decides when to discover, call a tool, and finish.

Permissions & limits

Who can use the Assistant and the billing and usage limits that apply.