Self-hosted service
ip2a/mcpstore avatar
ip2a/mcpstore

mcpstore: a Rust control plane for MCP services, with Python and Rust SDKs

Elegantly manage your MCP services

431 stars30 forksRustMIT

At a glance

What is it?
mcpstore manages MCP servers from a CLI, a beta desktop GUI, an HTTP API, or embedded SDKs, and converts their tools into LangChain, LangGraph, OpenAI, AutoGen, CrewAI and LlamaIndex formats. The interesting part is the split between a control plane and a data plane, and the awkward part is that the README never explains what happens when a service fails to start.
Who is it for?
Adopt mcpstore if you already run several MCP servers and want one place to add, connect, restart and remove them, plus a single call that returns framework-shaped tools for LangChain, LangGraph, OpenAI, AutoGen, CrewAI or LlamaIndex. Do not adopt it if you only need one local stdio server wired into one script, because the store abstraction and its scope model add a layer you will not use.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem mcpstore addresses: MCP servers accumulate faster than anyone manages them

MCP has a configuration problem before it has a capability problem. Each client keeps its own list of servers, each server is described as a JSON blob with a name, a URL or a command, and the same server gets re-declared in every project that needs it. When one of those servers stops responding, there is no shared place to look. mcpstore is aimed at that layer. The README describes it as "MCP management built with Rust" and the CLI verbs confirm the intent: add, list, connect, remove, restart. The audience is anyone running more than a couple of MCP servers, and specifically teams whose agents need different subsets of those servers. The for_agent(agent_id) scope in the Python SDK exists for that case: agent1 gets the wiki service, agent2 gets the GitHub server, and each scope lists only its own tools. That is a management product, not a protocol implementation.

Control plane, data plane, and what that split buys you

The README states that the architecture "mirrors Kubernetes-style control plane / data plane: the control plane handles orchestration, while the data plane focuses on invocation." The practical consequence is stated in the next sentence: on resource-constrained hosts you can attach only the data plane and call already-shared MCP services with zero local maintenance. That is the design claim worth taking seriously. Orchestration (starting processes, holding config, tracking which services are connected) happens once, somewhere with resources. Invocation happens wherever the agent runs. The material does not describe the wire protocol between the two planes, nor does it say how a data-plane-only host discovers the control plane. That is a gap. If you are evaluating this for an edge deployment, the README gives you the shape of the answer but not the configuration keys to make it real.

Getting it running: npm, curl, or cargo

Three install paths appear in the material. The global npm install is `npm install -g ip2a@mcpstore`, which is worth reading carefully because the package name is ip2a@mcpstore rather than mcpstore. The shell installer is `curl -fsSL https://raw.githubusercontent.com/ip2a/mcpstore/main/install.sh | bash`. For embedding, `pip install mcpstore` for Python and `cargo add mcpstore` for Rust. The CLI then takes commands of the form `mcpstore add wiki https://example.com/mcp`, followed by `mcpstore list`, `mcpstore connect wiki` and `mcpstore remove wiki`. Two inspection commands are given: `mcpstore config show` and `mcpstore web` for the Web UI. The HTTP API is started with `mcpstore api --host 127.0.0.1 --port 1820`, so the two flags you need are --host and --port. The desktop GUI is labelled Beta and is downloaded from GitHub Releases rather than installed from a package manager. Nothing in the README describes platform-specific install caveats, so treat the three download badges (macOS, Windows, Linux) as the supported set.

The Python SDK's scope model is the part that needs a second read

Setup is one call: `store = MCPStore.setup_store()`. From there, `store.for_store()` gives a global scope for managing services and tools, and `store.for_agent(agent_id)` gives an independent scope per agent. The two scopes accept different config shapes, which the README shows without comment. The global form nests under an mcpServers key: `{"mcpServers": {"mcpstore_wiki": {"url": "https://example.com/mcp"}}}`. The agent form is flat and takes a name plus either a url or a command with args, as in the GitHub example using `npx` with `-y` and `@modelcontextprotocol/server-github`. Whether that difference is intentional or an artifact of the examples is not stated. If you copy the global shape into for_agent() or the reverse, you are guessing. The Rust SDK takes a third shape again: `McpConfig::from_json_str` with a flat `{"name":..., "url":...}` object, and waits via `ServiceTarget::ServiceName("mcpstore_wiki")` with a `Duration::from_secs(30)` timeout. Three config shapes for one concept is friction you should budget for.

Framework adapters: one store, six tool formats

The adapter table is the most concrete thing in the README. LangChain, LangGraph, OpenAI, AutoGen, CrewAI and LlamaIndex each get a one-line call of the form `tools = store.for_store().for_langchain().list_tools()`, with the framework name swapped. The chain reads as scope first, framework second, then list_tools(). This means the same registered services can feed agents built on different frameworks without re-declaring the servers for each one. The Python example wires the result into `create_agent(model=llm, tools=tools, system_prompt=...)` from langchain.agents and invokes it with a messages array. Note that the example passes a real-looking api_key placeholder and a base_url, so it assumes an OpenAI-compatible endpoint. The adapters are the reason to pick mcpstore over hand-written MCP client code: the conversion work is already done and the framework list covers most of what Python agent developers actually use.

Where the documentation stops being useful

Failure behaviour is undocumented. The README shows `wait_service("mcpstore_wiki")` in Python and `wait_service(ServiceTarget::ServiceName(...), Duration::from_secs(30))` in Rust, but never says what happens when the wait expires, when a URL is unreachable, or when an npx-based stdio server cannot start because the package is missing. Those are the three failure modes you will hit first with any MCP manager, and none of them are described. The API surface has the same asymmetry: list_services, list_tools, list_prompts and show_config are documented, and so are restart_service and disconnect_service, but there is no mention of logs, health checks, retry policy or how a crashed service is reported. The desktop app is Beta, which the README states plainly, so treat the GUI as a convenience layer rather than the supported interface. And the homepage is listed as a GitHub Pages site while the README's own links point at the repository, so there may be more documentation elsewhere that this material does not include.

What to compare it against, and the licence and maintenance picture

The obvious alternative is not another manager but the MCP client built into whatever framework you already use. LangChain's MCP integration loads servers from a config file and exposes tools directly; you write the config, you get the tools, and there is no store object, no scope model and no second install. The difference in approach is real: mcpstore centralises service state so that adding a server once makes it available to every framework adapter and every agent scope, while framework-native loading keeps each project self-contained and repeats the server list per project. If your server list is short and stable, the framework-native path has fewer moving parts. If it is long, shared across agents, or needs a restart verb, mcpstore is the better fit. On licensing, the repository is MIT, which permits commercial use and modification; the README does not state how the desktop binary is distributed or whether any component carries a different licence, so check the release artefacts and any bundled dependency licences yourself rather than assuming MIT covers the whole distribution. On maintenance, the release cadence visible in the material is tight: v2.2.0 and v2.2.1 on consecutive days in late August 2026, then v2.3.0 about a day later, with a push to main in early September. Frequent patch releases at that rate can mean active bug fixing or a stabilising API; the README does not publish a compatibility policy, so pin the version you install and read the release notes before moving between minor versions. This is not legal advice.

Editorial conclusion

Adopt mcpstore if you already run several MCP servers and want one place to add, connect, restart and remove them, plus a single call that returns framework-shaped tools for LangChain, LangGraph, OpenAI, AutoGen, CrewAI or LlamaIndex. Do not adopt it if you only need one local stdio server wired into one script, because the store abstraction and its scope model add a layer you will not use. Verify three things first: the exact scope semantics of for_store() versus for_agent(), whether wait_service() surfaces a timeout or a silent failure when a remote URL never answers, and whether the Python SDK on PyPI matches the v2.3.0 release you are reading about.

Official sources

  1. ip2a/mcpstore on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes