How to Integrate with Anthropic Claude Using @composio/anthropic: A Complete Guide

The @composio/anthropic package provides a non-agentic provider that automatically wraps Composio tools for Claude, handles tool execution, and manages optional caching through the AnthropicProvider class.

The Composio ecosystem enables AI agents to interact with external APIs through standardized tools. For developers building with Anthropic's Claude models, the @composio/anthropic package bridges Claude's native function calling capabilities with Composio's tool registry. This integration is implemented in the ComposioHQ/composio repository and allows you to leverage Claude's reasoning while Composio handles authentication, execution, and result formatting.

Understanding the AnthropicProvider Architecture

The provider architecture centers on extending BaseNonAgenticProvider from @composio/core, implementing specific adapters for Anthropic's API requirements.

Core Provider Implementation

In ts/packages/providers/anthropic/src/index.ts, the AnthropicProvider class extends BaseNonAgenticProvider and implements three critical responsibilities:

  • wrapTool / wrapTools – Converts Composio Tool definitions into Anthropic's tool schema (AnthropicTool). The conversion injects the tool's name, description, input_schema, and optional cache_control when caching is enabled.

  • executeToolCall – Receives a Claude tool_use block, builds a ToolExecuteParams payload, forwards it to the generic executeTool method supplied by the base class, and returns the JSON-stringified result.

  • handleToolCalls – Scans an Anthropic Message for all tool_use blocks, runs each via executeToolCall, and returns an array of tool_result blocks that Claude can consume in a follow-up message.

Ephemeral Caching Support

When cacheTools: true is passed to the constructor, every tool description includes cache_control: { type: 'ephemeral' }. This allows Claude to reuse tool results within a session, reducing latency and token consumption for repeated operations.

Implementing the Integration Pattern

The typical integration flow involves initializing the Anthropic SDK, configuring Composio with the Anthropic provider, and managing the request-response cycle.

Basic Setup and Initialization

First, instantiate the Anthropic SDK and Composio with the provider:

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

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

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

Fetching and Wrapping Tools

Fetch tools from the Composio registry. The provider automatically wraps them for Claude's API:

const tools = await composio.tools.get('default', 'HACKERNEWS_GET_USER');

The wrapTools method in ts/packages/providers/anthropic/src/index.ts converts these into Anthropic-compatible tool definitions with proper input_schema formatting.

Handling Tool Calls and Responses

Send a message to Claude with the wrapped tools:

const firstMsg = await anthropic.messages.create({
  model: 'claude-3-7-sonnet-latest',
  max_tokens: 1024,
  tools,
  messages: [{ role: 'user', content: "Get and summarize Hacker News user 'pg'" }],
});

If Claude returns tool_use blocks, execute them through Composio:

if (firstMsg.content.some(c => c.type === 'tool_use')) {
  const toolResults = await composio.provider.handleToolCalls('default', firstMsg);
  
  // Append results and get final response
  const conversation = [
    { role: 'user', content: "Get and summarize Hacker News user 'pg'" },
    { role: 'assistant', content: firstMsg.content },
    ...toolResults,
  ];
  
  const finalMsg = await anthropic.messages.create({
    model: 'claude-3-7-sonnet-latest',
    max_tokens: 1024,
    messages: conversation,
  });
  
  console.log(finalMsg.content.filter(c => c.type === 'text').map(c => c.text).join('\n'));
}

Working with Streaming Responses

For real-time applications, handle streaming tool calls using the executeToolCall method directly:

const stream = await anthropic.messages.stream({
  model: 'claude-3-sonnet-20240229',
  max_tokens: 1024,
  tools,
  messages: [{ role: 'user', content: 'Send an email to support@example.com saying thanks.' }],
});

for await (const chunk of stream) {
  if (chunk.type === 'content_block_delta' && chunk.delta.type === 'tool_calls') {
    const toolCall = chunk.delta;
    const result = await composio.provider.executeToolCall(
      'default',
      toolCall as any,
      { connectedAccountId: 'my-gmail-account' }
    );
    console.log('Tool result:', result);
  }
}

This pattern, demonstrated in ts/examples/anthropic/src/streaming.ts, processes tool calls as they arrive in the stream rather than waiting for the complete response.

Summary

  • The @composio/anthropic package extends BaseNonAgenticProvider to bridge Composio tools with Anthropic's Claude API.
  • Automatic tool wrapping converts Composio definitions into Anthropic-compatible schemas via wrapTool and wrapTools in ts/packages/providers/anthropic/src/index.ts.
  • Execution handling is managed through executeToolCall for individual tools and handleToolCalls for batch processing complete messages.
  • Ephemeral caching reduces token usage when cacheTools: true is enabled, adding cache_control headers to tool definitions.
  • Streaming support allows real-time tool execution during Claude's response generation, as shown in ts/examples/anthropic/src/streaming.ts.

Frequently Asked Questions

What is the difference between the agentic and non-agentic providers in Composio?

The non-agentic provider, such as AnthropicProvider, implements BaseNonAgenticProvider and gives you direct control over the LLM client and message flow. You manually invoke anthropic.messages.create() and handle tool calls via composio.provider.handleToolCalls(). Agentic providers, conversely, manage the entire conversation loop internally, automatically deciding when to call tools and continuing the dialogue without manual intervention.

How does tool caching work with the Anthropic provider?

When you instantiate AnthropicProvider with cacheTools: true, the wrapTool method automatically injects cache_control: { type: 'ephemeral' } into every tool definition's description. This Anthropic-specific feature allows Claude to cache tool definitions and results within a session, reducing latency and token consumption for subsequent tool calls. The implementation resides in ts/packages/providers/anthropic/src/index.ts at lines 29-30.

Can I use the Anthropic provider with streaming responses?

Yes, the provider supports streaming through the executeToolCall method. As demonstrated in ts/examples/anthropic/src/streaming.ts, you can use anthropic.messages.stream() and process content_block_delta chunks in real-time. When a chunk contains a tool_use block, you immediately invoke composio.provider.executeToolCall() to execute the tool and return results without waiting for the complete response.

What file handles the core tool wrapping logic for Claude?

The core implementation is located at ts/packages/providers/anthropic/src/index.ts. This file defines the AnthropicProvider class and its methods: wrapTool, wrapTools, executeToolCall, and handleToolCalls. It also handles the conversion between Composio's internal tool definitions and Anthropic's expected tool schema format, including the optional ephemeral caching headers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →