Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ComposioHQ/composio/llms.txt

Use this file to discover all available pages before exploring further.

Composio’s Anthropic provider formats tools as ToolParam objects for Anthropic’s tool_use API. Pass Composio tools to anthropic.messages.create() and execute tool_use content blocks back through composio.provider.handleToolCalls() — the provider handles all extraction and formatting automatically.

Installation

npm install @composio/core @composio/anthropic @anthropic-ai/sdk
Set your API keys in a .env file:
.env
COMPOSIO_API_KEY=your_composio_api_key
ANTHROPIC_API_KEY=your_anthropic_api_key

Example

import { Composio } from '@composio/core';
import { AnthropicProvider } from '@composio/anthropic';
import Anthropic from '@anthropic-ai/sdk';
import 'dotenv/config';

const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

const composio = new Composio({
  apiKey: process.env.COMPOSIO_API_KEY,
  provider: new AnthropicProvider(),
});

async function main() {
  // Tools are returned as ToolParam[] — Claude's native format
  const tools = await composio.tools.get('default', 'HACKERNEWS_GET_USER');

  const messages: Anthropic.Messages.MessageParam[] = [
    {
      role: 'user',
      content: "Fetch the details of the user 'pg' from HackerNews and summarize their profile",
    },
  ];

  let message = await anthropic.messages.create({
    model: 'claude-3-7-sonnet-latest',
    max_tokens: 1024,
    tools,
    messages,
  });

  messages.push({ role: 'assistant', content: message.content });

  // Agentic loop — keep executing tool calls until Claude responds with text
  while (message.stop_reason === 'tool_use') {
    // handleToolCalls extracts tool_use blocks, executes them, and returns
    // formatted tool_result messages ready to append to the conversation
    const toolResults = await composio.provider.handleToolCalls('default', message);
    messages.push(...toolResults);

    message = await anthropic.messages.create({
      model: 'claude-3-7-sonnet-latest',
      max_tokens: 1024,
      tools,
      messages,
    });

    messages.push({ role: 'assistant', content: message.content });
  }

  // Print the final text response
  for (const block of message.content) {
    if (block.type === 'text') {
      console.log(block.text);
    }
  }
}

main();

Handling tool use blocks

When Claude decides to use a tool, the response’s stop_reason is "tool_use" and response.content contains one or more tool_use blocks. Composio’s provider handles this for you:
1

Detect tool use

Check message.stop_reason === 'tool_use' (TypeScript) or response.stop_reason == 'tool_use' (Python) before processing.
2

Execute all tool calls

Call composio.provider.handleToolCalls(userId, message) — it extracts every tool_use block from message.content, executes each one, and returns a list of MessageParam objects with role: 'user' and tool_result content blocks ready to append to your conversation.
3

Continue the conversation

Append the tool results to your messages array and call anthropic.messages.create() again. Repeat until stop_reason is 'end_turn'.
// handleToolCalls returns MessageParam[] — append directly to your messages
const toolResults = await composio.provider.handleToolCalls('user_123', message);
messages.push(...toolResults);

Tool caching

Enable Anthropic’s prompt caching for tools by passing { cacheTools: true } to AnthropicProvider. This adds cache_control: { type: 'ephemeral' } to each tool definition, which can significantly reduce latency and costs for repeated calls with the same tool set.
const composio = new Composio({
  apiKey: process.env.COMPOSIO_API_KEY,
  provider: new AnthropicProvider({ cacheTools: true }),
});

Claude Agent SDK

For the Claude Agent SDK (higher-level agentic framework from Anthropic), use the separate @composio/claude-agent-sdk package:
import { Composio } from '@composio/core';
import { ClaudeAgentSDKProvider } from '@composio/claude-agent-sdk';
import { createSdkMcpServer, query } from '@anthropic-ai/claude-agent-sdk';

const composio = new Composio({
  provider: new ClaudeAgentSDKProvider(),
});

const session = await composio.create('user_123');
const tools = await session.tools();
const toolServer = createSdkMcpServer({ name: 'composio', version: '1.0.0', tools });

for await (const content of query({
  prompt: "Send an email to john@example.com with subject 'Hello'",
  options: {
    mcpServers: { composio: toolServer },
    permissionMode: 'bypassPermissions',
  },
})) {
  if (content.type === 'assistant') {
    console.log('Claude:', content.message);
  }
}

Build docs developers (and LLMs) love