Skip to content

Integrations

Integrations connect Pinchy to external systems — ERPs, email accounts, CRMs, search engines — so agents can work with real business data and access live information. Instead of giving agents direct access, Pinchy provides a controlled bridge: the admin sets up a connection once, then decides which agents can use it and what they're allowed to do.

| Integration | Connection method | Guide | | ----------------------------- | ----------------- | ------------------------------------------------------------- | | Google (Gmail) | OAuth 2.0 | Connect Email (Gmail) | | Microsoft (Outlook / 365) | OAuth 2.0 | Connect Email (Microsoft) | | Odoo | API key | Connect Odoo | | Web Search (Brave) | API key | Set Up Web Search |

These are two separate concepts:

  • Connection — a global setting an admin creates once. It stores the credentials and knows how to talk to the external system. Think of it as "Pinchy can talk to this system."
  • Permissions — per-agent settings that control what each agent can do with that connection. Think of it as "this agent can read emails but not send them" or "this agent can search the web but not fetch arbitrary pages."

Creating a connection doesn't give any agent access. You must explicitly grant access in each agent's Permissions tab.

Integrations are admin-managed and attach to shared agents

Section titled “Integrations are admin-managed and attach to shared agents”

Integrations are an admin-level feature, and they only attach to shared agents. Two facts about how Pinchy creates agents explain why:

  • Every agent you create is a shared agent. New agents are shared by default — the only personal agent is the Smithers that Pinchy auto-creates for each user.
  • Only shared agents have a Permissions tab. Personal agents (like Smithers) don't show Permissions or Access, because there's nothing to share and nothing to govern. See Agent Settings for the full tab breakdown.

Since a connection is granted through the Permissions tab, and that tab exists only on shared agents managed by an admin, integrations always live on shared, team-visible agents.

Not today. There's no per-user, private email connection: an admin sets up the email app and connects the mailboxes, then grants specific agents access to them. A mailbox connected this way is reachable by any agent an admin points at it — it isn't scoped to a single person's private Smithers.

If you need an agent to work with a mailbox, ask an admin to connect it and grant a shared agent the appropriate email permissions. Keep in mind that shared agents are team resources: anyone with access to that agent can ask it to read or send mail from the connected mailbox, within the permissions it's been granted.

Pinchy connects to email over OAuth 2.0 for both Google (Gmail) and Microsoft (Outlook / Microsoft 365). An admin sets up the provider's OAuth app once, connects one or more mailboxes, then grants specific permissions per agent.

Email setup has two layers with separate lifecycles:

  • The OAuth app — the Client ID, Client Secret, and (for Microsoft) optional Tenant ID registered with the provider. Set up once per provider through the Add Integration wizard, it's what lets Pinchy talk to Google or Microsoft at all. Once configured, it appears in the Connected apps section of Settings → Integrations, where an admin can Edit or Reset it. That section is management-only: it stays hidden until at least one app is configured and never offers setup itself.
  • The mailboxes — the individual accounts connected through that app. One app carries many mailboxes. After the app exists, connecting another mailbox skips the credentials step.

Rotating just the app's client secret keeps every mailbox connected. Changing the client ID is effectively a new app, so every mailbox has to be reconnected. Resetting an app disconnects all of its mailboxes — the UI warns with the exact count first. The app persists even after its last mailbox is removed; it's cleared only by an explicit reset.

Email requires a provider OAuth app (one-time, per Pinchy installation): a Google Cloud OAuth app for Gmail, or an Azure app registration for Microsoft. Once created, admins connect one or more mailboxes through the Add Integration wizard. Both providers require HTTPS — the wizard shows a warning and blocks the OAuth flow when Pinchy is running without HTTPS.

Each agent gets email permissions independently, and each operation is its own checkbox — granting Send does not also grant Read or Draft. Check every operation the agent needs.

| Permission | Tools enabled | | ----------------- | ------------------------------------------------------------------ | | Read messages | email_list, email_read, email_search, email_get_attachment | | Create drafts | email_draft | | Send messages | email_send |

OAuth access tokens expire after about one hour. Pinchy refreshes them in the background using the stored refresh token. If a refresh fails permanently — the user revoked access, a Google refresh token expired in Testing mode, or a Microsoft client secret expired — the mailbox surfaces an "Authentication failed" state and the admin reconnects it via the mailbox's Reconnect action, which keeps its agent permissions attached.

  • Client ID and Client Secret are encrypted with AES-256-GCM before storage
  • Access and refresh tokens are encrypted per-connection
  • Tokens are decrypted on-demand when the agent makes an API call — they never end up in the OpenClaw config file
  • The pinchy-email plugin fetches tokens via Pinchy's internal API, authenticated by the shared gateway token

For the full setup walkthrough, see Connect Email.

Web Search is the simplest integration — a single API key connects Pinchy to the Brave Search API, giving agents the ability to search the web and fetch pages.

Unlike Odoo, Web Search has no multi-step sync or schema discovery. You enter your API key, Pinchy validates it, and the connection is ready. From there, you enable web search tools per agent in the Permissions tab.

| Tool | What it does | | ------------------- | -------------------------------------------------- | | Search the web | Queries Brave Search and returns ranked results | | Fetch web pages | Downloads and extracts readable content from a URL |

Each agent can have its own web search configuration:

  • Domain restrictions — one list where each domain is marked Include (agent may only access these) or Exclude (agent is blocked from these); modes can be combined
  • Freshness — limit results to a time window (last day, week, month, or year)
  • Language / Region — bias results toward a language or geographic region (full ISO lists, searchable)

These filters are stored per agent, so you can have a support agent restricted to your docs site while a research agent has unrestricted access.

When an agent has both web fetch access and access to sensitive data (files or Odoo records), Pinchy shows a contextual security warning about data exfiltration risk. The web fetch module also includes built-in SSRF protection — agents cannot fetch internal network addresses or localhost.

For the full setup walkthrough, see Set Up Web Search.

When you add a connection, Pinchy probes the external system to discover what's available:

  1. Schema discovery — Pinchy calls fields_get() on each model to learn the field names, types, and relationships
  2. Permission check — Pinchy calls check_access_rights() to determine which operations (read, create, write, delete) the API user can perform
  3. Filtering — Only models where the API user has at least read access appear in the connection summary

This means the connection reflects what's actually accessible — not what exists in theory. If the Odoo admin later restricts the API user's permissions, some models may disappear on the next sync.

When granting an agent access to an Odoo connection, you choose an access level:

| Level | Tools enabled | Use case | | ---------------- | --------------------------------------------------- | ---------------------------- | | Read-only | list-models, describe-model, read, count, aggregate | Reporting, dashboards, Q&A | | Read & Write | read-only set + create, write, attach-file | Data entry, updating records | | Full | read & write set + delete | Full CRUD — use with caution | | Custom | You pick individual tools | Fine-grained control |

Each level maps directly to the Odoo tools that get enabled for the agent. See Agent Permissions for the full tool list, including the per-tool IDs and the cross-company write protection that applies to all Odoo agents regardless of level.

If the Odoo admin changes the API user's permissions after you've set up the connection, agents may lose access to certain models. When this happens:

  • The agent gets a clear error message explaining that access was denied
  • The error suggests that an admin re-syncs the connection

To re-sync: go to Settings → Integrations, open the connection's menu, and click Sync Schema. Pinchy probes the available models again and updates the connection accordingly.

Re-syncing may remove models that are no longer accessible. Agents that were configured to use those models will lose access to them.

OAuth connections (Gmail, Microsoft 365) have a brief pending phase between clicking Connect and finishing the provider's sign-in. Pinchy handles that window for you:

  • The list updates itself. The Integrations list polls while a connection is pending, so it flips to connected — or to an error — on its own, without a page reload.
  • You can cancel a half-finished setup. A pending row's button reads Cancel setup rather than Delete; use it if you started a connection you no longer want.
  • Abandoned attempts clean themselves up. A pending record that never completes is swept automatically after 15 minutes, so a closed browser tab or an abandoned sign-in doesn't leave a stray row behind.

If the sign-in itself fails — most often a wrong Client Secret at the token-exchange step — Pinchy shows a persistent error banner on the Integrations tab that names the specific cause and the fix (for example, correcting the Client Secret under Connected apps). It stays until you dismiss it, rather than vanishing like a toast, because your attention is usually still on the provider's sign-in screen when it lands.

Pinchy detects permanent authentication failures — an expired API key, a revoked OAuth grant, a changed password — and surfaces them in two places:

  • The integration card on Settings → Integrations changes from a green checkmark to a red warning, with the failure reason from the upstream service.
  • The Settings entry in the sidebar shows a red ! badge when one or more integrations need attention. Opening Settings from that badge takes you straight to the Integrations tab — which carries its own error dot — so you land on the failing connection instead of hunting for it.

To recover, open the integration's menu and choose Edit credentials (or click Reconnect on the failed card). Update the affected field — for example, paste in a new API key. Non-secret fields stay pre-filled; secret fields are empty by default and left unchanged if you leave them blank. Pinchy validates the new credentials against the upstream service before saving, and clears the failed state on success. The connection keeps the same ID, so any agent permissions stay attached automatically.

Email connections (Gmail and Microsoft 365) depend on a separate, shared OAuth app — see The app and the mailboxes. If an admin resets or deletes that app's credentials in Connected apps while mailboxes are still connected through it, each affected mailbox shows an amber "App not configured" badge on Settings → Integrations, distinct from the red "Authentication failed" state used for revoked or expired credentials.

Restoring the same app — same Client ID, with a new secret if needed — clears the badge for every affected mailbox automatically, with no per-mailbox reconnect required. Refresh tokens are bound to the app's Client ID plus the connected user and scope, not to the secret, so as soon as the app is configured again, the next token refresh just works.

A full reconnect is only needed if the app was permanently deleted rather than just having its credentials reset, or if you're deliberately switching the mailbox to a different app going forward.

Integration credentials are encrypted at rest with the server's ENCRYPTION_KEY. If that key changes — an infrastructure migration, a mistaken rotation, a server rebuilt from scratch without the original key — Pinchy can no longer decrypt the connections written under the old key. Each one surfaces a red "can't be read" card on Settings → Integrations, noting that it was encrypted with a different ENCRYPTION_KEY than the one the server uses now.

Unlike "App not configured", this state does not clear on its own — there's no way to recover the old ciphertext without the old key. The only path forward is to delete the unreadable connection and re-add it under the current key. Keep ENCRYPTION_KEY stable across restarts and migrations to avoid this in the first place — see Secrets.

All integration credentials are handled with the same rigor as provider API keys:

  • Encryption — credentials are encrypted with AES-256-GCM before being stored in the database. They never appear in logs, config files, or API responses.
  • Audit trail — connection creation and permission changes are logged. All audit rows are HMAC-SHA256 signed.
  • Least privilege — each integration enforces its own permission model. Agents start with zero access and must be granted specific operations explicitly.
  • Token isolation — OAuth tokens and API keys stay in Pinchy's encrypted database. They are never written to the OpenClaw config file — plugins fetch them on-demand via an internal API.

See Agent Permissions for the full allow-list model and how integration tools fit in.