Skip to main content
Integrations extend your agents beyond conversation — they let your AI act on the world by calling real APIs, sending messages, querying documents, and triggering workflows inside the tools your team already uses. Feather’s integration layer handles OAuth flows, credential storage, and tool schema sync so you can focus on building agent logic rather than plumbing.

Browse available integrations

Before connecting, discover what’s available. The /v1/integrations endpoint returns a catalog of supported services, each described by an IntegrationSummary object.
curl -X GET https://api-sandbox.featherhq.com/v1/integrations \
  -H "x-api-key: <your_api_key>"
Example response:
[
  {
    "key": "slack",
    "display_name": "Slack",
    "description": "Send messages, read channels, react to events.",
    "category": "communication",
    "logo_url": "https://cdn.feather.io/integrations/slack.svg"
  },
  {
    "key": "notion",
    "display_name": "Notion",
    "description": "Search and edit pages, databases, and blocks; read comments and users.",
    "category": "productivity",
    "logo_url": "https://cdn.feather.io/integrations/notion.svg"
  },
  {
    "key": "google_drive",
    "display_name": "Google Drive",
    "description": "Ingest Google Docs, Sheets, Slides, and files into a knowledge base.",
    "category": "productivity",
    "logo_url": "https://cdn.feather.io/integrations/google-drive.svg"
  },
  {
    "key": "twilio",
    "display_name": "Twilio",
    "description": "Bring your own Twilio account for SMS and voice.",
    "category": "communication",
    "logo_url": "https://cdn.feather.io/integrations/twilio.svg"
  },
  {
    "key": "calcom",
    "display_name": "Cal.com",
    "description": "Check availability and book, cancel, or reschedule meetings.",
    "category": "scheduling",
    "logo_url": "https://cdn.feather.io/integrations/calcom.svg"
  },
  {
    "key": "email",
    "display_name": "Email",
    "description": "Send email to the customer from your connected mailbox.",
    "category": "communication",
    "logo_url": "https://cdn.feather.io/integrations/email.svg"
  },
  {
    "key": "custom_mcp",
    "display_name": "Custom MCP",
    "description": "Connect any MCP server with customer-supplied auth.",
    "category": "custom",
    "logo_url": "https://cdn.feather.io/integrations/mcp.svg"
  }
]

Connect an integration (OAuth)

Most first-party integrations use OAuth. Feather delegates the OAuth handshake to Nango, an open-source auth platform — you never handle raw credentials.
1

Initiate the connection

Create a connection record and receive a short-lived session_token.
curl -X POST https://api-sandbox.featherhq.com/v1/integrations/connections \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_key": "slack",
    "nickname": "My Slack Workspace"
  }'
Response:
{
  "connection_id": "conn_01hx9z3p4qr7mn2k8wdt",
  "session_token": "nango_sess_eyJhbGciOiJIUzI1NiJ9...",
  "expires_at": "2024-09-01T14:32:00Z",
  "vendor": "nango"
}
2

Open the OAuth popup

Use the session_token with the Nango frontend SDK to launch the OAuth consent screen in your UI.
import Nango from "@nangohq/frontend";

const nango = new Nango();
await nango.auth("slack", "<connection_id>", {
  sessionToken: "<session_token>",
});
The popup guides your user through Slack’s standard OAuth flow. No credentials touch your server.
3

Finalize the connection

Once the user completes OAuth, activate the connection so Feather can begin syncing tools.
curl -X POST https://api-sandbox.featherhq.com/v1/integrations/connections/conn_01hx9z3p4qr7mn2k8wdt/finalize \
  -H "x-api-key: <your_api_key>"
Feather will immediately sync the tool schema for your new connection. Tools are ready to attach to agents within seconds.

Connect a custom MCP server

Any server that implements the Model Context Protocol can be connected to Feather — whether it’s an internal microservice or a third-party MCP host.

Bearer token authentication

For MCP servers protected by a static secret:
curl -X POST https://api-sandbox.featherhq.com/v1/integrations/connections/custom-mcp \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "nickname": "My MCP",
    "server_url": "https://mcp.example.com",
    "transport": "sse",
    "auth_type": "bearer",
    "token": "<secret>"
  }'

OAuth-protected MCP servers

For MCP servers that use OAuth, first run discovery to retrieve the authorization metadata:
1

Discover OAuth config

curl -X POST https://api-sandbox.featherhq.com/v1/integrations/connections/custom-mcp/discover \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{"server_url": "https://mcp.example.com"}'
The response includes the OAuth authorization endpoints and scopes required by the server.
2

Connect with OAuth

Use the discovered metadata to connect with auth_type: "oauth", then follow the same finalize flow as standard OAuth integrations.
curl -X POST https://api-sandbox.featherhq.com/v1/integrations/connections/custom-mcp \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "nickname": "My MCP",
    "server_url": "https://mcp.example.com",
    "transport": "sse",
    "auth_type": "oauth"
  }'

View and manage tools

After a connection is finalized, Feather automatically syncs the available tools from the integration. Each tool has a unique slug, a human-readable name, and a JSON Schema describing its inputs.
curl https://api-sandbox.featherhq.com/v1/integrations/connections/conn_01hx9z3p4qr7mn2k8wdt \
  -H "x-api-key: <your_api_key>"
Response (tools array excerpt):
{
  "id": "conn_01hx9z3p4qr7mn2k8wdt",
  "integration_key": "slack",
  "nickname": "My Slack Workspace",
  "status": "active",
  "tools": [
    {
      "slug": "send_message",
      "display_name": "Send Message",
      "is_enabled": true,
      "input_schema": {
        "type": "object",
        "properties": {
          "channel": { "type": "string", "description": "Channel name or ID" },
          "text": { "type": "string", "description": "Message content" }
        },
        "required": ["channel", "text"]
      }
    },
    {
      "slug": "list_channels",
      "display_name": "List Channels",
      "is_enabled": true,
      "input_schema": {
        "type": "object",
        "properties": {
          "limit": { "type": "integer", "default": 20 }
        }
      }
    }
  ]
}

Disable or enable individual tools

Prevent an agent from calling specific tools without disconnecting the entire integration. The path takes the tool’s id (the UUID from the connection’s tools array), not its slug:
curl -X PATCH \
  "https://api-sandbox.featherhq.com/v1/integrations/connections/conn_01hx9z3p4qr7mn2k8wdt/tools/9f8b2c14-7d3e-4a91-b6f0-2e5c1a8d4f37" \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{"is_enabled": false}'

Bulk toggle all tools

curl -X PATCH \
  "https://api-sandbox.featherhq.com/v1/integrations/connections/conn_01hx9z3p4qr7mn2k8wdt/tools" \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{"is_enabled": true}'

Test a tool

Before attaching a tool to an agent, verify it works end-to-end using the test invoke endpoint.
curl -X POST \
  "https://api-sandbox.featherhq.com/v1/integrations/connections/conn_01hx9z3p4qr7mn2k8wdt/test-invoke" \
  -H "x-api-key: <your_api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "send_message",
    "input": {
      "channel": "#general",
      "text": "Hello from Feather!"
    }
  }'
Response:
{
  "result": {
    "ok": true,
    "channel": "C08ABCDEF",
    "ts": "1725200000.123456",
    "message": { "text": "Hello from Feather!", "type": "message" }
  },
  "narrowed": {
    "ok": true,
    "channel": "C08ABCDEF",
    "ts": "1725200000.123456"
  }
}
The result field is the full vendor API response. narrowed is the field-map filtered result that your agent actually receives — only the fields relevant to decision-making.

Attach integration tools to an agent

Reference integration tools in your agent revision’s tool_refs array using the tool’s slug. Each tool slug is built as {nickname_slug}_{tool_slug} — the connection nickname slugified (lowercased, non-alphanumeric runs collapsed to underscores) joined to the slugified tool path with an underscore. A connection nicknamed “My Slack Workspace” therefore produces slugs like my_slack_workspace_send_message.
{
  "tool_refs": [
    {
      "kind": "integration",
      "slug": "my_slack_workspace_send_message"
    },
    {
      "kind": "integration",
      "slug": "my_slack_workspace_list_channels"
    },
    {
      "kind": "integration",
      "slug": "my_notion_search_pages"
    }
  ]
}
The agent will automatically receive the tool’s input schema in its context and can invoke it during a conversation without any additional wiring.
If an integration provider adds new tools or changes their schema, use POST /v1/integrations/connections/{connection_id}/refresh-tools to manually re-sync. This is useful when building against a frequently updated MCP server.