Skip to content

Connected apps and actions ​

Configure provides app tools through the user's MCP session. The user authorizes an app through the hosted flow. Your agent can then call its tools without a separate OAuth integration for that app. This guide lists available tools, access restrictions, and action approval requirements.

The tools ​

A user's MCP session has seventeen tools: configure_connect, eight profile tools, and the eight connected-app tools below. Every session lists all of them, whether or not the user connected the app. If the user has not authorized a tool, the call is denied and returns a connection URL.

ReadsChanges external state
configure_gmail_searchconfigure_email_send
configure_calendar_getconfigure_calendar_create_event
configure_drive_search
configure_notion_search
configure_sheets_search, configure_sheets_read

These tools are on the SDK and REST only, not on the MCP session:

  • configure_email_search, which searches Gmail and Outlook together.
  • The Sheets writes: configure_sheets_values_update, configure_sheets_values_append, configure_sheets_create_spreadsheet, and configure_sheets_add_sheet.

On the SDK path, profile.tools() returns 14. It leaves out configure_profile_commit and configure_project_share, which the MCP session carries. These are always included: configure_profile_read, configure_profile_search, configure_profile_remember, configure_profile_forget, configure_profile_import, and configure_connect.

Scope what your agent may do ​

On the Quickstart path, the model gets these tools through the MCP session (step 7) and calls them itself. The session sets the scope. A tool call without user authorization is denied and returns a connection URL.

You can also run the calls yourself. Use a handle that carries the user's own token, from Sign in with Configure. Then you choose which tools the model sees:

ts
import { Configure } from "configure";
const configure = new Configure({ apiKey: process.env.CONFIGURE_API_KEY, agent: process.env.CONFIGURE_AGENT });
const profile = configure.profile({ token: session.token });   // the user's token, not your externalId

const tools = profile.tools({
  connectors: ["gmail", "calendar"],       // reads to expose
  actions: ["calendar.create_event"],      // state-changing tools to expose; [] for none
});

// Hand `tools` to the model (Anthropic shape; toOpenAIFunctions(tools) for OpenAI),
// then run whatever it calls:
const result = await profile.executeTool(call);

A tool outside the set is refused with ACCESS_DENIED before any request leaves your server. On a profile keyed by externalId, executeTool serves only the profile tools. It answers connector calls with authorization_required and a link. Reach connected apps through the session instead.

Handle authorization errors ​

Authorization errors depend on the credential used to create the profile handle. Token-based handles throw an error. Handles based on externalId return an authorization response.

On a profile keyed by token, a connector the user has not connected, or whose access expired, throws a ConfigureError with code: "TOOL_NOT_CONNECTED". suggestedAction is "connect_tool" for an app the user never connected and "reconnect" for one whose access expired. There is no connect_url on that error. Create one with profile.connect({ app }) and put it in your reply.

Do not send an expiring connection URL through a message channel. The URL may expire before the user opens the message. Use auth.createMessageSignInUrl({ reason: "reconnect" }) instead, as Message agents explains.

On a profile keyed by externalId, the same call returns instead of throwing. The value is the connect payload: { status: "authorization_required", connect_url, app, connected: false, instructions }. Use connect_url verbatim.

A missing scope is a different failure. It fails with permission_denied.

Filter the session tool list to include only the tools your product needs. Additional tool definitions increase prompt size and expose unnecessary capabilities. configure_profile_read also tells the model to call it first on every turn, which conflicts with the context you already injected. Filter tools by name after listTools().

Inspect the error before passing it to the model. Quota limits, rate limits, expired tokens, and missing app connections can all cause tool calls to fail. Preserve the specific error so the model does not request a new connection for an unrelated failure.

Read the cause from the original error object. Converting an object with String(error) can return "[object Object]" and discard the details needed to handle it. Request a connection when the error requires authorization. A revoked or expired app token requires the user to reconnect through the hosted flow.

Actions and approval ​

Configure checks two authorization requirements before a state-changing call. The user must have connected the app, and the user must have approved your agent. Both checks fail closed on Configure's side. Neither one is a per-call prompt from Configure.

You decide whether to confirm each send or event with the user, and you build that UI. The components bundle ships a card for it: <configure-tool-approval>. It shows the tool and its parameters with Approve and Deny. It times out to Deny. It emits configure:tool-approve, configure:tool-deny, or configure:tool-always-allow with the action ID. The card executes nothing. Your handler runs the tool only on approve. Tool annotations also mark configure_email_send as destructive, so MCP clients that confirm destructive calls confirm it on their own.

Infrastructure to connect agents, apps, and chats