AI Guide to the Galaxy: MCP Toolkit and Gateway, Explained

This is an abridged version of the interview we had in AI Guide to the Galaxy, where host Oleg Šelajev spoke with Jim Clark, Principal Software Engineer at Docker, to unpack Docker’s MCP Toolkit and MCP Gateway.

TL;DR

What they are: The MCP Toolkit helps you discover, run, and manage MCP servers; the MCP Gateway unifies and securely exposes them to your agent clients.

Why Docker: Everything runs as containers with supply-chain checks, secret isolation, and OAuth support.

How to use: Pick servers from the MCP Catalog, start the MCP Gateway, and your client (e.g., Claude) instantly sees the tools.

First things first: if you want the official overview and how-tos, start with the Docker MCP Catalog and Toolkit.

A quick origin story (why MCP and Docker?)

Oleg: You’ve been deep in agents for a while. Where did this all start?

Jim: When tool calling arrived, we noticed something simple but powerful: tools look a lot like containers. So we wrapped tools in Docker images, gave agents controlled “hands,” and everything clicked. That was even before the Model Context Protocol (MCP) spec landed. When Anthropic published MCP, it put a name to what we were already building.

What the MCP Toolkit actually solves

Oleg: So, what problem does the Toolkit solve on day one?

Jim: Installation and orchestration. The Toolkit gives you a catalog of MCP servers (think: YouTube transcript, Brave search, Atlassian, etc.) packaged as containers and ready to run. No cloning, no environment drift. Just grab the image, start it, and go. As Docker builds these images and publishes them to Hub, you get consistency and governance on pull.

Oleg: And it presents a single, client-friendly surface?

Jim: Exactly. The Toolkit can act as an MCP server to clients, aggregating whatever servers you enable so clients can list tools in one place.

How the MCP Gateway fits in

Oleg: I see “Toolkit” inside Docker Desktop. Where does the MCP Gateway come in?

Jim: The Gateway is a core piece inside the Toolkit: a process (and open source project) that unifies which MCP servers are exposed to which clients. The CLI and UI manage both local containerized servers and trusted remote MCP servers. That way you can attach a client, run through OAuth where needed, and use those remote capabilities securely via one entry point.

Oleg: Can we see it from a client’s perspective?

Jim: Sure. Fire up the Gateway, connect Claude, run mcp list, and you’ll see the tools (e.g., Brave Web Search, Get Transcript) available to that session, backed by containers the Gateway spins up on demand.

Security: provenance, secrets, and OAuth without drama

Oleg: What hardening happens before a server runs?

Jim: On pull/run, we do provenance verification, ensuring Docker built the image, checking for an SBOM, and running supply-chain checks (via Docker Scout) so you’re not executing something tampered with.

Oleg: And credentials?

Jim: Secrets you add (say, for Atlassian) are mounted only into the target container at runtime, nothing else can see them. For remote servers, the Gateway can handle OAuth flows, acquiring or proxying tokens into the right container or request path. It’s two flavors of secret management: local injection and remote OAuth, both controlled from Docker Desktop and the CLI.

Profiles, filtering, and “just the tools I want”

Oleg: If I have 30 servers, can I scope what a given client sees?

Jim: Yes. Choose the servers per Gateway run, then filter tools, prompts, and resources so the client only gets the subset you want. Treat it like “profiles” you can version alongside your code; compose files and config make it repeatable for teams. You can even run multiple gateways for different configurations (e.g., “chess tools” vs. “cloud ops tools”).

From local dev to production (and back again)

Oleg: How do I move from tinkering to something durable?

Jim: Keep it Compose-first. The Gateway and servers are defined as services in your compose files, so your agent stack is reproducible. From there, push to cloud: partners like Google Cloud Run already support one-command deploys from Compose, with Azure integrations in progress. Start locally, then graduate to remote runs seamlessly.

Oleg: And choosing models?

Jim: Experiment locally, swap models as needed, and wire in the MCP tools that fit your agent’s job. The pattern is the same: pick models, pick tools, compose them, and ship.

Getting started with MCP Gateway (in minutes)

Oleg: Summarize the path for me.

Jim:

Pick servers from the catalog in Docker Desktop (or CLI).

Start the MCP Gateway and connect your client.

Add secrets or flow through OAuth as needed.

Filter tools into a profile.

Capture it in Compose and scale out.

Why the MCP Toolkit and Gateway improve team workflows

Fast onboarding: No glue code or conflicting envs, servers come containerized.

Security built-in: Supply-chain checks and scoped secret access reduce risk.

One workflow: Local debug, Compose config, cloud deploys. Same primitives, fewer rewrites.

Try it out

Spin up your first profile and point your favorite client at the Gateway. When you’re ready to expand your agent stack, explore tooling like Docker Desktop for local iteration and Docker Offload for on-demand cloud resources — then keep everything declarative with Compose.

Ready to build? Explore the Docker MCP Catalog and Toolkit to get started.

Learn More

Watch the rest of the AI Guide to the Galaxy series

Explore the MCP Catalog: Discover containerized, security-hardened MCP servers

Open Docker Desktop and get started with the MCP Toolkit (Requires version 4.48 or newer to launch the MCP Toolkit automatically)

Check out our latest guide on how to setup Claude Code with Docker’s MCP Toolkit

Quelle: https://blog.docker.com/feed/

Your Org, Your Tools: Building a Custom MCP Catalog

I’m Mike Coleman, a staff solutions architect at Docker. In this role, I spend a lot of time talking to enterprise customers about AI adoption. One thing I hear over and over again is that these companies want to ensure appropriate guardrails are in place when it comes to deploying AI tooling. 

For instance, many organizations want tighter control over which tools developers and AI assistants can access via Docker’s Model Context Protocol (MCP) tooling. Some have strict security policies that prohibit pulling images directly from Docker Hub. Others simply want to offer a curated set of trusted MCP servers to their teams or customers.

In this post, we walk through how to build your own MCP catalog. You’ll see how to:

Fork Docker’s official MCP catalog

Host MCP server images in your own container registry

Publish a private catalog

Use MCP Gateway to expose those servers to clients

Whether you’re pulling existing MCP servers from Docker’s MCP Catalog or building your own, you’ll end up with a clean, controlled MCP environment that fits your organization.

Introducing Docker’s MCP Tooling

Docker’s MCP ecosystem has three core pieces:

MCP Catalog

A YAML-based index of MCP server definitions. These describe how to run each server and what metadata (description, image, repo) is associated with it. The MCP Catalog hosts over 220+ containerized MCP servers, ready to run with just a click. 

The official docker-mcp catalog is read-only. But you can fork it, export it, or build your own.

MCP Gateway

The MCP Gateway connects your clients to your MCP servers. It doesn’t “host” anything — the servers are just regular Docker containers. But it provides a single connection point to expose multiple servers from a catalog over HTTP SSE or STDIO.

Traditionally, with X servers and Y clients, you needed X * Y configuration entries. MCP Gateway reduces that to just Y entries (one per client). Servers are managed behind the scenes based on your selected catalog.

You can start the gateway using a specific catalog:

docker mcp gateway run –catalog my-private-catalog

MCP Gateway is open source: https://github.com/docker/mcp-gateway

Figure 1: The MCP Gateway provides a single connection point to expose multiple MCP servers

MCP Toolkit (GUI)

Built into Docker Desktop, the MCP Toolkit provides a graphical way to work with the MCP Catalog and MCP Gateway. This allows you to:

Access to Docker’s MCP Catalog via a rich GUI

Secure handling of secrets (like GitHub tokens)

Easily enable MCP servers

Connect your selected MCP servers with one click to a variety of clients like Claude code, Claude Desktop, Codex, Cursor, Continue.dev, and Gemini CLI

Workflow Overview

The workflow below will show you the steps necessary to create and use a custom MCP catalog. 

The basic steps are:

Export the official MCP Catalog to inspect its contents

Fork the Catalog so you can edit it

Create your own private catalog

Add specific server entries

Pull (or rebuild) images and push them to your registry

Update your catalog to use your images

Run the MCP Gateway using your catalog

Connect clients to it

Step-by-Step Guide: Creating and Using a Custom MCP Catalog

We start by setting a few environment variables to make this process repeatable and easy to modify later.For the purpose of this example, assume we are migrating an existing MCP server (DuckDuckGo) to a private registry (ghcr.io/mikegcoleman). You can also add your own custom MCP server images into the catalog, and we mention that below as well. 

export MCP_SERVER_NAME="duckduckgo"
export GHCR_REGISTRY="ghcr.io"
export GHCR_ORG="mikegcoleman"
export GHCR_IMAGE="${GHCR_REGISTRY}/${GHCR_ORG}/${MCP_SERVER_NAME}:latest"
export FORK_CATALOG="my-fork"
export PRIVATE_CATALOG="my-private-catalog"
export FORK_EXPORT="./my-fork.yaml"
export OFFICIAL_DUMP="./docker-mcp.yaml"
export MCP_HOME="${HOME}/.docker/mcp"
export MCP_CATALOG_FILE="${MCP_HOME}/catalogs/${PRIVATE_CATALOG}.yaml"

Step 1: Export the official MCP Catalog 

Exporting the official Docker MCPCatalog gives you a readable local YAML file listing all servers. This makes it easy to inspect metadata like images, descriptions, and repository sources outside the CLI.

docker mcp catalog show docker-mcp –format yaml > "${OFFICIAL_DUMP}"

Step 2: Fork the official MCP Catalog

Forking the official catalog creates a copy you can modify. Since the built-in Docker catalog is read-only, this fork acts as your editable version.

docker mcp catalog fork docker-mcp "${FORK_CATALOG}"
docker mcp catalog ls

Step 3: Create a new catalog

Now create a brand-new catalog that will hold only the servers you explicitly want to support. This ensures your organization runs a clean, controlled catalog that you fully own.

docker mcp catalog create "${PRIVATE_CATALOG}"

Step 4: Add specific server entries

Export your forked catalog to a file so you can copy over just the entries you want. Here we’ll take only the duckduckgo server and add it to your private catalog.

docker mcp catalog export "${FORK_CATALOG}" "${FORK_EXPORT}"
docker mcp catalog add "${PRIVATE_CATALOG}" "${MCP_SERVER_NAME}" "${FORK_EXPORT}"

Step 5: Pull (or rebuild) images and push them to your registry

At this point you have two options:

If you are able to pull from Docker Hub, find the image key for the server you’re interested in by looking at the YAML file you exported earlier. Then pull that image down to your local machine. After you’ve pulled it down, retag it for whatever repository it is you want to use. 

Example for duckduckgo

vi "${OFFICIAL_DUMP}" # look for the duckduck go entry and find the image: key which will look like this:
# image: mcp/duckduckgo@sha256:68eb20db6109f5c312a695fc5ec3386ad15d93ffb765a0b4eb1baf4328dec14f

# pull the image to your machine
docker pull
mcp/duckduckgo@sha256:68eb20db6109f5c312a695fc5ec3386ad15d93ffb765a0b4eb1baf4328dec14f

# tag the image with the appropriate registry
docker image tag mcp/duckduckgo@sha256:68eb20db6109f5c312a695fc5ec3386ad15d93ffb765a0b4eb1baf4328dec14f ${GHCR_IMAGE}

# push the image
docker push ${GHCR_IMAGE}

At this point you can move on to editing the MCP Catalog file in the next section.

 If you cannot download from Docker Hub you can always rebuild the MCP server from its GitHub repo. To do this, open the exported YAML and look for your target server’s GitHub source repository. You can use tools like vi, cat, or grep to find it — it’s usually listed under a source key. 

Example for duckduckgo:
source: https://github.com/nickclyde/duckduckgo-mcp-server/tree/main

export SOURCE_REPO="https://github.com/nickclyde/duckduckgo-mcp-server.git"

Next, you’ll rebuild the MCP server image from the original GitHub repository and push it to your own registry. This gives you full control over the image and eliminates dependency on Docker Hub access.

echo "${GH_PAT}" | docker login "${GHCR_REGISTRY}" -u "${GHCR_ORG}" –password-stdin

docker buildx build
–platform linux/amd64,linux/arm64
"${SOURCE_REPO}"
-t "${GHCR_IMAGE}"
–push

Step 6: Update your catalog 

After publishing the image to GHCR, update your private catalog so it points to that new image instead of the Docker Hub version. This step links your catalog entry directly to the image you just built.

vi "${MCP_CATALOG_FILE}"

# Update the image line for the duckduckgo server to point to the image you created in the previous step (e.g. ghcr.io/mikegcoleman/duckduckgo-mcp)

Remove the forked version of the catalog as you no longer need it

docker mcp catalog rm "${FORK_CATALOG}"

Step 7: Run the MCP Gateway 

Enabling the server activates it within your MCP environment. Once enabled, the gateway can load it and make it available to connected clients. You will get warnings about “overlapping servers” that is because the same servers are listed in two places (your catalog and the original catalog)

docker mcp server enable "${MCP_SERVER_NAME}"
docker mcp server list

Step 8: Connect to popular clients 

Now integrate the MCP Gateway with your chosen client. The raw command to run the gateway is: 

docker mcp gateway run –catalog "${PRIVATE_CATALOG}"

But that just runs an instance on your local machine, when what you probably want is to integrate with some client application. 

To do this you need to format the raw command so that it works for the client you wish to use. For example, with VS Code you’d want to update the mcp.json as follows:

"servers": {
"docker-mcp-gateway-private": {
"type": "stdio",
"command": "docker",
"args": [
"mcp",
"gateway",
"run",
"–catalog",
"my-private-catalog"
]
}
}

Finally, verify that the gateway is using your new GHCR image and that the server is properly enabled. This quick check confirms everything is configured as expected before connecting clients.

docker mcp server inspect "${MCP_SERVER_NAME}" | grep -E 'name|image'

Summary of Key Commands

You might find the following CLI commands handy:

docker mcp catalog show docker-mcp –format yaml > ./docker-mcp.yaml
docker mcp catalog fork docker-mcp my-fork
docker mcp catalog export my-fork ./my-fork.yaml
docker mcp catalog create my-private-catalog
docker mcp catalog add my-private-catalog duckduckgo ./my-fork.yaml
docker buildx build –platform linux/amd64,linux/arm64 https://github.com/nickclyde/duckduckgo-mcp-server.git
-t ghcr.io/mikegcoleman/duckduckgo:latest –push
docker mcp server enable duckduckgo
docker mcp gateway run –catalog my-private-catalog

Conclusion

By using Docker’s MCP Toolkit, Catalog, and Gateway, you can fully control the tools available to your developers, customers, or AI agents. No more one-off setups, scattered images, or cross-client connection headaches.

Your next steps:

Add more servers to your catalog

Set up CI to rebuild and publish new server images

Share your catalog internally or with customers

Docs:

https://docs.docker.com/ai/mcp-catalog-and-toolkit/

https://github.com/docker/mcp-gateway/

Happy curating. 

We’re working on some exciting enhancements to make creating custom catalogs even easier. Stay tuned for updates!

Learn more

Explore the MCP Catalog: Discover containerized, security-hardened MCP servers

Open Docker Desktop and get started with the MCP Toolkit (Requires version 4.48 or newer to launch the MCP Toolkit automatically)

Read about How Open Source Genius Cut Entropy Debt with Docker MCP Toolkit and Claude Desktop

Quelle: https://blog.docker.com/feed/

Docker + E2B: Building the Future of Trusted AI

Trusted Software Starts Here

The era of agents is here. Some teams are experimenting, others are just getting started, and a few are already running agents in production. But one challenge stands out: trust. Trust that your agents will act securely. Over 20 million developers already rely on Docker to build and ship software safely and fast. Now, we’re helping you build what’s next.

Over the past few months, Docker has continued to make significant investments in driving developer productivity and building a trusted foundation for AI, with a focus on simplicity and portability, from how you build and run agents to how you secure them. We’ve shipped new capabilities: a toolkit for MCP, support for running open-weight models locally, and a catalog of 200+ MCP servers. 

Today, we’re taking that commitment to the next level through a new partnership with E2B, a company that provides secure cloud sandboxes for AI agents. Together, we’re giving developers fast, secure access to hundreds of real-world tools, without sacrificing safety or speed.

The Next Frontier of AI: Trust

Agents can code, connect, and act, but without control, that power creates risk in two areas.

First, when agents run code. AI-generated code often executes in live environments without safeguards, accessing files or APIs it shouldn’t. Teams are learning that “auto-run” doesn’t mean “safe to run.”

Second, when agents connect to real-world tools. Integrating with external tools can create security trade-offs. And the challenge keeps growing. With the rise of the Model Context Protocol (MCP), every connected tool becomes its own potential risk surface with hundreds of servers and tokens to manage. Today, developers use a variety of DIY isolation techniques, custom-built sandboxes, and resource limits, but all of them tend to slow productivity.

Developers have seen this before. Before containers, developers struggled with messy dependencies and inconsistent environments when building applications. 

Today’s AI builders face a similar challenge. Models need access to APIs and databases, but enabling that access slows them down and introduces complexity and risk. Just as containers standardized how applications run, Docker is now standardizing how agents connect and act.

This is where E2B and Docker come together. E2B secures agent-generated code execution with cloud sandboxes. Docker secures tool access through the MCP Gateway and Catalog, offering direct connectivity to 200+ real-world tools. Each MCP server is curated by Docker and automatically audited for exploits and malicious behavior.

Docker + E2B: Secure Access to Hundreds of MCP Tools

Starting today, every E2B sandbox includes direct access to Docker’s MCP Catalog, a collection of 200+ tools such as GitHub, Perplexity, Browserbase, and ElevenLabs, all enabled by the Docker MCP Gateway. Developers can now run and connect agents more confidently, without slowing down.

Try it here.

What’s Next 

This is only the beginning. Today’s partnership is the first step in a larger journey. Together, our goal is to build the future of a secure AI stack, where every agent runs securely, every connection is verifiable, and developers can move fast without compromise.

From Docker’s perspective, our goal is to ensure developers can trust the MCP servers they pull, validate them through Docker, and govern their AI stack with the same visibility and confidence they already have for containers today.

The next wave of AI development will be built on trust. Trust in the tools, the data, and the environments behind them. At Docker, we’re building that foundation.

Quelle: https://blog.docker.com/feed/

Getting Started with Offload: Automating Everyday Workflows with Docker

Every developer eventually hits a wall with their local machine. Maybe it’s training an AI model that drains your CPU, compiling a massive codebase that makes your fan sound like a jet engine, or simply trying to run GPU workloads on a laptop that doesn’t have one. The result is the same: slow builds, limited resources, and wasted time.

Docker Offload was built to solve exactly that problem. Instead of forcing you to upgrade your hardware or spend days setting up cloud infrastructure, Offload extends your existing Docker workflow into the cloud. You keep using the same docker build and docker run commands you already know — but behind the scenes, the heavy lifting happens on powerful, cloud-hosted machines (including GPUs).

Think of it as a turbo button for Docker: the same developer experience, just supercharged.

Docker Offload is a fully managed service that lets you execute Docker builds and run containers in the cloud while maintaining your familiar local development experience.It provides on-demand cloud infrastructure for fast, consistent builds and compute-intensive workloads like running LLMs, machine learning pipelines, and GPU-accelerated applications.This is ideal if you want to leverage cloud resources or if your local machine doesn’t meet the hardware requirements to run the model locally.

Why use Docker Offload

Docker Offload is designed to support modern development teams working across local and cloud environments. It helps you:

Offload heavy builds and runs to fast, scalable infrastructure

Accelerate feedback loops in development and testing

Run containers that require more resources than your local setup can provide

Use Docker Compose to manage complex, multi-service apps that need cloud resources

Docker Offload is ideal for high-velocity development workflows that need the flexibility of the cloud without sacrificing the simplicity of local tools.

How to get started

Step 1: Sign up and subscribe to Docker Offload for access

To access Docker Offload, you must sign up and subscribe.

Step 2: Start Docker Offload

Start Docker Desktop and sign in with your account.

Open a terminal and run the following command to start Docker Offload:

$ docker offload start

When prompted, select your Docker account to use for Docker Offload. This account will consume credits for your Docker Offload usage.

When prompted, select whether to enable GPU support. If you choose to enable GPU support, Docker Offload will run in an instance with an NVIDIA L4 GPU, which is useful for machine learning or compute-intensive workloads.

NoteEnabling GPU support consumes more budget. For more details, see Docker Offload usage.

Step 3: Run a container with Docker Offload

After starting Docker Offload, Docker Desktop connects to a secure cloud environment that mirrors your local experience. When you run builds or containers, they execute remotely, but behave just like local ones.

To verify that Docker Offload is working, run a container:

$ docker run –rm hello-world

If you enabled GPU support, you can also run a GPU-enabled container:

$ docker run –rm –gpus all hello-world

If Docker Offload is working, you’ll see Hello from Docker! in the terminal output.

Step 4: Stop Docker Offload

When you’re done using Docker Offload, you can stop it, which will stop a budget consumption, however after a few minutes the offload worker will be completely disposed. When stopped, you get back to  building images and running containers locally.

$ docker offload stop

To start Docker Offload again, run the docker offload start command.

Save money

Docker Offload runs your builds remotely, not on the machine where you invoke the build. This means that files must be transferred from your local system to the cloud over the network.

Transferring files over the network introduces higher latency and lower bandwidth compared to local transfers. To reduce these effects, Docker Offload includes several performance optimizations:

It uses attached storage volumes for build cache, which makes reading and writing cache fast.

When pulling build results back to your local machine, it only transfers files that changed since the previous build.

Even with these optimizations, large projects or slower network connections can lead to longer transfer times. Here are several ways to optimize your build setup for Docker Offload:

Use .dockerignore files

Choose slim base images

Use multi-stage builds

Fetch remote files during the build

Leverage multi-threaded tools

For general Dockerfile tips, see Building best practices.
Quelle: https://blog.docker.com/feed/

Introducing a Richer ”docker model run” Experience

The command line is where developers live and breathe. A powerful and intuitive CLI can make the difference between a frustrating task and a joyful one. That’s why we’re excited to announce a major upgrade to the interactive chat experience in Docker Model Runner, our tool for running AI workloads locally.

We’ve rolled out a new, fully-featured interactive prompt for the “docker model run” command that brings a host of quality-of-life improvements, making it faster, easier, and more intuitive to chat with your local models. Let’s dive into what’s new.

A True Readline-Style Prompt with Keyboard Shortcuts

The most significant change is the move to a new readline-like implementation. If you spend any time in a modern terminal, you’ll feel right at home. This brings advanced keyboard support for navigating and editing your prompts right on the command line.

You can now use familiar keyboard shortcuts to work with your text more efficiently. Here are some of the new key bindings you can start using immediately:

Move to Start/End: Use “Ctrl + a” to jump to the beginning of the line and “Ctrl + e” to jump to the end.

Word-by-Word Navigation: Quickly move through your prompt using “Alt + b” to go back one word and “Alt + f” to go forward one word.

Efficient Deletions:

“Ctrl + k”: Delete everything from the cursor to the end of the line.

“Ctrl + u”: Delete everything from the cursor to the beginning of the line.

“Ctrl + w”: Delete the word immediately before the cursor.

Screen and Session Management:

“Ctrl + l”: Clear the terminal screen to reduce clutter.

“Ctrl + d”: Exit the chat session, just like the /bye command.

Take Back Control with “Ctrl + c”

We’ve all been there: you send a prompt to a model, and it starts generating a long, incorrect, or unwanted response. Previously, you had to wait for it to finish. Not anymore.

You can now press “Ctrl + c” at any time while the model is generating a response to immediately stop it. We’ve implemented this using context cancellation in our client, which sends a signal to halt the streaming response from the model. This gives you full control over the interaction, saving you time and frustration. This feature has also been added to the basic interactive mode for users who may not be in a standard terminal environment. “Ctrl + c” ends that interaction but does not exit. “Ctrl + d” exits “docker model run”.

Improved Multi-line and History Support

Working with multi-line prompts, like pasting in code snippets, is now much smoother. The prompt intelligently changes from > to a more subtle . to indicate that you’re in multi-line mode.

Furthermore, the new prompt includes command history. Simply use the Up and Down arrow keys to cycle through your previous prompts, making it easy to experiment, correct mistakes, or ask follow-up questions without retyping everything. For privacy or scripting purposes, you can disable history writing by setting the DOCKER_MODEL_NOHISTORY environment variable.

Get Started Today!

These improvements make “docker model run” a more powerful and pleasant tool for all your local AI experiments. Pull a model from Docker Hub and start a chat to experience the new prompt yourself:

$ docker model run ai/gemma3
> Tell me a joke about docker containers.
Why did the Docker container break up with the Linux host?

… Because it said, "I need some space!"

Would you like to hear another one?

Help Us Build the Future of Local AI

Docker Model Runner is an open-source project, and we’re building it for the community. These updates are a direct result of our effort to create the best possible experience for developers working with AI.

We invite you to get involved!

Star, fork, and contribute to the project on GitHub: https://github.com/docker/model-runner

Report issues and suggest new features you’d like to see.

Share your feedback with us and the community.

Your contributions help shape the future of local AI development and make powerful tools accessible to everyone. We can’t wait to see what you build!

Learn more

Check out the Docker Model Runner General Availability announcement

Visit our Model Runner GitHub repo! Docker Model Runner is open-source, and we welcome collaboration and contributions from the community!

Get started with Docker Model Runner with a simple hello GenAI application

Quelle: https://blog.docker.com/feed/

Docker Model Runner Meets Open WebUI: A Simpler Way to Run Local AI Models

Hi, I’m Sergei Shitikov – a Docker Captain and Lead Software Engineer living in Berlin. I’m focused on DevOps, developer experience, open source, and local AI tools. I created this extension to make it easier for anyone – even without a technical background – to get started with local LLMs using Docker Model Runner and Open WebUI.

This new Docker extension lets you run Docker Model Runner as the inference service behind Open WebUI, powering a richer chat experience. This blog walks you through why Docker Model Runner and Open WebUI make a powerful duo, how to set up your own local AI assistant, and what’s happening under the hood.

Local LLMs are no longer just experimental toys. Thanks to rapid advances in model optimization and increasingly powerful consumer hardware, local large language models have gone from proof-of-concept curiosities to genuinely useful tools.

Even a MacBook with an M-series chip can now run models that deliver fast, meaningful responses offline, without an internet connection or API keys.

Docker Model Runner, accessible via Docker Desktop (and also available as a plugin for Docker CE and of course fully OSS), makes getting started easy: just pick a model in the UI or run a single docker model run from the CLI.You’ll have a fully operational model up and running in seconds.

Docker Model Runner + Open WebUI: A powerful duo for running richer, local AI chat experiences

Docker Model Runner is designed as an inference service in Docker Desktop or CLI, allowing developers to run models locally with familiar workflows and commands they trust and know. This means from a design perspective, it only provides the bare minimum: a prompt box and a response field. There’s no memory. No file upload. No chat flow. No interface that feels like a real assistant. Note this is actually by design. There is no intention to replicate an experience within Docker Desktop; that is already well implemented by other offerings within the wider ecosystem.

That’s where Open WebUI comes in: a modern, self-hosted interface designed specifically for working with local LLMs.

It brings chat history, file uploads, prompt editing, and more. All local. All private.

That’s why an extension was created: to combine the two.

This Docker Extension launches Open WebUI and hooks it directly into your running model via Docker Model Runner. No configuration. No setup. Just open and go.

Let’s see how it works.

From Zero to Local AI Assistant in a Few Clicks

If you already have Docker Desktop installed, you’re almost there.

Head over to the Models tab and pick any model from the Docker Hub section: GPT-OSS, Gemma, LLaMA 3, Mistral or others.

One click, and Docker Model Runner will pull the container and start serving the model locally.

Prefer the CLI? A single docker model pull does the same job.

Next, you might want something more capable than a single input box.

Open the Extensions Marketplace inside Docker Desktop and install the Open WebUI extension, a feature-rich interface for local LLMs.

It automatically provisions the container and connects to your local Docker Model Runner.

All models you’ve downloaded will appear in the WebUI, ready to use; no manual config, no environment variables, no port mapping.

Once setup completes, you’ll see a screen confirming the extension is running, along with a button to launch the interface in your browser.

Alternatively, you can open it manually at http://localhost:8090 (default port) or bookmark it for future use.

Note: The first-time startup may take a couple of minutes as Open WebUI installs required components and configures integration.

Subsequent launches are much faster – nearly instant.

What You Can Do with Open WebUI

Once installed, Open WebUI feels instantly familiar, like using ChatGPT, but running entirely on your own machine.

You get a full chat experience, with persistent conversations, system prompt editing, and the ability to switch between models on the fly.

Upload files and chat with them

Drop in PDFs, Markdown files, presentations, spreadsheets, or even images.

Open WebUI extracts the content and makes it queryable through the chat.

Need a summary, quick answer, or content overview? Just ask: all processing happens locally.

Speak instead of type

With voice input turned on, you can talk to your assistant right from the browser.

This is great for hands-free tasks, quick prompts, or just demoing your local AI setup to a friend.

Requires permission setup for microphone access.

Define how your model behaves

Open WebUI supports full control over system prompts with templates, variables, and chat presets.

Whether you’re drafting code, writing blog posts, or answering emails, you can fine-tune how the model thinks and responds.

Switch between models instantly

Already downloaded multiple models using Docker Model Runner?

Open WebUI detects them automatically. Pick any model from the dropdown and start chatting; no restart required.

Save insights to memory

Want the model to remember something specific?

You can store facts or reminders manually in the personal memory panel and edit or remove them at any time.

More Things You Can Do

Open WebUI goes beyond chat with advanced tools that power real workflows:

Function Calling & Plugins

Use prebuilt tools or define your own Python functions via the Pipelines framework, ideal for automations, translations, or data lookups.

Multilingual UI

Open WebUI supports a wide range of interface languages and is fully localizable, perfect for international teams or non-English users.

Secure, local-first by design

No sign-up and no cloud storage. Everything stays on your machine, under your control.

Note: Not all features are universally available. Some depend on the model’s capabilities (e.g., function calling, image understanding), your current Open WebUI settings (e.g., voice input, plugins), or the hardware you’re running on (e.g., GPU acceleration, local RAG performance).Open WebUI aims to provide a flexible platform, but actual functionality may vary based on your setup.

How it works inside

Under the hood, the extension brings together two key components: integration between Open WebUI and Docker Model Runner, and a dynamic container provisioner built into the Docker extension.

Open WebUI supports Python-based “functions”, lightweight plugins that extend model behavior.This extension includes a function that connects to Docker Model Runner via its local API, allowing the interface to list and access all downloaded models automatically.

When you install the extension, Docker spins up the Open WebUI container on demand. It’s not a static setup, the container is configured dynamically based on your environment. You can:

Switch to a different Open WebUI image (e.g., CUDA-enabled or a specific version)

Change the default port

Support for custom environments and advanced flags – coming soon

The extension handles all of this behind the scenes, but gives you full control when needed.

Conclusion

You’ve just seen how the Docker Open WebUI Extension turns Docker Model Runner from a simple model launcher into a fully-featured local AI assistant with memory, file uploads, multi-model support, and more.

What used to require custom configs, manual ports, or third-party scripts now works out of the box, with just a few clicks.

Next steps

Install the Open WebUI Extension from the Docker Desktop Marketplace

Download a model via Docker Model Runner (e.g., GPT-OSS, Gemma, LLaMA 3, Mistral)

Launch the interface at http://localhost:8090 and start chatting locally

Explore advanced features: file chat, voice input, system prompts, knowledge, plugins

Switch models anytime or try new ones without changing your setup

The future of local AI is modular, private, and easy to use.

This extension brings us one step closer to that vision and it’s just getting started.

Get involved

Star or contribute to Open WebUI Docker Extension on GitHub

Follow updates and releases in the Docker Extensions Marketplace

Contribute to the Docker Model Runner repo: it’s open source and community-driven

Share feedback or use cases with the Docker and Open WebUI communities

Quelle: https://blog.docker.com/feed/

Why I Still Use jQuery

jQuery is a household name among web developers who have been around the block. Initially released in 2006, it took the web development world by storm with its easy and intuitive syntax for navigating a document, selecting DOM elements, handling events, and making AJAX requests. At its peak in 2015, jQuery featured on 62.7 percent of the top one million websites and 17 percent of all Internet websites.

A decade later, jQuery is not the shiny new kid on the block anymore. Most of the original pain points jQuery solved, such as DOM manipulation and inconsistent browser behavior, are gone thanks to modern browser APIs. 

But jQuery is still widely used. According to SimilarWeb, as of August 11, 2025, nearly 195 million websites use it. That means many developers, like me, still use it every day. And like me, you might prefer it in certain cases. 

So, in this article, I’ll share when it still makes sense to use jQuery and when not. Don’t worry: I’m not arguing we should replace React with jQuery. And I’m not here to romanticize 2008. In 2025, I simply still find myself reaching for jQuery because it’s the right tool for the job. 

A Brief History of jQuery

To determine when it makes sense to use jQuery and when not, it helps to know why it was created in the first place and what problems it aimed to solve.

When John Resig launched jQuery at BarCamp NYC in January 2006, the web was a different place. Features we take for granted today were absent from most browsers:

No querySelectorAll: Selecting DOM elements across browsers was messy. In the mid-2000s, none of the available element selectors, like getElementById or getElementsByClassName, could select elements using complex CSS queries.

Inconsistent event handling: addEventListener wasn’t universal. While browsers like Firefox, Safari, and Chrome supported the W3C event model with addEventListener, Internet Explorer (before IE9) used Microsoft’s proprietary model with attachEvent. These two models differed from each other in almost all functional aspects.

Different browsers had different APIs for XMLHttpRequest. While browsers like Firefox and Safari offered the familiar XMLHttpRequest, Internet Explorer (before IE7) used ActiveX objects to give JavaScript network capabilities. This meant you had to use a bunch of if-else blocks to make an AJAX request.

CSS manipulation quirks: In the 2000s and early 2010s, many CSS features were implemented inconsistently across browsers, which made it difficult to manipulate CSS with JS.

jQuery solved all of this with a simple, chainable syntax and consistent cross-browser behavior. It offered a streamlined, chainable API for DOM traversal, event handling, and AJAX—far simpler than cross-browser native JavaScript at the time. These features made jQuery become the go-to JavaScript library in the 2010s, powering everything from personal blogs to Fortune 500 sites. In 2012, a W3Techs survey found that jQuery was running on 50 percent of all websites, and by 62.7 percent of the top 1M websites used it.

Where jQuery Still Makes Sense

Although jQuery’s glory days are clearly behind us, it still works well in some situations. Here are the scenarios where I still choose jQuery:

Legacy Projects

Even now in 2025, a W3Techs survey shows that jQuery is used in 77.8 percent of the top 10M websites in 2025. This is mostly legacy usage—old apps that use jQuery because switching to a more modern framework is a costly endeavour. This is clear when you look at the version statistics. In a 2023 survey across 500 organizations, only 44 percent use maintained versions (3.6.0 or newer), while 59 percent run older versions (1.x to 3.5.1)

I maintain a few legacy projects like these that were written with jQuery, and I can tell you why they’re still around: they just work. So as the adage goes, “If it ain’t broke, don’t fix it.” 

Many large enterprises, government sites, corporate intranets, and many WordPress plugins and themes still rely on jQuery. Rewriting these sites to pure JavaScript or a modern framework is a time-consuming, expensive endeavour that can also introduce new challenges and bugs. Most of the time, all that effort and risk aren’t worth the relatively small benefits in the short term.

The truth is this: the codebase I inherited, built in the jQuery era, works. The business logic is robust, the profit margins are healthy, and—most surprisingly—shipping new features feels like slipping into a worn leather jacket: unfashionable, but comfortable. – Marc Boisvert-Duprs

Yes, most jQuery plugins are no longer actively maintained or have been deprecated, so depending on them is a security risk. Abandoned plugins may become incompatible or insecure as browsers continue to evolve. So, legacy projects that use jQuery and jQuery plugins should eventually migrate away from jQuery.

Quick Prototyping without Build Tools

Developers often need to prototype very simple frontend apps, be it for throwaway demos, internal tools, or proof-of-concept pages. Sometimes the spec may even require a very basic frontend with minimal interactivity (for example, a static page with a simple form and a button).

jQuery is a perfect choice for these situations. Simply drop in a <script> tag from a CDN and get animations, DOM manipulation, and AJAX in minutes—no need for npm, bundlers, transpilers, or complicated frameworks with hundreds of dependencies. It’s also great for running quick commands from the DevTools console, especially if you want to experiment with an app. 

But why not use a more modern but lightweight framework like Alpine.js? Personally, I’m intimately familiar with jQuery: I’ve used it since the beginning of my web development journey. I love its simplicity and ease of use. The minor improvements a new framework can make in this scenario don’t offset the time spent learning a new tool.

Complex DOM Manipulation in Different Browser Contexts

Hopefully, you don’t have to support older browsers that lack the standard querySelector, or browsers like Internet Explorer, notorious for their non-standard behavior. Unfortunately, some of us still need to maintain apps that run on these browsers.

While native JS is perfectly fine for modern browsers, if you’re building something that has to run on older embedded browsers (think: kiosk software, older enterprise or university intranets, or web apps inside legacy desktop apps), jQuery’s normalization saves you from manual polyfilling, and its CSS selector lets you perform complex DOM manipulations easily.

Simple Animations without CSS Keyframes

As someone who primarily works with backend apps, I don’t often need to code animations for the frontend. But when I do need to create basic chained animations (fading, sliding, sequencing multiple elements, etc.), jQuery’s .animate()is simpler (and more lightweight) to write than juggling CSS animations and JS event callbacks.

Simple AJAX with HTML Server Responses

I was recently tasked to make some upgrades to an ancient app with a PHP backend. Imagine my surprise when I discovered that the server returns HTML fragments, and not JSON APIs. In this case, jQuery’s .load() and .html() methods can be simpler and more efficient than writing fetch() boilerplate with DOM parsing.

For example, I can extract a DOM element from the results of an AJAX request, and load it into an element like so:

// Replace #comments with just the #comments-list from the server response
$('#comments').load('/article/1 #comments-list');

Whereas the same thing in native JS would be:

fetch('/article/1')
.then(res => res.text())
.then(html => {
const doc = new DOMParser().parseFromString(html, 'text/html');
const comments = doc.querySelector('#comments-list');
document.querySelector('#comments').innerHTML = comments.outerHTML;
})

Yes, while the jQuery syntax is more straightforward, both approaches are doing the same thing under the hood, so there’s not a huge performance gain. In the jQuery version, you also have the added overhead of bundling the jQuery library. So, it’s a tradeoff between simplicity and bundle size.

When You Should Not Use jQuery

While jQuery still makes sense in some situations, there are some cases where I would never use jQuery.

Building a Modern, Component-Driven Frontend

If I’m building a modern frontend app with lots of reactivity and reusable components, I’d use a modern framework like React or Vue with native features for DOM manipulation.

Frameworks like React, Vue, Svelte, or Angular handle DOM rendering in a virtualised way. Direct DOM manipulation with jQuery conflicts with their data-binding approach, causing state mismatches and bugs. 

For example, in React, calling $(‘#el’).html(‘…’) bypasses React’s virtual DOM and React won’t know about the change. This will inevitably lead to bugs that are difficult to diagnose.

When Simple Vanilla JS Is Enough

Most of jQuery’s once-killer features, such as selectors, AJAX, events, and animations, are now native in JavaScript:

document.querySelectorAll() replaces $().

fetch() replaces $.ajax().

element.classList replaces .addClass()/ .removeClass().

element.animate() handles animations.

If I’m just toggling classes or making a fetch call, adding jQuery is wasteful.

Targeting Modern Browsers Only

jQuery’s major draw between 2008 and 2015 was its cross-browser compatibility, which was necessary due to quirks in IE6–IE9. It simply wasn’t practical to write browser-specific JS for all the different versions of IE. With jQuery, the quirks were abstracted away.

When IE was discontinued, this usefulness is no longer relevant. 

So if the app I’m working on needs to support only modern browsers, I don’t need most of jQuery’s compatibility layer.

Projects Already Using Modern Tooling

Mixing jQuery and framework code leads to a “hybrid monster” that’s difficult to maintain. 

jQuery can conflict with existing frameworks, which can cause hard-to-fix bugs. If my project is already written in another framework, I avoid including jQuery.

Alternatives to jQuery

Sometimes, I need to use some features of jQuery, but I can’t justify including it in its entirety.  Here are some libraries I use in cases like these. 

DOM Selection and Traversal

Native DOM API (most common replacement) using document.querySelector() and document.querySelectorAll()

Cash: jQuery-like API, tiny (~10KB), works with modern browsers

Zepto.js: lightweight jQuery-compatible library for mobile-first projects

AJAX/HTTP Requests

Native fetch() API

Axios: promise-based HTTP client with interceptors and JSON handling.

Event Handling

Native events using element.addEventListener()

delegate-it: small utility for jQuery-style event delegation

Animations

CSS transitions and animations (native, GPU-accelerated)

Web Animations API

GSAP: Powerful animation library, much more capable than .animate() in jQuery.

Utilities

* Lodash: collection iteration, object/array utilities, throttling, debouncing

* Day.js: date manipulation in a tiny package (instead of jQuery’s date plugins)

All-in-One Mini jQuery Replacements

If you still like a single API but want it lighter than jQuery:

Umbrella JS: ~3KB, jQuery-like API

Bliss: focuses on modern features, syntactic sugar, and chaining

Cash: as mentioned above, the closest modern equivalent

 jQuery Still Has a Job

In 2025, jQuery isn’t the cutting-edge choice for building complex, highly interactive single-page applications that it was in the 2010s, and that’s perfectly fine. While modern frameworks dominate the headlines, jQuery remains a reliable, well-understood tool that solves the problems it was designed for, simply and effectively.

In the end, the “right” tool is the one that meets your project’s needs, and for countless developers and businesses, jQuery continues to be that.
Quelle: https://blog.docker.com/feed/

How to add MCP Servers to OpenAI’s Codex with Docker MCP Toolkit

AI assistants are changing how we write code, but their true power is unleashed when they can interact with specialized, high-precision tools. OpenAI’s Codex is a formidable coding partner, but what happens when you connect it directly to your running infrastructure?

Enter the Docker MCP Toolkit.

The Model Context Protocol (MCP) Toolkit acts as a secure bridge, allowing AI models like Codex to safely discover and use any of the 200+ MCP servers from the trusted MCP catalog curated by Docker.

In this post, we’ll walk through an end-to-end demo, just like our Claude Code and Gemini CLI tutorials. But this time, we’re pairing Codex with Neo4j MCP servers.

First, we’ll connect Codex to the Neo4j server using the MCP Toolkit. Then, we’ll show a fun example: building a graph of Pokémon species and their types, and exploring the data visually. While playful, this example highlights how Codex + MCP can be applied to real-world, semi-structured data pipelines.

Read on to see how a generic AI assistant, when supercharged with Docker and MCP, can evolve into a specialized data engineering powerhouse!

Why use Codex with Docker MCP

While Codex provides powerful AI capabilities and MCP provides the protocol, Docker MCP Toolkit makes automated data modeling and graph engineering practical. Without containerization, building a knowledge graph means managing local Neo4j installations, dealing with database driver versions, writing boilerplate connection and authentication code, and manually scripting the entire data validation and loading pipeline. A setup that should take minutes can easily stretch into hours for each developer.

Docker MCP Toolkit eliminates this friction:

200+ pre-built MCP servers in the Catalog

One-click deployment through Docker Desktop

Neo4j Data Modeling MCP for schema design and validation

Neo4j Cypher MCP for direct database queries and ingestion

Secure credential management for database passwords

Consistent configuration across Mac, Windows, and Linux

Automatic updates when new server versions are released

We built Docker MCP Toolkit to meet developers where they are. If you’re using Codex, you should be able to engineer a knowledge graph without wrestling with database infrastructure.

The Setup: Connecting Codex to Neo4j Tools

Prerequisites

First, we need to give Codex access to the specialized Neo4j tools. 

Install Codex and run it at least once to get authentication out of the way

Install Docker Desktop 4.40 or later

Enable MCP Toolkit 

Step 1: Add the Neo4j MCP Servers

The Neo4j Cypher and Data Modeling servers are available out-of-the-box in the main MCP Toolkit catalog.

In Docker Desktop, navigate to the MCP Toolkit tab.

Click the Catalog tab.

Search for “Neo4j” and click + Add for both the Neo4j Cypher and Neo4j Data Modeling servers.

They will now appear in your “My servers” list.

Step 2: Connect Codex to the MCP Toolkit

With our tools ready, we run a one-time command to make Codex aware of the MCP Toolkit:

docker mcp-client configure codex

We can also do that from the Docker Desktop UI, navigate to the clients tab, and smash that connect button next to Codex and any other assistants you use:

Docker will edit the corresponding configuration files and next time Codex starts, it’ll connect to the MCP toolkit and you’ll have the tools at your disposal!

Step 3: Start and Configure Neo4j

We still need to configure the Neo4j Cypher MCP server to connect to the Neo4j database, so we’ll set this up now. We’ll use Codex to start our Neo4j database and configure the connection. First, we ask Codex to create the container:

› Spin up a Neo4j container for me in Docker please.

Codex will run the necessary Docker command, and get our Neo4j container running. You can of course do this manually, use a cloud service, or download the Neo4j Desktop application, but since we’re having fun in Codex – then why not make it do these mundane things for us.

With Neo4j available in the container we now need to configure the Neo4j Cypher MCP server to connect to it. The Neo4j Data Modeling MCP server works without any configuration. To simplify you can take a screenshot of the configuration form and ask Codex for the information on how to fill it to connect to the container we just started.

Next, we asked Codex for help, pointing it to a screenshot of the configuration page:

› There is a screenshot in this directory. It has the information we need to configure, MCP server to connect to the Neo4j database. Please look at it and give me the information to configure the MCP server to connect to our Neo4j container.

Codex inspected the container, found the running container, and determined its authentication details (e.g., NEO4J_AUTH=neo4j/password). It then provided the correct configuration values. We just need to update the Neo4j Cypher MCP server configuration in the Docker Desktop UI with the neo4j-cypher.url (neo4j://localhost:7687) and the password.

Fill the form in the Docker MCP toolkit for the Neo4j Cypher MCP server and restart codex now.

Use Case: Building a Pokémon Graph with Codex + Neo4j

Now we’re ready to tackle our original problem of building the graph of Pokémon species. First of all, enter the YOLO mode by typing /approvals and selecting the mode where it has freedom to do whatever it pleases:

Next, we can throw the full power of Codex models at our task. We give it the full problem statement: 

› Here's the page with all pokemon in generation 1: https://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_by_index_number_in_Generation_I
and here's the types information: https://bulbapedia.bulbagarden.net/wiki/Type

we're going to create a graph with data about these pokemon (ignore MissingNo entries – they are a glitch and ignore other glitched pokemon).
you have a neo4j container running, and the MCP tools for modelling and cypher.

Codex will accept the task, break it down into a plan, and start cranking at it. 

There are a few interesting moments in how it approaches it, though it largely depends on the model you configure Codex with. For me it was “model: gpt-5-codex” and it tends to use scripting more than chaining curl commands for example. 

Here’s the plan you might see if you’re following along:

• I’m preparing to build a Pokemon graph by fetching data from a website using network access. Since this is a complex task, I’ll create a detailed plan involving data gathering, modeling
entities like Pokémon and Types, defining relationships such as evolutions and type effectiveness, and then using tools like MCP Docker to build the Neo4j graph. The first step is to draft
• Updated Plan
└ □ Inspect requirements and gather Generation I Pokémon data with types and evolution chains
□ Define Neo4j graph data model for Pokémon, Types, and relationships
□ Load data into Neo4j via Cypher ingestion and validate

Then it immediately started cranking python scripts with requests, BeautifulSoup and other web scraping friends to fetch the data from the provided wiki. It’s interesting that the Pokemon data is not actually on a single page, but spread through subpages for every Pokemon species, so perhaps scraping with Python makes a ton of sense over curling the pages and spending tokens on processing the data in the model. And it leaves the scripts behind so you can verify and reproduce the results if needed. 

Eventually the model proceeds to analyze the data, and here the MCP tools become really helpful. You can see below that it’s calling the MCP_DOCKER.validate_data_model from the server we configured earlier.

I'm outlining a comprehensive data model for Pokemon, types, and their relationships with precise property types and units converted for better clarity. I plan to generate ingestion-ready
JSON files via a Python script to integrate cleanly with Neo4j ingestion tools, ensuring the data pipeline is robust and structured.
└ wrote data model to data/gen1_pokemon_model.json

• Called MCP_DOCKER.validate_data_model({"data_model":"data/gen1_pokemon_model.json","return_validated":true})
└ Input validation error: 'data/gen1_pokemon_model.json' is not of type 'object'
….

It took Codex a few attempts to figure out the data model json schema and produce one for the Pokémon that satisfied the Neo4j Data Modelling MCP server. 

Then it returned to Python for creating the data ingestion script and loaded the data into the Neo4j instance.

A few MCP tool calls later to query the data with cypher (query language for graph databases) which it can do because it has access to the MCP server for Neo4j Cypher. And with it, Codex and the MCP servers can answer analytical questions about our data.

– Greedy type-coverage search suggests trios such as (Rhydon, Parasect, Dragonite) or (Rhydon, Parasect, Jynx) hit 13 of the 15 defending types super-effectively; no trio can cover Normal/Rock simultaneously because Normal has no offensive 2× matchup.

Now what’s really fun about Neo4j is that it comes with a terrific console where you can explore the data. 

While our Neo4j container with the Pokémon data is still running we can go to http://localhost:7474, enter neo4j/password credentials and get to explore the data in a visual way. 

Here for example is a subset of the Pokémon and their type relationships.

And if you know Cypher or have an AI assistant that can generate Cypher queries (and verify they work with an MCP tool call), you can generate more complex projections of your data, for example this (generated by Codex) shows all Pokémon, their evolution relationships and primary/secondary types.

MATCH (p:Pokemon)
CALL {
WITH p
OPTIONAL MATCH (p)-[:EVOLVES_TO*1..]->(evo:Pokemon)
WITH collect(DISTINCT evo) AS evos
RETURN [e IN evos WHERE e IS NOT NULL | {node: e, relType: 'EVOLVES_TO'}] AS evolutionConnections
}
CALL {
WITH p
OPTIONAL MATCH (p)-[:HAS_TYPE]->(type:Type)
WITH type
ORDER BY type.name // ensures a stable primary/secondary ordering
RETURN collect(type) AS orderedTypes
}
WITH p, evolutionConnections, orderedTypes,
CASE WHEN size(orderedTypes) >= 1 THEN orderedTypes[0] END AS primaryType,
CASE WHEN size(orderedTypes) >= 2 THEN orderedTypes[1] END AS secondaryType
WITH p,
evolutionConnections +
CASE WHEN primaryType IS NULL THEN [] ELSE [{node: primaryType, relType: 'HAS_PRIMARY_TYPE'}] END +
CASE WHEN secondaryType IS NULL THEN [] ELSE [{node: secondaryType, relType: 'HAS_SECONDARY_TYPE'}] END AS connections
UNWIND connections AS connection
RETURN p AS pokemon,
connection.node AS related,
connection.relType AS relationship
ORDER BY pokemon.name, relationship, related.name;

Turn Your AI Coding Assistant into a Data Engineer, Architect, Analyst and More

While this Pokémon demo is a fun example, it’s also a practical blueprint for working with real-world, semi-structured data. Graph databases like Neo4j are especially well-suited for this kind of work. Their relationship-first model makes it easier to represent the complexity of real-world systems.

In this walkthrough, we showed how to connect OpenAI’s Codex to the Neo4j MCP Servers via Docker MCP Toolkit, enabling it to take on multiple specialized roles:

Data Engineer: Writing Python to scrape and transform web data

Data Architect: Designing and validating graph models using domain-specific tools

DevOps Engineer: Starting services and configuring tools based on its environment

Data Analyst: Running complex Cypher and Python queries to extract insights

In your own projects, you might ask your AI assistant to “Analyze production logs and identify the cause of performance spikes,” “Migrate the user database schema to a new microservice,” or “Model our product catalog from a set of messy CSVs.”

Summary

The Docker MCP Toolkit bridges the gap between powerful AI coding agents and the specialized tools they need to be truly useful. By providing secure, one-click access to a curated catalog of over 200 MCP servers, it enables AI agents to interact with real infrastructure, including databases, APIs, command-line tools, and more. Whether you’re automating data workflows, querying complex systems, or orchestrating services, the MCP Toolkit equips your assistant to work like a real developer. If you’re building with AI coding assistants and want it to go beyond code generation, it’s time to start integrating with the tools your stack already relies on!

Learn more

Explore the MCP Catalog: Discover containerized, security-hardened MCP servers

Open Docker Desktop and get started with the MCP Toolkit (Requires version 4.48 or newer to launch the MCP Toolkit automatically)

Read our tutorial on How to Add MCP Servers to Claude Code with Docker MCP Toolkit

Read our tutorial on How to Add MCP Servers to Gemini CLI with Docker MCP Toolkit

Quelle: https://blog.docker.com/feed/

Debug Docker Builds with Visual Studio Code

Building Docker images is an important component of the software delivery pipeline for modern applications. It’s how we package our apps and services so that they can be distributed to others and deployed to production. While the Dockerfile has long been the standard for defining container images, it is known to be challenging to make changes and debug when issues arise. It’s currently a real pain to understand the build time state during the different stages of the build. What was the state of the ARG? Which files were copied into the image?

Recently, we have been making updates to the Docker Build clients (Buildx) and our VS Code extension (Docker DX) to improve the developer experience when using Docker. Today, we are sharing the next stage of that process with the introduction of Build Debugging in VS Code and Docker Build.

With the new debugging feature in Buildx from Docker, you will be able to reduce the time you spend fixing your Docker builds. In this post, you’ll learn how to configure the Buildx debugger in Visual Studio Code, step through a build and inspect variables and the image’s file system, and open a shell inside the image being built. Finally, you will learn a little about the debugger’s implementation and how it can be integrated into other editors.

Configuring Visual Studio Code

To start debugging Dockerfiles in Visual Studio Code:

Install the latest version of the Docker DX extension.

Update to the latest version of Docker Desktop to ensure you have the latest Docker build tooling.

Run docker buildx version and verify that your Buildx is at least version 0.29.x.

Creating a Launch Configuration

Open up your Dockerfile and open the Run and Debug view in Visual Studio Code. If you do not have any launch configurations, you will see something like the following.

Figure 1: Run and Debug view opened in Visual Studio Code with no launch configurations defined.

Click on the “create a launch.json file” hyperlink. If you have launch configurations, open up your launch.json file by clicking on the cog icon in the top right hand corner of the Run and Debug view.

In your launch.json file, create a new launch configuration for debugging your Docker build. You can use the sample below to get started. For a full description of the various attributes in a launch configuration, see here.

{
"name": "Docker: Build",
"type": "dockerfile",
"request": "launch",
"dockerfile": "Dockerfile",
"contextPath": "${workspaceFolder}"
}

Adding a Breakpoint

Now that you have completed setting up your launch configuration, let’s add a breakpoint to our Dockerfile. Place a breakpoint next to one of your RUN instructions by clicking in the editor’s left margin or by pressing F9. A circle should appear to indicate that a breakpoint has been added.

Launching the Debugger

We are now ready to start the debugger. Select the launch configuration you created and then hit F5. The build should pause at the RUN line where you placed the breakpoint.

Figure 2: Docker build suspended by a breakpoint in Visual Studio Code.

Debugging Features

We will now walk you through the three different features that the Buildx Debugger provides.

Inspecting Variables

When a build is in a suspended state, you can look at any variables that may have been defined. In this example, by looking at the executed command’s workdir value on the left-hand side, we can now see that the command is not being run in the right folder as we had copied the contents into /app. We can fix this by adding WORKDIR /app before the RUN line. Also note that we can view variables that have been defined by our image and the base image as seen by VAR and NODE_VERSION.

Figure 3: Docker build encounters an error and is suspended by the debugger instead of terminating.

File Explorer

In addition to inspecting variables, you can also look at the structure of the file system to see what is already there and what you have copied in. For text files, you can also see its file content as shown in the file’s data field.

Figure 4: View the file system of the Docker image being built.

Interactive Debugging

Creating the right Dockerfile is often an iterative process. Part of this is usually because the host system you are developing on shares few similarities with the image you are building. Consider the differences between running Ubuntu locally but trying to build an Alpine Linux image. The small differences in package names creates a lot of back and forth between your editor and your browser as you search for the right name. You add a line here and then maybe comment another line somewhere else before running docker build again to just hope for the best.

This iterative process can now be streamlined with the help of the debugger. When your build is in a suspended state, open the Debug Console view and then place your cursor in the input field at the bottom. Type in exec and then hit the enter key. The Terminal view should now open with a shell that is attached to the image that is being built.

Figure 5: Use the Debug Console to open a shell into the Docker image being built by running exec.

Figure 6: The Docker image that is being built can now be accessed and inspected with a terminal.

This feature is a game changer as you can now easily open the image of a Dockerfile at any given step and inspect its content and run commands for testing. Previously, we would have to comment everything after the buggy line, build the Docker image, and then manually run and open a shell into the image. All of that is now condensed into adding a breakpoint in your editor and starting a debug session!Keep in mind that none of the changes you make in the terminal are persisted so this is purely for experimentation. In the figure below, we can see that a file was created when the debugger was paused at line 3. When the debugger was advanced to line 4, the file disappeared.

Figure 7: Changes to the Docker image inside the exec terminal will be reset when the debugger steps to another line.

Integrations powered by an Open Specification

Just like our work with the Docker Language Server that implements the Language Server Protocol, the Buildx debugger is built on open standards as it implements the Debug Adapter Protocol which means that you can debug Dockerfile builds with any editor that supports the protocol. Besides Visual Studio Code, we also provide an official plugin for Neovim. For the JetBrains users out there, we have verified that it integrates well with the LSP4IJ plugin. If your favourite editor supports the Debug Adapter Protocol, there should be a way for the Buildx debugger to integrate with it.

Thank You

We want to take this opportunity to thank Kohei Tokunaga (ktock) for his ideas and initial work around this feature. The contributions he provided to Buildx gave us a great foundation for us to build out and complete this feature. This release would not have been possible without his help. Thank you, Kohei!

Next Steps

Download the Docker DX extension and try out the new debugging feature.

Share feedback and issues with us in our GitHub repositories for Docker DX and Buildx.

You can also submit feedback through the Docker feedback page.

Learn More

Setup the Buildx debugger in Neovim with nvim-dap-docker.

Setup the Buildx debugger in a JetBrains editor with the LSP4IJ plugin.

Read the Buildx documentation about our implementation of DAP and configuring launches.

Quelle: https://blog.docker.com/feed/

How to add MCP Servers to Gemini CLI with Docker MCP Toolkit

In the rapidly evolving landscape of AI-assisted development, most developers continue to struggle with clunky web interfaces, resource-intensive IDEs, and fragmented toolchains. But what if we told you there’s a combination that pairs Google’s 76.3K-star Gemini CLI (in just 5 months) with Docker’s innovative MCP Toolkit, quietly revolutionizing how modern AI developers work?

Enter the powerhouse duo: Gemini CLI and Docker MCP Toolkit. This isn’t just another tool combination — it’s a paradigm shift that delivers developer AI assistance with zero complexity overhead. A one-time setup of just 5 minutes can save you 20 minutes per test scenario — that’s a 97% time reduction that compounds with every test you run.

Let’s look at a concrete example: browser testing and performance analysis that developers do regularly can be simplified and completely automated. What used to require opening browsers, clicking through flows, analyzing DevTools, taking screenshots, and manually documenting buys can now happen in a single 30-second conversation.

In this guide, you’ll learn how to:

Set up Gemini CLI and connect it to Docker MCP Toolkit

Configure the Playwright MCP server for browser automation

Configure the GitHub MCP server for issue creation

Configure the Filesystem MCP server for saving test artifacts

Automate browser testing that discovers real bugs and creates documented GitHub issues

See how Gemini CLI can analyze performance, capture screenshots, and report findings—all without leaving your terminal

With 220+ pre-built MCP servers, browser automation becomes as simple as having a conversation. No Selenium WebDriver configuration, no CI/CD pipeline complexity, no manual screenshot management — just natural language instructions that execute real browser tests.

Why Gemini CLI and Docker MCP Toolkit Work Better Together

Manual browser testing and performance analysis are broken. You open Chrome DevTools, click through pages, check network requests, analyze performance metrics, take screenshots, write bug reports, and then manually create GitHub issues. This context-switching nightmare wastes hours every sprint.

Traditional automation tools don’t solve the real problem. Selenium requires brittle selectors and a complex setup. Playwright needs JavaScript knowledge and test frameworks. Both require maintaining test scripts that break with every UI change. The “solution” often takes more time than manual testing.

While Gemini provides powerful AI capabilities and MCP provides the protocol, Docker MCP Toolkit makes browser automation practical. Without containerization, setting up browser testing means managing Chrome/Firefox installations, dealing with WebDriver versions, configuring Node.js dependencies, handling screenshot directories manually, and different configurations for every developer’s machine. The setup that should take 2 minutes takes 2-6 hours per developer.

Docker MCP Toolkit eliminates this friction:

220+ pre-built MCP servers in the catalog

One-click deployment through Docker Desktop

Playwright MCP with browsers pre-installed (Chrome, Firefox, WebKit)

GitHub MCP for automated issue creation

Filesystem MCP for artifact storage

Secure credential management via OAuth or encrypted storage

Consistent configuration across Mac, Windows, and Linux

Automatic updates when new server versions are released

We built Docker MCP Toolkit to meet developers where they are. If you’re using Gemini CLI, you should be able to automate browser testing without wrestling with infrastructure.

Your tests run securely on your machine. Everything executes in isolated Docker containers on your local system. Test data, screenshots, and application access never leave your computer. No cloud uploads, no third-party services, no compliance concerns. You get enterprise-grade browser automation with complete privacy.

Setting up Gemini CLI in Docker MCP Toolkit

Prerequisites

Install Docker Desktop 4.40 or later

Enable MCP Toolkit 

Step 1. Install Gemini CLI

Install via npm:

npm install -g @google/gemini-cli

Step 2. Launch and authenticate

Once installed, just type gemini in your terminal window.

gemini

Step 3. Log in via Google

Follow the setup wizard:

Select a preferred theme style from the options.

Choose a login method. I recommend “Login with Google”, which allows up to 60 requests/minute and 1,000 requests/day for free

In case you need higher rate limits or enterprise access, I suggested you use an API key from Google AI Studio. You can easily set it as an environment variable:

export GEMINI_API_KEY="YOUR_API_KEY"

After selecting your sign-in method, a browser window will open. Simply log in with your Google account

Step 4. Start chatting with Gemini

Just type “gemini” in your terminal window to start chatting with Gemini and enter your prompt.

Connect Gemini CLI to Docker MCP Toolkit

Option 1: One-Click Connection (Recommended)

Open Docker Desktop

Navigate to MCP Toolkit in the sidebar

Click the Clients tab

Find “Gemini” in the list.

Click Connect

Docker Desktop automatically configures the MCP Gateway connection – the underlying infrastructure that routes requests between Gemini CLI and your MCP servers, handling authentication, containerisation, and secure communication seamlessly.

Option 2: Manual Command Line SetupIf you prefer a command-line setup or need to configure a specific project:

Navigate to your project folder in the terminal

Run this command:

docker mcp client connect gemini –global

You’ll see output like this:

=== System-wide MCP Configurations ===
● gemini: connected
MCP_DOCKER: Docker MCP Catalog (gateway server) (stdio)
● gordon: connected
MCP_DOCKER: Docker MCP Catalog (gateway server) (stdio)

You might have to restart 'gemini'.

The connected status confirms Gemini CLI is linked to the Docker MCP Gateway.

What’s happening under the hood?

The Gemini CLI uses the mcpServers configuration in your settings.json file to locate and connect to MCP servers. This configuration supports multiple servers with different transport mechanisms. The mcpServers object is where you define each MCP server you want the CLI to connect to.

Whenever you hit the “Connect” button under the Docker MCP Client for Gemini CLI, it adds the following Docker MCP Gateway configuration to the ~/.gemini/settings.json file.

{
"theme": "Default",
"selectedAuthType": "oauth-personal",
"mcpServers": {
"MCP_DOCKER": {
"command": "docker",
"args": ["mcp", "gateway", "run"],
"env": {}
}
}
}

Learn more about MCP and Gemini CLI interaction through this link.

Step 5. Restart Gemini CLI

# Exit Gemini CLI if running, then restart
gemini

Step 6. Verify the Connection

Inside Claude Code, type /mcp to see available MCP servers. 

You should see the Docker MCP Gateway listed, which provides access to all enabled MCP servers. The /MCP_DOCKER tools indicate a successful connection. As you enable more MCP servers in Docker Desktop, they’ll appear here automatically.

First Run: What to Expect

When you start Gemini CLI for the first time after connecting to Docker MCP Toolkit, you’ll see a prompt about the new MCP server:

Choose Option 1 (recommended). This configures your project to automatically use Docker MCP Toolkit and any MCP servers you enable in Docker Desktop. You won’t need to approve MCP servers individually each time.

You’re now ready to use Gemini with MCP servers from Docker Desktop.

Real-World Demo: Automated Browser Testing and Performance Analysis

Now that you’ve connected Gemini CLI to Docker MCP Toolkit, let’s see it in action with a practical example. We’ll automatically discover real bugs through browser testing and identify performance bottlenecks through detailed analysis — the kind that would take 20 minutes of manual testing, DevTools monitoring, and performance profiling.

What Makes This Realistic?

This isn’t a trivial “Hello World” demo. We’re performing comprehensive browser testing and performance analysis on a real e-commerce application with the kinds of issues you encounter in production:

Uses actual application running on localhost

Executes functional browser tests (navigation, element inspection, console monitoring)

Discovers genuine performance bottlenecks through browser DevTools analysis

Identifies accessibility violations that affect real users

Captures evidence with screenshots and console logs

Measures real performance metrics: page load times, network requests, resource usage

Creates properly formatted GitHub issues with actionable recommendations

Time investment:

Manual process: ~20 minutes (opening browsers, clicking through flows, DevTools analysis, performance profiling, documentation, issue creation)

Automated with Gemini CLI + MCP: ~30 seconds total

That’s a 97% time reduction, but more importantly, it’s consistent, thorough, and documented every time.

What We’re Testing

The catalog-service-node application is a realistic e-commerce catalog with intentional issues that mirror common production problems:

Performance Issues:

No pagination – loads all 15 products at once (will degrade with scale)

Duplicate API calls – requests /api/products twice unnecessarily

Missing optimization – unoptimized loading patterns

Accessibility Issues:

Missing product images – placeholder buttons instead of actual images

Vague button labels – “Fetch” and “Upload” aren’t descriptive for screen readers

Missing ARIA labels – table structure not properly announced

Browser Issues:

Missing favicon – generates 404 errors in console

Console warnings – duplicate request warnings

Let’s see if Gemini CLI can discover all of these automatically through intelligent browser testing and performance analysis, then create a comprehensive GitHub issue.

Step 1: Set Up a Real-World e-Commerce Catalog application

For this demo, we’ll use a real e-commerce catalog application. This gives us realistic performance and accessibility issues to discover.

Clone the repository:

git clone https://github.com/ajeetraina/catalog-service-node
cd catalog-service-node

Start all services:

# Start Docker services (database, S3, Kafka)
docker compose up -d

# Install dependencies
npm install –omit=optional

# Start the application
npm run dev

Verify it’s running:

Frontend: http://localhost:5173

API: http://localhost:3000

Step 2: Seed Test Data

To make testing realistic, create sample products:

# Create seed script
cat > seed-data.sh << 'EOF'
#!/bin/bash
API_URL="http://localhost:3000/api"

echo "Seeding test products…"

curl -s -X POST "$API_URL/products"
-H "Content-Type: application/json"
-d '{"name":"Vintage Camera","description":"Classic 35mm film camera","price":299.99,"upc":"CAM001"}'
> /dev/null && echo "✅ Vintage Camera"

curl -s -X POST "$API_URL/products"
-H "Content-Type: application/json"
-d '{"name":"Rare Vinyl Record – LAST ONE!","description":"Limited edition. Only 1 left!","price":149.99,"upc":"VINYL001"}'
> /dev/null && echo "✅ Rare Vinyl Record"

curl -s -X POST "$API_URL/products"
-H "Content-Type: application/json"
-d '{"name":"Professional DSLR Camera","description":"50MP camera with 8K video","price":2499.99,"upc":"CAMPRO001"}'
> /dev/null && echo "✅ Professional DSLR"

# Add bulk test products
for i in {4..15}; do
curl -s -X POST "$API_URL/products"
-H "Content-Type: application/json"
-d "{"name":"Test Product $i","description":"Bulk test product $i","price":$((50 + RANDOM % 450)).99,"upc":"BULK$(printf '%03d' $i)"}"
> /dev/null && echo "✅ Test Product $i"
done

echo ""
TOTAL=$(curl -s "$API_URL/products" | jq '. | length')
echo "Total products: $TOTAL"
echo "Ready! Visit http://localhost:5173"
EOF

chmod +x seed-data.sh
./seed-data.sh

Expected output:

Seeding test products…
✅ Vintage Camera
✅ Rare Vinyl Record
✅ Professional DSLR
✅ Test Product 4
✅ Test Product 5

✅ Test Product 15

Total products: 15
Ready! Visit http://localhost:5173

Now you have a realistic environment with 15 products to analyze.

Configure MCP Servers

For browser testing and performance analysis automation, you’ll orchestrate three MCP servers:

Playwright MCP – Controls browsers, takes screenshots, captures console logs

GitHub MCP – Creates issues automatically with full context

Filesystem MCP – Saves screenshots and test artifacts

Let’s configure each one.

Configure Playwright MCP (Browser Automation)

The Playwright MCP server gives Gemini the ability to control real browsers, Chrome, Firefox, and WebKit, just like a human would.

In Docker Desktop:

Open Docker Desktop → MCP Toolkit → Catalog

Search for “Playwright” or “Browser”

Find Playwright (Browser Automation) in the results

Click + Add

The server will be added with default configuration (no additional setup needed)

Click Start Server

What you get:

21+ browser automation tools including:

browser_navigate – Navigate to URLs

browser_snapshot – Capture page state for analysis

browser_take_screenshot – Save visual evidence

browser_click, browser_type – Interact with elements

browser_console_messages – Get console errors

browser_network_requests – Analyze HTTP requests

The Playwright MCP runs in a secure Docker container with browsers pre-installed. No manual ChromeDriver setup, no WebDriver conflicts, no OS-specific browser installations.

Configure GitHub MCP (Issue Creation)

The GitHub MCP enables Gemini to create issues, PRs, and manage repositories on your behalf.

Option 1: OAuth Authentication (Recommended – Easiest)

In MCP Toolkit → Catalog, search “GitHub Official”

Click + Add

Go to the OAuth tab in Docker Desktop

Find the GitHub entry

Click “Authorize”

Your browser opens GitHub’s authorization page

Click “Authorize Docker” on GitHub

You’re redirected back to Docker Desktop

Return to Catalog tab, find GitHub Official

Click Start Server

Advantage: No manual token creation. Authorization happens through GitHub’s secure OAuth flow with automatic token refresh.

Option 2: Personal Access Token (For Granular Control)

If you prefer manual control or need specific scopes:

Step 1: Create GitHub Personal Access Token

Go to https://github.com  and sign in

Click your profile picture → Settings

Scroll to “Developer settings” in the left sidebar

Click “Personal access tokens” → “Tokens (classic)”

Click “Generate new token” → “Generate new token (classic)”

Name it: “Docker MCP Browser Testing”

Select scopes:

repo (Full control of repositories)

workflow (Update GitHub Actions workflows)

Click “Generate token”

Copy the token immediately (you won’t see it again!)

Step 2: Configure in Docker Desktop

In MCP Toolkit → Catalog, find GitHub Official

Click + Add (if not already added)

Go to Configuration tab

Select “Personal Access Token” as the authentication method

Paste your token

Click Start Server

Or via CLI:

docker mcp secret set GITHUB.PERSONAL_ACCESS_TOKEN=github_pat_YOUR_TOKEN_HERE

Configure Filesystem MCP (Screenshot Storage)

The Filesystem MCP allows Gemini to save screenshots and test artifacts to your local machine.

In Docker Desktop:

Go to MCP Toolkit → Catalog

Search for “Filesystem”

Find Filesystem (Reference) and click + Add

Go to the Configuration tab

Under filesystem.paths, add your project directory:

Example: /Users/yourname/catalog-service-node

Or wherever you cloned the repository

You can add multiple paths by clicking the + button

Click Save

Click Start Server

Important Security Note: Only grant access to directories you’re comfortable with Gemini reading and writing to. The Filesystem MCP is scoped to these specific paths for your protection.

Run the Automation

Change directory to the root of the catalog-service-node project repository and open Gemini CLI:

gemini

Paste this prompt:

Navigate to http://host.docker.internal:5173 and perform a detailed
performance and accessibility analysis:

1. Take a screenshot of the full page
2. Count how many products are displayed
3. Open browser DevTools and check:
– Console for any JavaScript errors
– Network tab: how many HTTP requests are made?
– Performance: how long does the page take to load?
4. Identify performance issues:
– Are all products loading at once with no pagination?
– Are images optimized?
– Any unnecessary network requests?
5. Check for accessibility issues:
– Missing alt text on images
– Color contrast problems
– Vague button labels

Create a GitHub issue titled "Product catalog performance and
accessibility issues" with:
– Screenshots attached
– List of specific problems found
– Severity: Medium
– Labels: performance, accessibility, enhancement

Watch Gemini Work

Here’s what happens behind the scenes as Gemini orchestrates multiple MCP servers:

Step 1: Browser Navigation

The web server is running. I'll navigate to http://host.docker.internal:5173, take a screenshot, and then proceed with the rest of the performance analysis.

Gemini launches a real Chromium browser in the Docker container and navigates to your application.

Step 2: Console Analysis

✦ I can see 15 products listed on the page: * Vintage Camera * Rare Vinyl Record – LAST ONE! * Professional DSLR Camera * Test Product 4-15

Step 3: Performance Check

✦ Checking browser console and network requests… Opening DevTools to analyze performance metrics…

Step 4: Issue Creation

✦ Creating GitHub issue with findings…

create_issue (MCP_DOCKER MCP Server) {"labels":["performance","accessibility","enhancement"],"body":"### Summary…"}

✦ I have successfully created the issue. You can find it at: https://github.com/ajeetraina/catalog-service-node/issues/1

The Complete GitHub Issue

Gemini automatically created this comprehensive issue with structured information:

Workflow Comparison: Before vs After MCP

Step

Before MCP (Manual Testing)

Time

After MCP (Gemini CLI + MCP)

Time

1

Open browser manually

1 min

Paste prompt in Gemini CLI

5 sec

2

Navigate to application

30 sec

Gemini analyzes automatically

25 sec

3

Click through pages

3 min

GitHub issue created

auto

4

Open DevTools manually

30 sec

Screenshots attached

auto

5

Take screenshots

2 min

✓ Complete

6

Check browser console

1 min

7

Analyze network requests

2 min

8

Document findings

3 min

9

Write detailed bug report

5 min

10

Create GitHub issue

2 min

Summary

Total

~ 20 minutes per test

30 sec per test

Time saved per test: 19.5 minutes (97% faster!)

Impact over time:

Per day (5 tests): 97 minutes saved → 1.6 hours

Per week (25 tests): 8 hours saved → 1 full workday

Per sprint (50 tests): 16 hours saved → 2 full workdays

Per year (1,000 tests): 325 hours saved → 40 workdays

Wrapping Up

You’ve just witnessed how Docker MCP Toolkit transforms Gemini CLI from a chat assistant into a complete browser testing and performance analysis platform. What used to require opening browsers, clicking through flows, analyzing DevTools, documenting bugs, and creating issues manually now happens in one 30-second conversation.

The combination of Gemini CLI and Docker MCP Toolkit represents a paradigm shift in AI-assisted development. By leveraging terminal-native tools and containerized services, you get:

Unmatched flexibility in tool selection

Superior performance with minimal overhead

Future-proof architecture that scales with your needs

This setup isn’t just about convenience — it’s about building a development environment that adapts to your workflow rather than forcing you to adapt to it. The developer productivity revolution is here. The question isn’t whether you’ll adopt AI-assisted development — it’s whether you’ll lead with the best tools available or play catch-up later.

Ready to try it? Enable Docker MCP Toolkit in Docker Desktop and start building your own Gemini-powered development workflow today.

Learn more

Explore the MCP Catalog: Discover containerized, security-hardened MCP servers

Open Docker Desktop and get started with the MCP Toolkit (Requires version 4.48 or newer to launch the MCP Toolkit automatically)

Explore our guide on adding MCP Servers to Claude Code with the Docker MCP Toolkit

Check out our MCP Horror Stories series to see common MCP security pitfalls and how you can avoid them.

Quelle: https://blog.docker.com/feed/