## Summary Depends on #3492. This completes the Phase 2 migration by removing the transitional version-file layer and making `mise.toml` plus `mise.lock` the repository toolchain source of truth. It also moves runtime test matrices into `toolchain-versions.json`, so CI matrix changes are explicit and reviewable without reintroducing `.nvmrc`, `.dvmrc`, `.bun-version`, or `.python-version`. The Node.js e2e matrix now starts at the latest Node 22 LTS line and also covers the latest Node 24 and Node 25 lines. That removes Node 20 from the well-known e2e versions while keeping us covered on the runtimes SDK users are moving toward. ## Rationale Phase 1 introduced mise side by side with the existing version files to keep the first PR low-risk. Phase 2 removes that compatibility layer so there is one place to update tool versions. That avoids silent drift between local setup, GitHub Actions, Docker E2E images, release docs, and install-time checks. The composite setup actions now install Node, Bun, Python, and uv through mise by default, with explicit version overrides only where a matrix needs them. New GitHub actions added in this PR are pinned by release commit SHA and include the release version comment. ## What changed - Deleted the transitional root/version files: `.nvmrc`, `.bun-version`, `.dvmrc`, root `.python-version`, and `python/.python-version`. - Removed `idiomatic_version_file_enable_tools` from `mise.toml` and added a committed `mise.lock` for linux/macOS x64/arm64 tool resolution. - Replaced `BYPASS_BUN_VERSION_CHECK` with `BYPASS_TOOLCHAIN_CHECK`, and made Docker E2E image installs use that bypass because they receive explicit build args instead of installing mise. - Updated Node/Bun and Python/uv composite actions to default to mise, remove `*-version-file` inputs, report resolved versions, and cache pnpm after `corepack enable`. - Centralized CI runtime matrices in `toolchain-versions.json` for TS E2E, Python tests, and CLI npm fallback coverage. - Updated the Node E2E matrix to `22.22.3`, `24.16.0`, and `25.9.0`, removing Node 20 from the well-known runtime versions. - Updated workflows, docs, E2E helpers, Dockerfiles, and release guidance to reference `mise.toml` / `mise.lock`. ## Verification - Verified latest Node 22/24/25 releases from the official Node dist index: `22.22.3`, `24.16.0`, `25.9.0` (https://nodejs.org/dist/index.json). - `pnpm install --frozen-lockfile` - `pnpm --filter @e2e-tests/utils typecheck` - `pnpm --filter @e2e-tests/utils exec tsc --noEmit --target es2022 --module esnext --moduleResolution bundler --types bun --resolveJsonModule --skipLibCheck --strict scripts/docker-build.ts` - `bash -n ts/scripts/pre-install.sh && bun run ts/scripts/pre-install/check-toolchain.ts && BYPASS_TOOLCHAIN_CHECK=1 bash ts/scripts/pre-install.sh` - `pnpm exec prettier --check ...` on touched YAML/Markdown/TS/JSON files - `ruby -e "require \"yaml\"; ARGV.each { |f| YAML.load_file(f) }" ...` on touched actions/workflows - `mise lock --platform linux-x64,linux-arm64,macos-arm64,macos-x64 && git diff --exit-code mise.lock` - `mise exec node@22.22.3 -- pnpm --filter @e2e-tests/utils typecheck` - `mise exec node@22.22.3 -- pnpm --filter @e2e-tests/node-esm-basic typecheck` - `mise exec node@22.22.3 -- pnpm --filter @e2e-tests/node-cjs-basic typecheck` - `docker manifest inspect node:24.16.0-slim` - `docker manifest inspect node:25.9.0-slim` - `git diff --check`
Composio
The Composio Python SDK allows you to interact with the Composio Platform. It provides a powerful and flexible way to manage and execute tools, handle authentication, and integrate with various AI frameworks and platforms.
Learn more about the SDK from our docs
Core Features
- Tools: Manage and execute tools within the Composio ecosystem. Includes functionality to list, retrieve, and execute tools.
- Toolkits: Organize and manage collections of tools for specific use cases.
- Triggers: Create and manage event triggers that can execute tools based on specific conditions.
- AuthConfigs: Configure authentication providers and settings.
- ConnectedAccounts: Manage third-party service connections.
- ActionExecution: Track and manage the execution of actions within the platform.
- Provider Integrations: Built-in support for OpenAI, Anthropic, LangChain, CrewAI, AutoGen, and more.
Installation
pip install composio
# or
pip install composio-core
Provider-Specific Installations
For specific AI framework integrations:
# OpenAI integration
pip install composio-openai
# LangChain integration
pip install composio-langchain
# CrewAI integration
pip install composio-crewai
# Anthropic integration
pip install composio-anthropic
# AutoGen integration
pip install composio-autogen
# And many more...
Getting Started
Basic Usage with OpenAI
import os
from composio import Composio
from openai import OpenAI
# Initialize OpenAI client
openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# Initialize Composio with your API key
composio = Composio(api_key=os.getenv("COMPOSIO_API_KEY"))
def main():
try:
# Fetch tools - single tool or multiple tools
tools = composio.tools.get(user_id="default", slug="HACKERNEWS_GET_USER")
# Or fetch multiple tools: composio.tools.get(user_id="default", toolkits=["hackernews"])
query = "Find information about the HackerNews user 'pg'"
# Create chat completion with tools
response = openai_client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": "You are a helpful assistant that can use tools to answer questions."
},
{"role": "user", "content": query}
],
tools=tools,
tool_choice="auto"
)
# Handle tool calls if the assistant decides to use them
if response.choices[0].message.tool_calls:
print("🔧 Assistant is using tool:", response.choices[0].message.tool_calls[0].function.name)
# Execute the tool call
tool_result = composio.provider.handle_tool_calls(
response=response,
user_id="default"
)
print("✅ Tool execution result:", tool_result)
# Get final response from assistant with tool result
final_response = openai_client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": "You are a helpful assistant that can use tools to answer questions."
},
{"role": "user", "content": query},
response.choices[0].message,
{
"role": "tool",
"tool_call_id": response.choices[0].message.tool_calls[0].id,
"content": str(tool_result)
}
]
)
print("🤖 Final response:", final_response.choices[0].message.content)
else:
print("🤖 Response:", response.choices[0].message.content)
except Exception as error:
print("❌ Error:", error)
if __name__ == "__main__":
main()
Using with Provider Integrations
OpenAI Provider
from composio_openai import OpenAIProvider
from openai import OpenAI
from composio import Composio
# Initialize with OpenAI provider
openai_client = OpenAI()
composio = Composio(provider=OpenAIProvider())
# Define task
task = "Star a repo composiohq/composio on GitHub"
# Get GitHub tools that are pre-configured
tools = composio.tools.get(user_id="default", toolkits=["GITHUB"])
# Get response from the LLM
response = openai_client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": task},
],
)
# Execute the function calls
result = composio.provider.handle_tool_calls(response=response, user_id="default")
print(result)
LangChain Integration
from composio_langchain import ComposioToolSet
from langchain_openai import ChatOpenAI
# Initialize the toolset
toolset = ComposioToolSet()
# Get tools for a specific toolkit
tools = toolset.get_tools(toolkits=["GITHUB"])
# Initialize LLM
llm = ChatOpenAI(model="gpt-4o")
# Create agent with tools
from langchain.agents import create_openai_functions_agent, AgentExecutor
from langchain.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant"),
("user", "{input}"),
("assistant", "{agent_scratchpad}")
])
agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools)
# Execute task
result = agent_executor.invoke({"input": "Star the composiohq/composio repository"})
print(result)
Configuration
The Composio constructor accepts the following configuration options:
from composio import Composio
from composio.core.provider import OpenAIProvider
composio = Composio(
api_key="your-api-key", # Your Composio API key
base_url="https://api.composio.dev", # Custom API base URL (optional)
timeout=60, # Request timeout in seconds
max_retries=3, # Maximum number of retries
allow_tracking=True, # Enable/disable telemetry (default: True)
file_download_dir="./downloads", # Directory for file downloads
provider=OpenAIProvider(), # Custom provider (default: OpenAIProvider)
toolkit_versions={ "github": "12202025_01" } # Toolkit versions to use
)
Modifiers
Composio SDK supports powerful modifiers to transform tool schemas and execution behavior.
Schema Modifiers
Schema modifiers allow you to transform tool schemas before they are used:
from composio import schema_modifier
from composio.types import Tool
@schema_modifier(tools=["HACKERNEWS_GET_USER"])
def modify_schema(tool: str, toolkit: str, schema: Tool) -> Tool:
# Perform modifications on the schema
schema["description"] = "Enhanced HackerNews user lookup with additional features"
schema["parameters"]["properties"]["include_karma"] = {
"type": "boolean",
"description": "Include user karma in response",
"default": True
}
return schema
# Use the modifier when getting tools
tools = composio.tools.get(
user_id="default",
slug="HACKERNEWS_GET_USER",
modifiers=[modify_schema]
)
Execution Modifiers
Transform tool execution behavior with before and after execute modifiers:
from composio import before_execute, after_execute
from composio.types import ToolExecuteParams, ToolExecutionResponse
@before_execute(tools=["HACKERNEWS_GET_USER"])
def before_execute_modifier(
tool: str,
toolkit: str,
params: ToolExecuteParams
) -> ToolExecuteParams:
# Transform input before execution
print(f"Executing {tool} with params: {params}")
return params
@after_execute(tools=["HACKERNEWS_GET_USER"])
def after_execute_modifier(
tool: str,
toolkit: str,
response: ToolExecutionResponse
) -> ToolExecutionResponse:
# Transform output after execution
return {
**response,
"data": {
**response["data"],
"processed_at": "2024-01-01T00:00:00Z"
}
}
# Execute tool with modifiers
response = composio.tools.execute(
user_id="default",
slug="HACKERNEWS_GET_USER",
arguments={"username": "pg"},
modifiers=[before_execute_modifier, after_execute_modifier]
)
Connected Accounts
Composio SDK provides a powerful way to manage third-party service connections through Connected Accounts. This feature allows you to authenticate with various services and maintain those connections.
Creating a Connected Account
from composio import Composio
from composio.types import auth_scheme
composio = Composio(api_key=os.getenv("COMPOSIO_API_KEY"))
# Create a connected account with OAuth
connection_request = composio.connected_accounts.initiate(
user_id="user123",
auth_config_id="ac_12343544", # You can create it from the dashboard
callback_url="https://your-app.com/callback",
data={
# Additional data for the connection
"scope": ["read", "write"]
}
)
# Wait for the connection to be established
# Default timeout is 60 seconds
connected_account = connection_request.wait_for_connection()
print(connected_account)
API Key Authentication
# Create a connected account with API Key
connection_request = composio.connected_accounts.initiate(
user_id="user123",
auth_config_id="ac_12343544",
config=auth_scheme.api_key(
options={
"api_key": "your-api-key-here"
}
)
)
Managing Connected Accounts
# List all connected accounts
accounts = composio.connected_accounts.list(user_id="user123")
# Get a specific connected account
account = composio.connected_accounts.get("account_id")
# Enable/Disable a connected account
composio.connected_accounts.enable("account_id")
composio.connected_accounts.disable("account_id")
# Refresh credentials
composio.connected_accounts.refresh("account_id")
# Delete a connected account
composio.connected_accounts.delete("account_id")
Connection Statuses
Connected accounts can have the following statuses:
ACTIVE: Connection is established and workingINACTIVE: Connection is temporarily disabledPENDING: Connection is being processedINITIATED: Connection request has startedEXPIRED: Connection credentials have expiredFAILED: Connection attempt failed
Tools and Toolkits
Working with Tools
# Get tools by toolkit
tools = composio.tools.get(user_id="default", toolkits=["GITHUB"])
# Get tools by search
tools = composio.tools.get(user_id="default", search="user")
# Get tools by toolkit and search
tools = composio.tools.get(user_id="default", toolkits=["GITHUB"], search="star")
# Execute a tool directly
response = composio.tools.execute(
user_id="default",
slug="HACKERNEWS_GET_USER",
arguments={"username": "pg"}
)
print(response)
Proxy Calls
Make direct API calls through connected accounts:
# Execute proxy call (GitHub API)
proxy_response = composio.tools.proxy(
endpoint="/repos/composiohq/composio/issues/1",
method="GET",
connected_account_id="ac_1234", # Use connected account for GitHub
parameters=[
{
"name": "Accept",
"value": "application/vnd.github.v3+json",
"type": "header"
}
]
)
print(proxy_response)
Authentication Schemes
Composio supports various authentication schemes:
- OAuth2
- OAuth1
- OAuth1a
- API Key
- Basic Auth
- Bearer Token
- Google Service Account
- And more...
Environment Variables
COMPOSIO_API_KEY: Your Composio API keyCOMPOSIO_BASE_URL: Custom API base URLCOMPOSIO_LOGGING_LEVEL: Logging level (silent, error, warn, info, debug)DEVELOPMENT: Development mode flagCOMPOSIO_TOOLKIT_VERSION_<TOOLKITNAME>: Version of the specific toolkitCI: CI environment flag
MCP (Model Context Protocol)
Create MCP servers for seamless integration with Claude, Cursor, and other MCP-compatible tools:
from composio import Composio
composio = Composio()
# Create MCP server
mcp_server = composio.mcp.create(
"my-mcp-server",
toolkits=["github", "gmail"],
manually_manage_connections=False
)
# Generate server instance for a user
server_instance = mcp_server.generate("user123")
print(f"MCP Server URL: {server_instance['url']}")
Supported AI Frameworks
Composio provides dedicated integrations for popular AI frameworks:
- OpenAI - Direct integration with OpenAI's API
- LangChain - Tools and agents for LangChain workflows
- LangGraph - State machine workflows with LangGraph
- CrewAI - Multi-agent systems with CrewAI
- AutoGen - Microsoft's AutoGen framework
- Anthropic - Claude integration
- Google AI - Gemini and other Google AI services
- LlamaIndex - RAG and data framework integration
Error Handling
from composio import Composio
from composio.exceptions import ComposioError, ApiKeyNotProvidedError
try:
composio = Composio() # Will raise ApiKeyNotProvidedError if no API key
tools = composio.tools.get(user_id="default", toolkits=["GITHUB"])
except ApiKeyNotProvidedError:
print("Please provide COMPOSIO_API_KEY environment variable")
except ComposioError as e:
print(f"Composio error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Contributing
We welcome contributions! Please see our Contributing Guide for more details.
License
Apache License 2.0
Support
For support, please visit our Documentation or join our Discord Community.