# MCP (/reference/sdk-reference/python/mcp)

# Methods

## create()

Create a new MCP server configuration with specified toolkits and authentication settings.

```python
def create(name: str, toolkits: List[Union[ConfigToolkit, str]], manually_manage_connections: bool = ..., allowed_tools: List[str | None] = ...) -> MCPCreateResponse
```

**Parameters**

| Name                           | Type                              |
| ------------------------------ | --------------------------------- |
| `name`                         | `str`                             |
| `toolkits`                     | `List[Union[ConfigToolkit, str]]` |
| `manually_manage_connections?` | `bool`                            |
| `allowed_tools?`               | `List[str \| None]`               |

**Returns**

`MCPCreateResponse` — Created server details with generate method

**Example**

```python
>>> # Using toolkit configuration objects with auth
    >>> server = composio.experimental.mcp.create(
    ...     'personal-mcp-server',
    ...     toolkits=[
    ...         {
    ...             'toolkit': 'github',
    ...             'auth_config_id': 'ac_xyz',
    ...         },
    ...         {
    ...             'toolkit': 'slack',
    ...             'auth_config_id': 'ac_abc',
    ...         },
    ...     ],
    ...     allowed_tools=['GITHUB_CREATE_ISSUE', 'GITHUB_LIST_REPOS', 'SLACK_SEND_MESSAGE'],
    ...     manually_manage_connections=False
    ... )
    >>>
    >>> # Using simple toolkit names (most common usage)
    >>> server = composio.experimental.mcp.create(
    ...     'simple-mcp-server',
    ...     toolkits=['composio_search', 'text_to_pdf'],
    ...     allowed_tools=['COMPOSIO_SEARCH_DUCK_DUCK_GO_SEARCH', 'TEXT_TO_PDF_CONVERT_TEXT_TO_PDF']
    ... )
    >>>
    >>> # Using all tools from toolkits (default behavior)
    >>> server = composio.experimental.mcp.create(
    ...     'all-tools-server',
    ...     toolkits=['composio_search', 'text_to_pdf']
    ...     # allowed_tools=None means all tools from these toolkits
    ... )
    >>>
    >>> # Get server instance for a user
    >>> mcp = server.generate('user_12345')
```

***

## list()

List MCP servers with optional filtering and pagination.

```python
def list(page_no: int | None = ..., limit: int | None = ..., toolkits: str | None = ..., auth_config_ids: str | None = ..., name: str | None = ..., order_by: Literal['created_at', 'updated_at' | None] = ..., order_direction: Literal['asc', 'desc' | None] = ...) -> MCPListResponse
```

**Parameters**

| Name               | Type                                          |
| ------------------ | --------------------------------------------- |
| `page_no?`         | `int \| None`                                 |
| `limit?`           | `int \| None`                                 |
| `toolkits?`        | `str \| None`                                 |
| `auth_config_ids?` | `str \| None`                                 |
| `name?`            | `str \| None`                                 |
| `order_by?`        | `Literal['created_at', 'updated_at' \| None]` |
| `order_direction?` | `Literal['asc', 'desc' \| None]`              |

**Returns**

`MCPListResponse` — Paginated list of MCP servers

**Example**

```python
>>> # List all servers
    >>> all_servers = composio.experimental.mcp.list()
    >>>
    >>> # List with pagination
    >>> paged_servers = composio.experimental.mcp.list(page_no=2, limit=5)
    >>>
    >>> # Filter by toolkit
    >>> github_servers = composio.experimental.mcp.list(toolkits='github', name='personal')
```

***

## get()

Retrieve detailed information about a specific MCP server/config.

```python
def get(server_id: str)
```

**Parameters**

| Name        | Type  |
| ----------- | ----- |
| `server_id` | `str` |

**Example**

```python
>>> server = composio.experimental.mcp.get('mcp_12345')
    >>>
    >>> print(server['name'])  # "My Personal MCP Server"
    >>> print(server['allowed_tools'])  # ["GITHUB_CREATE_ISSUE", "SLACK_SEND_MESSAGE"]
    >>> print(server['toolkits'])  # ["github", "slack"]
    >>> print(server['server_instance_count'])  # 3
```

***

## update()

Update an existing MCP server configuration.

```python
def update(server_id: str, name: str | None = ..., toolkits: List[Union[ConfigToolkit, str | None]] = ..., manually_manage_connections: bool | None = ..., allowed_tools: List[str | None] = ...)
```

**Parameters**

| Name                           | Type                                      |
| ------------------------------ | ----------------------------------------- |
| `server_id`                    | `str`                                     |
| `name?`                        | `str \| None`                             |
| `toolkits?`                    | `List[Union[ConfigToolkit, str \| None]]` |
| `manually_manage_connections?` | `bool \| None`                            |
| `allowed_tools?`               | `List[str \| None]`                       |

**Example**

```python
>>> # Update server name only
    >>> updated_server = composio.experimental.mcp.update(
    ...     'mcp_12345',
    ...     name='My Updated MCP Server'
    ... )
    >>>
    >>> # Update toolkits and tools
    >>> server_with_new_tools = composio.experimental.mcp.update(
    ...     'mcp_12345',
    ...     toolkits=['github', 'slack'],
    ...     allowed_tools=['GITHUB_CREATE_ISSUE', 'SLACK_SEND_MESSAGE']
    ... )
    >>>
    >>> # Update with auth configs
    >>> server_with_auth = composio.experimental.mcp.update(
    ...     'mcp_12345',
    ...     toolkits=[
    ...         {'toolkit': 'github', 'auth_config_id': 'auth_abc123'},
    ...         {'toolkit': 'slack', 'auth_config_id': 'auth_def456'}
    ...     ],
    ...     allowed_tools=['GITHUB_CREATE_ISSUE', 'SLACK_SEND_MESSAGE'],
    ...     manually_manage_connections=False
    ... )
```

***

## delete()

Permanently delete an MCP server configuration.

```python
def delete(server_id: str) -> Dict[str, Any]
```

**Parameters**

| Name        | Type  |
| ----------- | ----- |
| `server_id` | `str` |

**Returns**

`Dict[str, Any]` — Deletion result

**Example**

```python
>>> # Delete a server
    >>> result = composio.experimental.mcp.delete('mcp_12345')
    >>>
    >>> if result['deleted']:
    ...     print(f"Server {result['id']} has been successfully deleted")
    >>> else:
    ...     print(f"Failed to delete server {result['id']}")
```

***

## generate()

Get server URLs for an existing MCP server.  This matches the TypeScript implementation exactly.

```python
def generate(user_id: str, mcp_config_id: str, manually_manage_connections: bool | None = ...) -> MCPServerInstance
```

**Parameters**

| Name                           | Type           |
| ------------------------------ | -------------- |
| `user_id`                      | `str`          |
| `mcp_config_id`                | `str`          |
| `manually_manage_connections?` | `bool \| None` |

**Returns**

`MCPServerInstance` — MCP server instance

**Example**

```python
>>> mcp = composio.experimental.mcp.generate(
    ...     'user_12345',
    ...     'mcp_67890',
    ...     manually_manage_connections=False
    ... )
    >>>
    >>> print(mcp['url'])  # Server URL for the user
    >>> print(mcp['allowed_tools'])  # Available tools
```

***

[View source](https://github.com/composiohq/composio/blob/next/python/composio/core/models/mcp.py#L88)

---

📚 **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.

