Claude
Skills
Sign in
Back

composio

Included with Lifetime
$97 forever

Composio gateway: act on 1000+ connected apps like Gmail, Slack, GitHub, Calendar. Use when the user wants to act in a connected SaaS app (e.g. send Gmail, create Notion page, add Calendar event, open a GitHub issue).

Productivity

What this skill does


# Composio — External App Integration via Gateway

Composio lets users connect 1000+ external apps (Gmail, Slack, GitHub, Google Calendar, Notion, etc.) to their Starchild agent. All operations go through the **Composio Gateway** (`composio-gateway.fly.dev`), which handles auth and API key management.

## Architecture

```
Agent (Fly 6PN network)
    ↓  HTTP (auto-authenticated by IPv6)
Composio Gateway (composio-gateway.fly.dev)
    ↓  Composio SDK
Composio Cloud → Target API (Gmail, Slack, etc.)
```

- **You never touch the COMPOSIO_API_KEY** — the gateway holds it
- **You never call Composio SDK directly** — use the gateway HTTP API
- **Authentication is automatic** — your Fly 6PN IPv6 resolves to a user_id via the billing DB
- **No env vars needed** — the gateway is always accessible from any agent container

## Gateway Base URL

```
GATEWAY = "http://composio-gateway.flycast"
```

All requests use **plain HTTP over Fly internal network** (flycast). No JWT needed.

## API Reference

### 1. Search Tools (compact)

Find the right tool slug for a task. Returns **compact** tool info — just slug, description, and parameter names. Enough to pick the right tool.

```bash
curl -s -X POST $GATEWAY/internal/search \
  -H "Content-Type: application/json" \
  -d '{"query": "send email via gmail"}'
```

**Response (compact):**
```json
{
  "results": [{"primary_tool_slugs": ["GMAIL_SEND_EMAIL"], "use_case": "send email", ...}],
  "tool_schemas": {
    "GMAIL_SEND_EMAIL": {
      "tool_slug": "GMAIL_SEND_EMAIL",
      "toolkit": "gmail",
      "description": "Send an email...",
      "parameters": ["to", "subject", "body", "cc", "bcc"],
      "required": ["to", "subject", "body"]
    }
  },
  "toolkit_connection_statuses": [...]
}
```

### 2. Get Tool Schema (full)

Get the **complete** parameter definitions for a specific tool — types, descriptions, enums, defaults. Use this **after** search when you need exact parameter formats.

```bash
curl -s -X POST $GATEWAY/internal/tool_schema \
  -H "Content-Type: application/json" \
  -d '{"tool": "GOOGLECALENDAR_EVENTS_LIST"}'
```

**Response:**
```json
{
  "data": {
    "tool_slug": "GOOGLECALENDAR_EVENTS_LIST",
    "description": "Returns events on the specified calendar.",
    "input_parameters": {
      "properties": {
        "timeMin": {"type": "string", "description": "RFC3339 timestamp..."},
        "timeMax": {"type": "string", "description": "RFC3339 timestamp..."},
        "calendarId": {"type": "string", "default": "primary"}
      },
      "required": ["calendarId"]
    }
  },
  "error": null
}
```

### 3. Execute a Tool

Execute a Composio tool. **Key name is `arguments`, not `params`.**

```bash
curl -s -X POST $GATEWAY/internal/execute \
  -H "Content-Type: application/json" \
  -d '{"tool": "GMAIL_SEND_EMAIL", "arguments": {"to": "[email protected]", "subject": "Hi", "body": "Hello!"}}'
```

**On success:**
```json
{"data": {"messages": [...]}, "error": null}
```

**On failure** — includes tool_schema so you can self-correct:
```json
{
  "data": null,
  "error": "Missing required parameter: calendarId",
  "tool_schema": {
    "tool_slug": "GOOGLECALENDAR_EVENTS_LIST",
    "description": "...",
    "input_parameters": {"properties": {...}, "required": [...]}
  }
}
```

### 4. List User's Connections (and confirm OAuth completion)

```bash
# Optional toolkit filter: oauth_completed_active only turns true
# when that toolkit status is ACTIVE.
curl -s "$GATEWAY/internal/connections?toolkit=gmail"
```

Response includes:
- `connections`: current deduplicated connection list
- `oauth_completed_active`: boolean, true only when OAuth completion is observed as `ACTIVE`

Cache invalidation is triggered only after ACTIVE is observed, and it targets the user's instance (`fly-force-instance-id=<user container_id from user_mapping>`), not composio-gateway's own instance.

### 5. Initiate New Connection

```bash
curl -s -X POST $GATEWAY/api/connect \
  -H "Content-Type: application/json" \
  -d '{"toolkit": "gmail"}'
```

Returns `connect_url` for the user to complete OAuth.

### 6. Disconnect

```bash
curl -s -X DELETE $GATEWAY/api/connections/{connection_id}
```

### Instagram Posting (important slug mapping)

Composio search may return legacy Instagram slugs that are not executable in this environment.
When posting to Instagram, use these **working slugs**:

1) Create draft container:
- `INSTAGRAM_CREATE_MEDIA_CONTAINER`
- Required: `ig_user_id`
- Typical args for photo: `{"ig_user_id":"...","image_url":"https://...","content_type":"photo","caption":"..."}`

2) Publish draft:
- `INSTAGRAM_CREATE_POST`
- Required: `ig_user_id`, `creation_id`

Two-step flow:
- Execute `INSTAGRAM_CREATE_MEDIA_CONTAINER` → read `data.data.id` as `creation_id`
- Execute `INSTAGRAM_CREATE_POST` with that `creation_id`

Tip: If `/internal/search` suggests `INSTAGRAM_POST_IG_USER_MEDIA` or `INSTAGRAM_POST_IG_USER_MEDIA_PUBLISH` but execute returns "Tool ... not found", switch to the two slugs above.

### Browserbase — Hybrid Workflow (Session Management + Playwright CDP)

**Composio's Browserbase tools ONLY manage session lifecycle (open/close/list). They do NOT control web pages.**

To actually operate a browser (navigate, click, fill forms, scrape data), use **Playwright `connect_over_cdp`** to connect to the session's WebSocket URL.

#### Step 1: Create a Browserbase Session via Composio

```bash
curl -s -X POST $GATEWAY/internal/execute \
  -H "Content-Type: application/json" \
  -d '{"tool": "BROWSERBASE_TOOL_SESSIONS_CREATE", "arguments": {"projectId": "YOUR_PROJECT_ID"}}'
```

Response includes `id` (session_id), `status`, and timestamps.

#### Step 2: Build the CDP WebSocket URL

```python
import os
session_id = "<session_id from step 1>"
api_key = os.environ.get("BROWSERBASE_API_KEY")  # stored in workspace/.env
cdp_url = f"wss://connect.browserbase.com?apiKey={api_key}&sessionId={session_id}"
```

#### Step 3: Control the Browser with Playwright

```python
from playwright.async_api import async_playwright

async with async_playwright() as p:
    browser = await p.chromium.connect_over_cdp(cdp_url)
    page = await browser.new_page()
    await page.goto("https://example.com")

    # Click, fill, screenshot — full Playwright API
    await page.click("button.submit")
    await page.fill("input[name='email']", "[email protected]")
    await page.screenshot(path="result.png")

    content = await page.content()
```

#### Step 4: Delete the Session (IMPORTANT — stops billing)

```bash
curl -s -X POST $GATEWAY/internal/execute \
  -H "Content-Type: application/json" \
  -d '{"tool": "BROWSERBASE_TOOL_SESSIONS_DELETE", "arguments": {"id": "YOUR_SESSION_ID"}}'
```

#### Key Concepts

| Aspect | Detail |
|--------|--------|
| **Composio role** | Session lifecycle only — create, list, delete sessions |
| **Playwright role** | Page control — navigate, click, fill, scrape, screenshot |
| **Memory cost** | ~30-50MB locally (Playwright client only); Chromium runs on Browserbase servers |
| **Anti-detection** | Browserbase handles it server-side — fingerprint masking, captcha solving, Cloudflare bypass. Playwright client does nothing special. |
| **Billing** | Per-minute (rounded up). Always delete sessions when done. |

#### Full Example Script (Create → Control → Delete)

```python
#!/usr/bin/env python3
"""Browserbase: create session → control with Playwright → clean up."""
import asyncio, os, requests
from playwright.async_api import async_playwright

GATEWAY = "http://composio-gateway.flycast"
PROJECT_ID = os.environ.get("BROWSERBASE_PROJECT_ID")

async def main():
    # 1. Create session via Composio
    resp = requests.post(f"{GATEWAY}/internal/execute", json={
        "tool": "BROWSERBASE_TOOL_SESSIONS_CREATE",
        "arguments": {"projectId": PROJECT_ID}
    }).json()
    session_id = resp["data"]["id"]
    print(f"Session created: {session_id}")

    try:
        # 2. Connect via CDP
        api_key = os.environ["BROWSERBASE_API_KEY"]
Files: 2
Size: 33.6 KB
Complexity: 40/100
Category: Productivity

Related in Productivity