# Composio (/reference/sdk-reference/python/composio)

# Properties

| Name                                                                       | Type                |
| -------------------------------------------------------------------------- | ------------------- |
| [`tools`](/reference/sdk-reference/python/tools)                           | `Tools`             |
| [`toolkits`](/reference/sdk-reference/python/toolkits)                     | `Toolkits`          |
| [`triggers`](/reference/sdk-reference/python/triggers)                     | `Triggers`          |
| [`auth_configs`](/reference/sdk-reference/python/auth-configs)             | `AuthConfigs`       |
| [`connected_accounts`](/reference/sdk-reference/python/connected-accounts) | `ConnectedAccounts` |
| [`mcp`](/reference/sdk-reference/python/mcp)                               | `MCP`               |

[View source](https://github.com/composiohq/composio/blob/next/python/composio/sdk.py#L46)

***

# Constructor

```python
Composio(
    provider: BaseProvider | None = None,
    *,
    api_key: str | None = None,
    base_url: str | None = None,
    timeout: int | None = None,
    max_retries: int | None = None,
    toolkit_versions: dict[str, str] | str | None = None,
    dangerously_allow_auto_upload_download_files: bool = False,
    sensitive_file_upload_protection: bool = True,
    file_upload_path_deny_segments: Sequence[str] | None = None,
    file_upload_dirs: Sequence[str] | Literal[False] | None = None,
    file_download_dir: str | None = None,
    allow_tracking: bool = True,
    environment: str = "production",
)
```

`api_key` falls back to `os.environ["COMPOSIO_API_KEY"]` when not passed.

## Common options

| Option             | Type                  | Default             | Description                                                       |
| ------------------ | --------------------- | ------------------- | ----------------------------------------------------------------- |
| `provider`         | `BaseProvider`        | `OpenAIProvider()`  | Provider used to wrap tools (Anthropic, LangChain, Gemini, etc.). |
| `api_key`          | `str`                 | `$COMPOSIO_API_KEY` | API key. Required.                                                |
| `base_url`         | `str`                 | Composio default    | Override the API base URL.                                        |
| `timeout`          | `int`                 | client default      | Per-request timeout in seconds.                                   |
| `max_retries`      | `int`                 | `3`                 | HTTP client retry count.                                          |
| `toolkit_versions` | `dict \| str \| None` | `'latest'`          | Pin toolkit versions globally (string) or per-toolkit (dict).     |

***

# File upload security

Automatic file handling for `file_uploadable` tool fields is **off by default**. Set `dangerously_allow_auto_upload_download_files=True` to opt in. Once on, the SDK can read local paths and stage them to S3 on your behalf, but only from an allowlisted set of directories.

| Option                                         | Type                                      | Default              | Description                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------------------------------- | ----------------------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dangerously_allow_auto_upload_download_files` | `bool`                                    | `False`              | Master opt-in. When `False`, paths and URLs in `file_uploadable` arguments are forwarded as-is — the backend will reject anything that isn't already a staged `{name, mimetype, s3key}` descriptor. Set to `True` to let the SDK stage local paths and URLs on your behalf at execute time.                                                                                                                 |
| `sensitive_file_upload_protection`             | `bool`                                    | `True`               | Block local paths matching a built-in denylist of segments (`.ssh`, `.aws`, etc.) and credential-like file names. Disable only if you accept the tradeoff.                                                                                                                                                                                                                                                  |
| `file_upload_path_deny_segments`               | `Sequence[str] \| None`                   | `None`               | Extra single path components merged with the built-in denylist.                                                                                                                                                                                                                                                                                                                                             |
| `file_upload_dirs`                             | `Sequence[str] \| Literal[False] \| None` | `[~/.composio/temp]` | Allowlist of directories the SDK may read during **automatic** upload. Pass `False` (or `[]`) to reject every local path — URLs still work. Providing a list **replaces** the default; include `~/.composio/temp` explicitly if you want the default staging dir to keep working. Comparison is on a path-component boundary after `os.path.realpath`. On Windows, entries are compared case-insensitively. |
| `file_download_dir`                            | `str \| None`                             | `~/.composio/files`  | Directory where files from tool responses marked `file_downloadable` are streamed.                                                                                                                                                                                                                                                                                                                          |

Per-execution hooks live on the `modifiers=[...]` argument to `composio.tools.execute`, not on the constructor. Use the `@before_file_upload` decorator from `composio.core.models._modifiers` to inspect or rewrite each path before it is read. The hook context includes a `source` field (`'path' | 'url'`) so you can branch on local paths vs URLs.

**Related errors:** `FileUploadPathNotAllowed`, `SensitiveFilePathBlocked`, `FileUploadAbortedError`, `SDKFileNotFoundError` (all from `composio.exceptions`).

## Restricting automatic uploads to specific directories

When `dangerously_allow_auto_upload_download_files=True`, the SDK only reads local files from directories listed in `file_upload_dirs`. This stacks with (it does NOT replace) the sensitive-path denylist.

```python
from composio import Composio

composio = Composio(
    api_key="your_composio_key",
    dangerously_allow_auto_upload_download_files=True,
    # Replaces the default `[~/.composio/temp]`. List every directory you want
    # the SDK to read from during tool execution.
    file_upload_dirs=["/srv/agent/uploads", "~/.composio/temp"],
)
```

Pass `file_upload_dirs=False` (or `[]`) to reject every filesystem path; URLs and in-memory bytes still upload normally:

```python
Composio(
    api_key="your_composio_key",
    dangerously_allow_auto_upload_download_files=True,
    file_upload_dirs=False,
)
```

## Tool-Router session files

The Tool-Router session API exposes a separate files surface (`session.files.upload(...)` / `session.files.download(...)`) for streaming files into and out of a long-running router session. Those calls are unrelated to the `file_uploadable` schema flow on individual tool execution and are not gated by `dangerously_allow_auto_upload_download_files` or `file_upload_dirs`. See [`tool-router-session`](/reference/sdk-reference/python/tool-router-session) for usage.

***

# See also

* [Executing tools](/docs/tools-direct/executing-tools) — automatic vs. manual file handling, before-execute modifiers.
* [Before-execution modifiers](/docs/tools-direct/modify-tool-behavior/before-execution-modifiers#before-file-upload-python) — `@before_file_upload` decorator and the context-form hook signature.
* [Legacy auto-upload config removal changelog](/docs/changelog/2026/04/24) — migration from the removed `auto_upload_download_files` flag and the allowlist semantics matrix.

---

📚 **More documentation:** [View all docs](https://docs.composio.dev/llms.txt) | [Glossary](https://docs.composio.dev/llms.mdx/docs/glossary) | [Cookbooks](https://docs.composio.dev/llms.mdx/cookbooks) | [API Reference](https://docs.composio.dev/llms.mdx/reference)

---

# Composio SDK — Instructions for AI Code Generators

**Purpose:** Enforce only the **current** and **correct** patterns for integrating [Composio](https://composio.dev/) tools into AI agents.
**Scope:** All AI-generated code using Composio must follow these guardrails.

---

## 1. Correct Composio Integration

Composio supports two integration modes: **Native Tools** (with a provider package) and **MCP** (no provider package needed).

### Native Tools

```python
# ✅ CORRECT — Python (defaults to OpenAI)
from composio import Composio

composio = Composio()
session = composio.create(user_id="user_123")
tools = session.tools()
# Pass tools to your agent/LLM framework
```

```typescript
// ✅ CORRECT — TypeScript (defaults to OpenAI)
import { Composio } from "@composio/core";

const composio = new Composio();
const session = await composio.create("user_123");
const tools = await session.tools();
// Pass tools to your agent/LLM framework
```

For other providers, pass the provider explicitly. Provider packages follow the naming convention: `composio_<provider>` for Python, `@composio/<provider>` for TypeScript.

### MCP

Use `session.mcp.url` and `session.mcp.headers` with any MCP-compatible client (Claude Desktop, Cursor, OpenAI Agents, etc.). No provider package needed.

---

## 2. CRITICAL INSTRUCTIONS FOR AI MODELS

### 2.1 — ALWAYS DO THE FOLLOWING

1. **Use `composio.create(user_id)`** to create a session — this is the entry point for all Composio integrations.
2. **Use `session.tools()`** for native tool integration or **`session.mcp.url`** for MCP integration.
3. **Import** from the correct provider package (`composio_<provider>` for Python, `@composio/<provider>` for TypeScript).
4. **Pass `user_id` to `composio.create()`**, not to individual tool calls.

### 2.2 — NEVER DO THE FOLLOWING

1. **Do not** instruct users to manually create auth configs or connected accounts before running.
2. **Do not** import from `composio_openai` / `@composio/openai` when using OpenAI Agents SDK — use `composio_openai_agents` / `@composio/openai-agents` instead.

### 2.3 — DISCOURAGED (do not use unless user explicitly asks)

Do **not** generate `composio.tools.get()`, `composio.tools.execute()`, or `composio.provider.handle_tool_calls()` unless the user explicitly requests direct tool execution. These are a supported but **not recommended** low-level interface.


---

## Terminology Migration (old → current)

If you encounter these terms in error messages, old documentation, or user prompts, translate them to the current equivalents. **Do not use the old terms in generated code or explanations.**

| Old term (v1/v2) | Current term (v3) | In code |
|---|---|---|
| entity ID | user ID | `user_id` parameter |
| actions | tools | e.g., `GITHUB_CREATE_ISSUE` is a *tool* |
| apps / appType | toolkits | e.g., `github` is a *toolkit* |
| integration / integration ID | auth config / auth config ID | `auth_config_id` parameter |
| connection | connected account | `connected_accounts` namespace |
| ComposioToolSet / OpenAIToolSet | `Composio` class with a provider | `Composio(provider=...)` |
| toolset | provider | e.g., `OpenAIProvider` |

If a user says "entity ID", they mean `user_id`. If they say "integration", they mean "auth config". Always respond using the current terminology.

