> ## Documentation Index
> Fetch the complete documentation index at: https://docs.idun-group.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker MCP toolkit

> Add external tool capabilities to your agents using pre-built MCP servers from the Docker MCP toolkit.

The Docker MCP toolkit is a collection of pre-built MCP servers packaged as Docker containers. These servers provide common functionality (web fetching, file system access, database operations) without requiring you to write or maintain custom MCP server code.

* **No custom code**: Pull and run pre-configured MCP servers
* **Isolation**: Each server runs in its own container with controlled resource limits
* **Community-maintained**: Implementations follow the MCP specification
* **Portable**: Works the same in development and production

This guide walks through integrating the Fetch MCP server from the Docker toolkit with an existing agent.

<Info>
  By the end of this guide, you will have an agent that can retrieve and analyze content from any URL through the Fetch MCP tool.
</Info>

## Prerequisites

Before starting, you need:

* A working agent deployed with Idun (see the [quickstart](/quickstart))
* [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed and running

Pull the Fetch MCP server image:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
docker pull mcp/fetch
```

## Set up the Fetch MCP server

<Steps>
  <Step title="Configure Docker Desktop">
    Open Docker Desktop and verify:

    1. Docker Desktop is running
    2. The `mcp/fetch` image appears in the **Images** section
  </Step>

  <Step title="Register the MCP server">
    Add the Fetch server to your standalone, either through the admin panel or in YAML.

    **Admin UI:** open `/admin/mcp/` and click **stdio**. Fill in:

    | Field       | Value                                |
    | ----------- | ------------------------------------ |
    | **Name**    | `fetch`                              |
    | **Command** | `docker`                             |
    | **Args**    | `["run", "-i", "--rm", "mcp/fetch"]` |

    **`config.yaml`:**

    ```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
    mcp_servers:
      - name: fetch
        transport: stdio
        command: docker
        args: ["run", "-i", "--rm", "mcp/fetch"]
    ```

    The args breakdown:

    * `run`: Execute a new container
    * `-i`: Interactive mode (keeps STDIN open for MCP communication)
    * `--rm`: Remove container when it stops
    * `mcp/fetch`: The Docker image to run

    Save (admin UI) or restart `idun serve` (YAML). The engine discovers the Fetch server's tools at boot.
  </Step>

  <Step title="Integrate MCP tools in your agent code">
    Import MCP tools in your agent code:

    <Tabs>
      <Tab title="ADK">
        ```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
        from google.adk.agents import LlmAgent
        from idun_agent_engine.mcp import get_adk_tools
        import os

        os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "TRUE"
        os.environ["GOOGLE_CLOUD_PROJECT"] = "your-project-id"
        os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1"

        def get_current_time(city: str) -> dict:
            """Returns the current time in a specified city."""
            return {"status": "success", "city": city, "time": "10:30 AM"}

        idun_tools = get_adk_tools()
        tools = [get_current_time] + idun_tools

        root_agent = LlmAgent(
            model="gemini-2.5-flash",
            name="root_agent",
            description="Tells the current time in a specified city.",
            instruction="You are a helpful assistant.",
            tools=tools,
        )
        ```
      </Tab>

      <Tab title="LangGraph">
        ```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
        from langgraph.prebuilt import create_react_agent
        from langchain_openai import ChatOpenAI
        from idun_agent_engine.mcp import get_langchain_tools

        model = ChatOpenAI(model="gpt-4")

        mcp_tools = await get_langchain_tools()

        agent = create_react_agent(
            model=model,
            tools=mcp_tools,
            state_modifier="You are a helpful assistant with access to web content fetching.",
        )
        ```
      </Tab>
    </Tabs>

    `get_adk_tools()` and `get_langchain_tools()` discover every MCP server in the engine config and make their tools available. You do not need to configure individual tools.
  </Step>

  <Step title="Launch the agent">
    From your agent directory:

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    idun serve
    ```

    The engine reads its config from the DB, starts the Fetch MCP server as a Docker container, registers the fetch tool with your agent, and serves the chat UI at `http://localhost:8000/`.
  </Step>

  <Step title="Test MCP integration">
    Open `http://localhost:8000/` and use the chat to test:

    ```
    Give me the information on this website: https://www.idun-group.com/idun-agent-platform
    ```

    ```
    Go to https://news.ycombinator.com and summarize the top 3 stories
    ```

    ```
    Fetch https://github.com/trending and list the trending repositories
    ```

    When you send a query, the agent recognizes it needs web content, invokes the Fetch MCP tool, and the Docker container retrieves the URL content for the agent to analyze.
  </Step>
</Steps>

## Verify the MCP server

Check that the Docker container is running:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
docker ps | grep mcp/fetch
```

View MCP server logs for debugging:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
docker logs $(docker ps -q --filter ancestor=mcp/fetch)
```

## Advanced configuration

### Multiple MCP servers

Add more MCP servers through `/admin/mcp/` or in the same `mcp_servers` list in `config.yaml`. Each entry runs alongside the others and contributes its tools to the registry.

**Filesystem access:**

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
- name: filesystem
  transport: stdio
  command: npx
  args: ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"]
```

Allows the agent to read, write, and manipulate files within specified directories.

**Custom Docker MCP server:**

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
- name: custom
  transport: stdio
  command: docker
  args: ["run", "-i", "--rm", "your-registry/your-mcp:latest"]
```

Deploy your own MCP servers for database access, API integrations, or internal tools.

## Troubleshooting

<AccordionGroup>
  <Accordion title="MCP server fails to connect">
    **Symptoms:** Agent starts but MCP tools are not available.

    **Solutions:**

    * Verify Docker Desktop is running: `docker info`
    * Check the image exists: `docker images | grep mcp/fetch`
    * Test the container manually: `docker run -i --rm mcp/fetch`
    * Review Docker Desktop logs
  </Accordion>

  <Accordion title="Agent does not use the fetch tool">
    **Symptoms:** Agent responds but does not fetch web content.

    **Solutions:**

    * Check Docker container is running: `docker ps | grep mcp/fetch`
    * Review MCP server logs: `docker logs <container_id>`
    * Try an explicit query: "Use the fetch tool to get [https://example.com](https://example.com)"
    * Restart the agent
    * Verify the MCP config saved correctly in `/admin/mcp/` or in your `config.yaml`
  </Accordion>

  <Accordion title="Args format invalid">
    **Symptoms:** "Invalid args format" error when saving.

    **Solution:** Args must be a properly formatted JSON array.

    Correct:

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    ["run", "-i", "--rm", "mcp/fetch"]
    ```

    Incorrect:

    ```
    run -i --rm mcp/fetch
    ```

    Incorrect:

    ```
    ["run -i --rm mcp/fetch"]
    ```
  </Accordion>
</AccordionGroup>

## Best practices

* **Naming**: Use descriptive, lowercase names for MCP servers: `fetch`, `filesystem`, `database`
* **Incremental testing**: Add one MCP server at a time. Test functionality before adding more
* **Resource limits**: In production, set Docker resource constraints to prevent runaway usage:
  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  ["run", "-i", "--rm", "--memory=512m", "--cpus=0.5", "mcp/fetch"]
  ```
* **Logging**: Configure Docker logging for better observability:
  ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
  ["run", "-i", "--rm", "--log-driver=json-file", "--log-opt=max-size=10m", "mcp/fetch"]
  ```
* **Credentials**: Never hardcode sensitive information in MCP configurations. Use environment variables
* **Monitoring**: Use [observability](/observability/overview) to track MCP server latency and error rates

## Next steps

<Card title="MCP Servers overview" icon="plug" horizontal href="/mcp-servers/overview">
  How the engine discovers and registers MCP tools.
</Card>

<Card title="Observability" icon="activity" horizontal href="/observability/overview">
  Trace MCP tool calls alongside agent runs.
</Card>

<Card title="Troubleshooting" icon="life-buoy" horizontal href="/troubleshooting">
  Diagnose container and transport failures.
</Card>
