# How to Create Claude Skills That Utilize Multiple MCP Servers

> Learn to create Claude skills that use multiple MCP servers. Declare servers in .mcp.json and prefix tool calls with server identifiers for seamless orchestration. Get started now!

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

---

**Claude skills orchestrate multiple MCP servers by declaring each server in the plugin's [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json) manifest and prefixing tool calls with the server identifier (e.g., `tres-finance.execute` or `quickdesign.introspect`).**

In the `anthropics/claude-plugins-community` repository, Claude skills run inside plugins that communicate with external services via the Model-Connector-Protocol (MCP). When you create skills that utilize multiple MCP servers, you combine disparate data sources and tools—such as financial ledgers and design generators—into unified workflows.

## Declaring Multiple MCP Servers in [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json)

Before a skill can call an MCP server, the plugin must declare it in the [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json) file at the repository root. This manifest registers each server's endpoint and authentication method.

The structure follows a **servers** object where each key becomes the namespace prefix for tool calls. According to the `anthropics/claude-plugins-community` source code, authentication should reference environment variables using the `env:` prefix to avoid hardcoding secrets.

Here is the configuration structure from the root [`/.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main//.mcp.json):

```json
{
  "servers": {
    "tres-finance": {
      "url": "https://ai.tres.finance/mcp",
      "auth": "env:TRES_TOKEN"
    },
    "quickdesign": {
      "url": "https://app.quickdesign.io/api/mcp",
      "auth": "env:QD_TOKEN"
    }
  }
}

```

This configuration enables the skill runtime to initialize clients for both TRES Finance and QuickDesign simultaneously.

## Namespaced Tool Calls in [`SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/SKILL.md)

To direct a tool call to a specific MCP server, prefix the tool name with the server identifier declared in [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json). This namespace-based routing is the only mechanism the runtime uses to determine which server receives the request.

For example, in [`tres-finance-plugin/skills/tres-report-create/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-report-create/SKILL.md), a skill combines data export from TRES Finance with visual mockup generation from QuickDesign:

```yaml
description: |
  Create a transaction ledger report via the TRES Finance MCP server,
  then generate a visual mock-up of the report using the QuickDesign MCP server.

steps:
  - name: Export report
    tool: tres-finance.execute
    args:
      query: |
        query ExportReport($type: String!) {
          exportReport(type: $type) { id status link }
        }
      variables:
        type: "Ledger"
    store: reportResult

  - name: Build visual mock-up
    when: "{{ user asks for a visual }}"
    tool: quickdesign.execute
    args:
      action: "createMockup"
      payload:
        title: "Ledger Report"
        dataUrl: "{{ reportResult.data.exportReport.link }}"
    store: designResult

```

Notice how `tres-finance.execute` targets the first server while `quickdesign.execute` targets the second.

## Orchestrating Multi-Server Logic in Python

For complex workflows requiring conditional logic or polling, implement the orchestration in Python using the `McpClient` class. The script [`tres-finance-plugin/skills/tres-report-create/scripts/run_report_matrix.py`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-report-create/scripts/run_report_matrix.py) demonstrates initializing separate clients for each declared server:

```python
import os
from claude_plugin import McpClient

# Initialise clients for each declared server

tres = McpClient(
    url="https://ai.tres.finance/mcp",
    token=os.getenv("TRES_TOKEN")
)
qd = McpClient(
    url="https://app.quickdesign.io/api/mcp",
    token=os.getenv("QD_TOKEN")
)

def create_report_and_mockup():
    # 1️⃣ Export the report via TRES

    export = tres.execute("""query ExportReport($type: String!) {
        exportReport(type: $type) { id status link }
    }""", {"type": "Ledger"})
    report_id = export["data"]["exportReport"]["id"]

    # 2️⃣ Poll until DONE

    while True:
        status = tres.execute("""query GetStatus($id: ID!) {
            reportStatus(id: $id) { status }
        }""", {"id": report_id})
        if status["data"]["reportStatus"]["status"] == "DONE":
            break
        time.sleep(2)

    link = export["data"]["exportReport"]["link"]

    # 3️⃣ Ask QuickDesign to build a mock-up

    mockup = qd.execute("""mutation CreateMockup($title: String!, $url: String!) {
        createMockup(title: $title, dataUrl: $url) { url }
    }""", {"title": "Ledger Report", "url": link})

    return {
        "reportLink": link,
        "designUrl": mockup["data"]["createMockup"]["url"]
    }

```

This approach allows you to stitch together data from multiple GraphQL endpoints, handling errors for each server independently so a failure in one does not cascade to others.

## Authentication and Environment Variables

Each MCP server may require distinct credentials. The [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json) manifest supports the `env:` prefix to reference environment variables securely. For example, [`tres-finance-plugin/.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/.mcp.json) and [`testdino/.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/testdino/.mcp.json) in the community repository demonstrate this pattern.

Never commit tokens to version control. Instead, define them in your runtime environment:

```bash
export TRES_TOKEN="your_tres_api_key"
export QD_TOKEN="your_quickdesign_key"

```

The skill runtime injects these values at execution time, keeping sensitive data out of skill definitions and source code.

## Summary

- Declare every MCP server in the root [`/.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main//.mcp.json) with a unique namespace key and `env:`-prefixed authentication.
- Reference tools using the `<server>.<tool>` syntax (e.g., `tres-finance.execute`) to route calls to the correct server.
- Combine multiple servers in a single [`SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/SKILL.md) workflow or Python orchestration script to fetch, process, and transform data across services.
- Implement error handling around individual server calls to prevent one failure from aborting the entire skill execution.
- Store credentials in environment variables and reference them via the manifest—never hardcode secrets in skills or scripts.

## Frequently Asked Questions

### Can a single Claude skill call more than two MCP servers?

Yes. The [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json) manifest supports declaring any number of servers. Each additional server requires a unique namespace identifier and authentication configuration. Within the skill logic, you can chain calls across three, four, or more servers by prefixing each tool invocation with the appropriate server name.

### What happens if one MCP server fails during a multi-server skill execution?

The skill runtime processes each tool call independently. If you implement error handling—such as checking for error keys in JSON responses or using try-catch blocks in Python orchestration scripts—the skill can continue executing subsequent steps or return partial results. Without explicit error handling, a failed GraphQL call may raise an exception that halts the skill.

### How does the skill runtime know which server to contact?

The runtime uses the namespace prefix in the tool name. When you specify `quickdesign.execute`, the runtime strips the prefix and routes the request to the URL defined under the `quickdesign` key in [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json). If the prefix does not match any declared server, the skill execution fails with a configuration error.

### Do all MCP servers use GraphQL, or can they expose REST endpoints?

The examples in `anthropics/claude-plugins-community`, such as [`tres-finance-plugin/skills/tres-report-create/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-report-create/SKILL.md), demonstrate GraphQL-based tools using the `execute` method. However, the MCP protocol itself is transport-agnostic. The specific tools available (e.g., `execute`, `introspect`, `get_viewer`) depend on the individual server's implementation declared in its schema.