ToolHive: Making MCP Servers Easy, Secure, and Fun

We are excited about the potential of Model Context Protocol (MCP) servers and inspired to make it more consistent to set up, easier to configure and overall secure. So, we're releasing ToolHive as an open-source project that uses existing technology (e.g. Docker and Kubernetes) for better packaging, security utilities, and more. Let's build on MCP together! TL;DR ToolHive helps you run MCP servers in an easy, secure, and opinionated way. ToolHive leverages container runtimes (e.g. the Docker runtime) to do so. ToolHive is open source, and we welcome contributions! Here's the repository Join us in Discord! How it started MCP has generated a lot of hype recently in the AI ecosystem. When we first heard about it, it felt just right: a formalization of how AI clients and agents can interact with external APIs, a potential ecosystem, and a lot of opportunities. So, to get myself better acquainted with this, I decided to try it out. There were already a lot of folks building MCP servers and many tutorials on setting them up, so this part wasn’t too hard. However, when I started going through the tutorials, some things felt off. I was sure I wasn’t the only one, so I kicked off an exploration phase with a colleague, and we started gathering information. We landed on three main points of friction: Search & Discovery Challenges Inconsistency & Installation Friction Credential & Permission Concerns Let’s go through the three friction points and expand. Search & Discovery Challenges When exploring the tooling, I and everybody I talked to had different answers to how we found servers. Docker provides a set of official MCP servers in a dedicated namespace, Anthropic has a set of examples, there are a bunch of “Awesome MCP” lists, and nowadays there are even services that allow you to use hosted MCPs. But a lot of questions lingered: Which MCP is the right one for me? How do I know if I can trust it? Finding MCP servers is not as simple as it could be, and finding the right one has its challenges. We clearly aren’t the only ones thinking about this; the recent disclosure of Tool Poisoning Attacks presents issues relating to this realm. Inconsistency & Installation Friction Once you’ve found a subset of MCP servers that work for your use case, the next issue is learning how to install and use them. At the time of writing, we found several implementations that didn’t work. Don’t get me wrong, software quality issues are common, especially in a community as new and fast-moving as MCP. But it is challenging for us early adopters. Before going forward, I must give props to Docker and Anthropic for their curated lists of MCP servers since they’re what’s worked the best for me so far. So, when looking at MCP installation instructions, they’d often look like this: { "mcpServers": { "some-mcp": { "command": "npx", "args": [ "-y", "@namespace/mcp-name" ] } } } I have to install npx? I’m one of those people who run an immutable Linux distribution (Fedora Silverblue) as my daily driver. If I need a tool, I’ll run a dedicated container or a toolbox for that. I’m not keen on allowing my IDE to run npx commands… But anyway, let’s see other implementations and figure out how to run them. And this is where I saw a lot of divergence. Some use uv, some use docker, and there are a lot more invocation styles for this! Credential & Permission Concerns Finally, when looking at other implementations, I stumbled upon something like this: { "mcpServers": { "some-mcp": { "command": "npx", "args": [ "-y", "@namespace/mcp-name" ], "env": { "MCP_API_KEY": "YOUR_API_KEY_HERE" } } } } Do I have to copy my API key into a clear text configuration file? As a security engineer, this feels like a no-go for me. And, once I run it, how do I know if it’s not sending my keys elsewhere? Enter ToolHive To address this, we decided to start project ToolHive to run MCP servers in an easy, consistent, and secure manner. This is not a problem that a single company can and should fix alone. And, given that security and community are our backbone, we’re open-sourcing it! ToolHive is an opinionated way of running MCP servers that takes best practices and packages them in a simple utility. Simply use the command thv run to get an MCP server running locally. ToolHive can also help configure your clients by automatically inserting the MCP entry into the right config file. Today we support Cursor, Roo Code, and GitHub Copilot in VS Code, with more to come. Docker (OCI) images are here to stay Packaging software can be challenging, but we already have solutions to this. And, coming from the Cloud Native community, we believe that Docker images sure get us a lot closer to the state we’d like in packaging MCP servers. They allow for better consistency

Apr 9, 2025 - 09:13
 0
ToolHive: Making MCP Servers Easy, Secure, and Fun

We are excited about the potential of Model Context Protocol (MCP) servers and inspired to make it more consistent to set up, easier to configure and overall secure. So, we're releasing ToolHive as an open-source project that uses existing technology (e.g. Docker and Kubernetes) for better packaging, security utilities, and more. Let's build on MCP together!

TL;DR

  • ToolHive helps you run MCP servers in an easy, secure, and opinionated way.
  • ToolHive leverages container runtimes (e.g. the Docker runtime) to do so.
  • ToolHive is open source, and we welcome contributions!
  • Here's the repository
  • Join us in Discord!

How it started

MCP has generated a lot of hype recently in the AI ecosystem. When we first heard about it, it felt just right: a formalization of how AI clients and agents can interact with external APIs, a potential ecosystem, and a lot of opportunities. So, to get myself better acquainted with this, I decided to try it out. There were already a lot of folks building MCP servers and many tutorials on setting them up, so this part wasn’t too hard. However, when I started going through the tutorials, some things felt off. I was sure I wasn’t the only one, so I kicked off an exploration phase with a colleague, and we started gathering information. We landed on three main points of friction:

  • Search & Discovery Challenges
  • Inconsistency & Installation Friction
  • Credential & Permission Concerns

Let’s go through the three friction points and expand.

Search & Discovery Challenges

When exploring the tooling, I and everybody I talked to had different answers to how we found servers. Docker provides a set of official MCP servers in a dedicated namespace, Anthropic has a set of examples, there are a bunch of “Awesome MCP” lists, and nowadays there are even services that allow you to use hosted MCPs. But a lot of questions lingered:

  • Which MCP is the right one for me?
  • How do I know if I can trust it?

Finding MCP servers is not as simple as it could be, and finding the right one has its challenges. We clearly aren’t the only ones thinking about this; the recent disclosure of Tool Poisoning Attacks presents issues relating to this realm.

Inconsistency & Installation Friction

Once you’ve found a subset of MCP servers that work for your use case, the next issue is learning how to install and use them.

At the time of writing, we found several implementations that didn’t work. Don’t get me wrong, software quality issues are common, especially in a community as new and fast-moving as MCP. But it is challenging for us early adopters. Before going forward, I must give props to Docker and Anthropic for their curated lists of MCP servers since they’re what’s worked the best for me so far.

So, when looking at MCP installation instructions, they’d often look like this:

{
  "mcpServers": {
    "some-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@namespace/mcp-name"
      ]
    }
  }
}

I have to install npx? I’m one of those people who run an immutable Linux distribution (Fedora Silverblue) as my daily driver. If I need a tool, I’ll run a dedicated container or a toolbox for that. I’m not keen on allowing my IDE to run npx commands…

But anyway, let’s see other implementations and figure out how to run them. And this is where I saw a lot of divergence. Some use uv, some use docker, and there are a lot more invocation styles for this!

Credential & Permission Concerns

Finally, when looking at other implementations, I stumbled upon something like this:

{
  "mcpServers": {
    "some-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@namespace/mcp-name"
      ],
      "env": {
        "MCP_API_KEY": "YOUR_API_KEY_HERE"
      }
    }
  }
}

Do I have to copy my API key into a clear text configuration file? As a security engineer, this feels like a no-go for me. And, once I run it, how do I know if it’s not sending my keys elsewhere?

Enter ToolHive

To address this, we decided to start project ToolHive to run MCP servers in an easy, consistent, and secure manner. This is not a problem that a single company can and should fix alone. And, given that security and community are our backbone, we’re open-sourcing it!

ToolHive is an opinionated way of running MCP servers that takes best practices and packages them in a simple utility.

Simply use the command thv run to get an MCP server running locally.

ToolHive can also help configure your clients by automatically inserting the MCP entry into the right config file. Today we support Cursor, Roo Code, and GitHub Copilot in VS Code, with more to come.

Docker (OCI) images are here to stay

Packaging software can be challenging, but we already have solutions to this. And, coming from the Cloud Native community, we believe that Docker images sure get us a lot closer to the state we’d like in packaging MCP servers. They allow for better consistency in packaging plus they allow us to leverage a lot of the security utilities that have been developed over recent years:

  • Container signatures
  • SBOMs tied to image tags
  • Attestations
  • Vulnerability Scanning

There’s a lot we can inherit from the ecosystem by simply converging on this format.

Containers, containers, containers

ToolHive itself does not re-invent the wheel. It simply is a wrapper that leverages existing technologies to do its job. In a local experience, ToolHive uses Docker (or any other container runtime of your choice) to spawn containers that run the server. It then spawns a proxy that ensures one way of serving that utility. Today, we’ve implemented HTTP SSE as the transport protocol of choice. This was done given current client support for this. However, when more clients start adopting the new Streamable HTTP transport, we’ll likely migrate to that.

So, you end up with one endpoint per MCP server you run.

We’re aware that a local experience is not going to be the only one that folks want to leverage, so we also added a Kubernetes runtime! This way, you can run your servers as you see fit, where you see fit.

Let secrets be secret

We’re not very keen on API keys leaking, and thus we decided to implement secret storage as part of this. Simply use the command thv secret set , to store an API key securely. To use it, you can reference the key as follows:

thv run --secret secret-key,target=ENV_API_KEY 

There is no need to copy secrets across configuration files!

Here’s how they’d look in the end:

{
  "mcpServers": {
    "fetch": {
      "url": "http://localhost:23971/sse#fetch"
    },
    "brave-search": {
      "url": "http://localhost:23872/sse#brave-search"
    },
    "sequentialthinking": {
      "url": "http://localhost:29313/sse#sequentialthinking"
    }
  }
}

ToolHive encrypts your secrets to keep them safe, including keyring support for Linux and macOS! We’ll dedicate a later blog post to this topic.

Find your tools

We’ve also implemented a basic MCP registry to allow you to easily find the tools you need depending on your use case. The thv search command allows you to search by tag or keyword, and the thv registry list allows you to view all the registry entries we’ve packaged so far.

The intention is not for us to be the ultimate gatekeepers of this. We’re happy to help curate entries, and we’re also glad to keep adding entries, but this is somewhere we welcome the community to engage. We’d like to make this more pluggable, and we’d like to have the community help in curation. This tool is meant for everyone, and we believe the community can do a better job in shepherding this effort.

Let’s lock things down

To address some of the security concerns we’ve encountered with MCP servers, we decided to propose a permission system for ToolHive. A sample would look as follows:

{
  "read": [],
  "write": [],
  "network": {
    "outbound": {
      "insecure_allow_all": false,
      "allow_transport": [
        "tcp"
      ],
      "allow_host": [
        "docs.github.com",
        "github.com"
      ],
      "allow_port": [
        443
      ]
    }
  }
}

This allows the MCP to access GitHub through port 443 and nothing else.

With this, we’re hoping to address concerns of keys leaking to external and unauthorized servers. Implementation of this is still in progress, so it’s a good time to join and chime in!

Wait… But there’s more!

We added support for running MCPs over Kubernetes, which allows you to host your tools in your own cluster.

We are also looking into authentication and authorization, bringing end-to-end security for the framework.

We’ll be talking about these in detail in further blog posts. There are a lot of things to come!

Join the fun!

ToolHive is open source, and we welcome contributions!

Whether you want to propose new MCP servers for the registry, add new functionality and features, or help us with documentation, we welcome everybody to join! It is only as a community that we can thrive.

Join us on Discord and check out the repo!

I’ll take some time to write further about the challenges we’re solving and dig deeper into each of the friction points, as well as the solutions that ToolHive proposes. Stay tuned!