Skip to main content

Stripe webhooks

Run the app locally, then forward Stripe events:
Use matching Stripe test secrets in .env.local.

Auth

WorkOS sign-in flows require the local callback URL to match the WorkOS application settings. Keep local, staging, and production WorkOS credentials separate. For OIDC deployments, including Keycloak-compatible realm issuers, verify browser callback wiring and token claims before production use.

Storage

R2 and S3-compatible storage flows use server-mediated upload and download routes. Test:
  • Presign URL creation.
  • Upload completion.
  • Owner-scoped content access.
  • File deletion.

Observability

PostHog and Sentry are optional locally. Use separate projects or DSNs per environment. Do not send local secrets, access tokens, or customer data in logs.

Composio

Composio catalog and connection setup require COMPOSIO_API_KEY on the Next.js server. Hosted deployments resolve WorkOS Vault first and fall back to the server environment. Keep the Vault object and deployment variable aligned when rotating the key. Verify configuration through GET /api/v1/integrations?action=health. Catalog requests fail with an actionable provider/configuration error when the key is missing, rejected, or the upstream catalog is unavailable; an empty catalog is reserved for a successful response with no matches. Connector visibility is workspace-scoped through workspaceConnectors. On the first Personal-workspace read after upgrading, active Composio accounts with no mapping in any workspace are assigned to Personal. Existing workspace mappings are never moved or duplicated.

MCP tools

AI SDK toolsContext is keyed by executable tool name. call_mcp_tool receives its user, conversation, turn, and model attribution under the call_mcp_tool key; a flat context object fails validation before the MCP network call and leaves the transcript looking stuck. MCP calls have a 30-second default timeout and record a terminal execution row for success or failure.

Slack import via Composio

Slack import uses Composio’s SLACKBOT toolkit with direct tool execution — not the LLM session-based flow used by agent tools. This is a deterministic, paginated backfill that runs as a server-side background job.

Architecture

Key files

Direct tool execution vs LLM sessions

Agent tools use createBrowserUnifiedTools() which creates a Composio session per user and lets the LLM choose tool calls. The Slack importer does not use sessions. Instead it calls Composio’s REST API directly:
This gives deterministic pagination, retries, checkpointing, and predictable costs. The response wraps Slack’s API response in a data field (sometimes as a JSON string that must be parsed).

Composio Slackbot auth config

The SLACKBOT toolkit requires a Composio-managed auth config before OAuth can work. If one doesn’t exist, the connect flow will fail. Auth configs are created via:
The auth config is project-scoped in Composio. Once created, the standard connectResponse({ providerKey: 'slackbot' }) flow works from the UI.

Rate limit considerations

  • The backfill worker adds small delays between thread fetches (200ms) to avoid rate limits.
  • Composio may return rate limit errors from Slack’s API. The worker logs these but continues with other channels.
  • Channel listing is cached per import job — the worker lists channels once at the start.
  • For large workspaces, the import may take several minutes. Progress is reported via Convex job status updates after each channel.

Slack access limitations

A Slack bot/user token only sees conversations the authenticated account can access:
  • Public channels: broadly accessible
  • Private channels: only if the bot/user is a member
  • DMs: only the authenticated user’s DMs
  • MPIMs: only if the user is a participant
The coverage report distinguishes public/private/DM/MPIM counts so users understand what was actually imported vs what exists in their Slack workspace. For full workspace export, Slack’s admin ZIP export or Enterprise Discovery API would be needed (not implemented yet).