# How to Integrate External APIs with Claude Plugins: A Complete Developer Guide

> Learn to integrate external APIs with Claude plugins. This guide covers declaring dependencies, reading secrets, and returning JSON data for seamless integration. Get started today.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: how-to-guide
- Published: 2026-09-13

---

**Claude plugins integrate external APIs by declaring HTTP client dependencies in [`requirements.txt`](https://github.com/anthropics/claude-plugins-community/blob/main/requirements.txt), reading secrets via environment variables, and returning JSON-serializable data from a standard `run` function.**

Claude plugins in the `anthropics/claude-plugins-community` repository are self-contained skill bundles that extend Claude's capabilities with external data sources. To integrate external APIs with Claude plugins, developers package HTTP client libraries with their skills, secure API keys through environment variables, and implement a standardized `run` function that transforms third-party responses into structured JSON outputs.

## Understanding the Plugin Architecture

Each Claude plugin lives in its own directory and functions as an isolated skill bundle. The runtime loads these plugins at execution time based on a declarative manifest and executes them within isolated containers.

### The Plugin Manifest

Every plugin requires a manifest file located at `. claude-plugin/plugin.json` in the plugin root. This JSON file describes the plugin's metadata, including its name, version, author, and entry points. Refer to [`quickdesign/.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/quickdesign/.claude-plugin/plugin.json) in the community repository for the exact schema, which specifies required fields such as `name`, `version`, `description`, and `icon`.

### Dependency Management

External API integration requires third-party HTTP clients such as `requests` or `httpx`. These dependencies must be declared in a [`requirements.txt`](https://github.com/anthropics/claude-plugins-community/blob/main/requirements.txt) file placed in the plugin root directory. The Claude validation workflow automatically installs these packages before the skill executes, ensuring all network libraries are available in the isolated runtime environment.

## The 4-Step API Integration Flow

Integrating external APIs with Claude plugins follows a consistent pattern across all skill implementations.

### Step 1: Declare HTTP Dependencies

Add your chosen HTTP client to [`requirements.txt`](https://github.com/anthropics/claude-plugins-community/blob/main/requirements.txt) in the plugin root. For standard synchronous requests, include:

```text
requests

```

The Claude runtime's validation pipeline will install this package during the deployment process.

### Step 2: Secure Configuration Handling

Never hard-code API keys or tokens in your source code. Instead, read sensitive configuration from environment variables using `os.getenv`. The runtime injects user-provided environment variables into the isolated container before execution.

```python
import os

api_key = os.getenv("OPENWEATHER_API_KEY")
if not api_key:
    raise RuntimeError("Missing OpenWeather API key")

```

This approach ensures secrets remain out of source control while remaining accessible to your skill logic.

### Step 3: Implement HTTP Requests

Use your declared HTTP client to call external endpoints, implementing proper timeout and error handling. The Claude runtime permits networking according to platform policies, but your code should handle connection failures gracefully.

```python
import requests

url = "https://api.openweathermap.org/data/2.5/weather"
params = {"q": city, "appid": api_key, "units": "metric"}
resp = requests.get(url, params=params, timeout=10)
resp.raise_for_status()
data = resp.json()

```

### Step 4: Return JSON-Serializable Data

Claude expects all plugin outputs to be JSON-serializable structures—strings, numbers, lists, or dictionaries. Transform raw API responses into clean, user-friendly formats before returning them from your entry point function.

## Complete Implementation Example: Weather Plugin

The following example demonstrates a complete weather plugin that fetches current temperatures from the OpenWeatherMap API.

### Skill Implementation

Create the skill file at [`weather_plugin/skills/get_weather.py`](https://github.com/anthropics/claude-plugins-community/blob/main/weather_plugin/skills/get_weather.py):

```python
import os
import json
import requests

def run(input: dict) -> dict:
    """Claude entry point.

    Args:
        input: {"city": "San Francisco"}

    Returns:
        {"city": "...", "temperature_c": ..., "description": "..."}
    """
    city = input.get("city", "London")
    api_key = os.getenv("OPENWEATHER_API_KEY")
    if not api_key:
        raise RuntimeError("Missing OpenWeather API key")

    url = "https://api.openweathermap.org/data/2.5/weather"
    params = {"q": city, "appid": api_key, "units": "metric"}
    resp = requests.get(url, params=params, timeout=10)
    resp.raise_for_status()
    data = resp.json()

    result = {
        "city": data["name"],
        "temperature_c": data["main"]["temp"],
        "description": data["weather"][0]["description"],
    }
    return result

```

### Plugin Structure

Organize your plugin with the following file layout:

- [`weather_plugin/.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/weather_plugin/.claude-plugin/plugin.json) – Manifest declaring the entry point ([`skills/get_weather.py`](https://github.com/anthropics/claude-plugins-community/blob/main/skills/get_weather.py))
- [`weather_plugin/requirements.txt`](https://github.com/anthropics/claude-plugins-community/blob/main/weather_plugin/requirements.txt) – Contains `requests`
- [`weather_plugin/skills/get_weather.py`](https://github.com/anthropics/claude-plugins-community/blob/main/weather_plugin/skills/get_weather.py) – The Python module implementing the `run` function
- [`weather_plugin/README.md`](https://github.com/anthropics/claude-plugins-community/blob/main/weather_plugin/README.md) – Documentation describing required environment variables

The manifest does not require special fields for external API calls; it only needs to specify the reachable entry point for the skill code.

## Security and Marketplace Validation

Before publishing to the `anthropics/claude-plugins-community` marketplace, your plugin must pass automated security scans. The Claude runtime executes skills in isolated containers with networking capabilities subject to platform policies. Ensure your implementation:

- Validates all external inputs
- Implements reasonable request timeouts
- Never logs or exposes API keys
- Handles HTTP error status codes gracefully

## Summary

- **Declare dependencies** in [`requirements.txt`](https://github.com/anthropics/claude-plugins-community/blob/main/requirements.txt) using standard Python package names like `requests` or `httpx`
- **Secure API credentials** by reading environment variables with `os.getenv` rather than hard-coding secrets
- **Implement the `run` function** at [`skills/your_module.py`](https://github.com/anthropics/claude-plugins-community/blob/main/skills/your_module.py) to accept a dictionary input and return a JSON-serializable dictionary
- **Structure your plugin** with a manifest at [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) referencing the correct entry point
- **Handle networking defensively** with timeouts and error checking, as the runtime executes your code in an isolated container

## Frequently Asked Questions

### How do I store API keys securely in Claude plugins?

Store API keys as environment variables that users configure when installing the plugin. Access these secrets within your Python code using `os.getenv("YOUR_API_KEY")`. This method keeps credentials out of source control and allows different users to provide their own authentication tokens.

### What HTTP libraries are supported for external API calls?

You can use any Python HTTP client library available on PyPI, including `requests`, `httpx`, `aiohttp`, or `urllib3`. Simply add the package name to your [`requirements.txt`](https://github.com/anthropics/claude-plugins-community/blob/main/requirements.txt) file. The Claude validation workflow installs these dependencies before your skill executes in the isolated runtime container.

### Does the plugin manifest require special fields for external API integration?

No, the manifest at [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) uses the same schema regardless of whether the plugin calls external APIs. The manifest only needs to declare standard metadata—name, version, description, icon—and specify the correct entry point file path where the `run` function is defined.

### What happens if an external API request times out or fails?

Your plugin should implement standard HTTP error handling using `try/except` blocks or the error methods provided by your HTTP client (such as `resp.raise_for_status()`). Claude expects your `run` function to return a valid dictionary or raise an exception; uncaught errors will fail the skill execution and return an error message to the user.