RFC: Distributed Actions with MCP in Backstage
🔎 Search Terms
ActionsRegistry, MCP, Distributed Actions, Scaffolder, ModelContextProtocol
🔖 Need
Model Context Protocol (MCP) is a fast moving space right now, and there’s a need to enable different MCP tools that provide access to different information and data which is surfaced through plugins in Backstage.
While MCP tools are useful on their own, there is also an opportunity to align this work with the broader Backstage framework rather than having MCP be bolted on. In many cases we expect Software Template Actions to be more or less identical to their MCP tool counterparts. Consider examples like registering a new component in the Software Catalog, paging the owner of an Entity, or opening a Pull Request; these all have potential to provide value both as actions in a Software Template, and as MCP tools.
Another related area is the opportunity to simplify the installation of Scaffolder actions. Today each action needs to be installed as a module for the scaffolder, meaning that they need to be published in their own package separately from what might be the main plugin backend package. There is room for improvement here, where we instead only need to install a single package to both provide the base functionality of the plugin and actions related to the plugin.
📝 Proposal
We propose the ability for plugins to define actions without the need to install a module for the Scaffolder. This means that we need to provide APIs for plugins to use to define actions that would then later be able to be invoked from other plugins.
Actions Registry
For this, we’ve started iteration on an ActionsRegistryService and ActionsService, which would be part of the Core Services that are shipped out the box in Backstage. These allow plugins to define actions with a very similar API to the Scaffolder actions, but effectively these become distributed and installed with the plugins themselves.
The ActionsService is a client on top of all these actions that are defined in the ActionsRegistry, allowing a plugin author to list the available actions and invoke them.
MCP Integration
We will provide an MCP server on top of the ActionsRegistryService and ActionsService in order to map the available actions as tools for a server, and invoke them. This will be the first step in bringing MCP integration to Backstage, with a focus on simplicity and a lightweight integration.
In order to allow for flexibility in the MCP servers available to end users, it will be configurable to allow for creation of multiple MCP servers, each with their own list of integrated actions. This makes it possible to configure what exact actions an integrator wants to expose as MCP tools. The goal of this is to be able to provide different servers for specific context to end users, in order to let the user steer execution and avoid confusion between similar servers by only enabling the ones that are relevant for a specific task.
This MCP server would implement both the Streamable specification, with sessions stored in the DatabaseService, and the legacy SSE variant for backwards compatibility with older clients. We expect the SSE implementation to be deprecated from the initial implementation, and should be avoided if possible.
We expect actions registered in the ActionsRegistry to have sufficient descriptions and metadata for them to be usable as MCP tools directly. This means that we will recommend excessively verbose descriptions compared to what you might expect for only human consumption. In practice we’ve found that this is more often a benefit to the humans rather than the other way around, as the more verbose descriptions will help them too.
As a starting point, we aim to ship a few actions from the catalog-backend plugin that will give clients the ability to interact with the Software Catalog. This will allow LLMs to be able to parse data out of the Software Catalog, leading to other tools built on top of this data pretty easily.
In the future it’s possible that we will ship an mcp-node package, with frameworks and APIs there to help you create MCP servers and not have to worry about implementing things like Authentication and the Transport protocols, just the implementation of what is surfaced by the MCP server itself. We expect organizations to have a myriad of MCP servers both within and outside of Backstage, along with the tooling necessary to manage these servers in a scalable way. We therefore don’t expect a potential sprawl of MCP servers from individual plugins to add significant friction compared to if we aimed to manage them through the framework.
Authentication for MCP Servers and therefore tools is very much a moving target right now. Our intention is to ship the MCP backend initially with the default Backstage Token Authentication, with Device Authentication for Backstage becoming very much a priority in order to make authentication with Backstage MCP Servers as smooth as possible.
This integration focuses on simplicity and the implementation of small single purpose tools. We still see that there might be a need for a more advanced MCP server in the Backstage Ecosystem, utilizing things such as Resources and Prompts, but will hold off on building those types of integrations while we wait for the MCP space to mature.
🔄 Alternatives
We could skip the ActionsRegistry and the distributed actions concept as a whole. But this would lead to tools being defined in MCP servers not being available for use by the broader Backstage plugin ecosystem such as the Scaffolder. We do also see distributed actions as a big benefit to the Scaffolder alone as it makes it much easier for plugins to provide their own actions. We think it would be a mistake to not at the same time also make these actions available as MCP tools.
We could also look at just focusing on immediately making it easier from a framework level to make your own individual MCP Servers, i.e. implementing mcp-node much sooner. The thinking here is that the MCP spec is moving very fast, and we’d rather wait for the dust to settle around authentication and some of the other features of MCP, and just focus on the tool parts for now which benefits more of the Backstage plugin ecosystem.
Thanks for the write up @benjdlambert !
If I'm reading this correctly it sounds kind of vaguely comparable to some of the concepts we played with in our plugin at BackstageCon NA last year in terms of allowing plugins to expose "tools" to a registry? But here MCP is the fundamental model that would be used to interface with those tools. Is that right or am I misinterpreting?
@niallthomson I'd say it's similar yes. The goal here is to use the ActionsRegistry as a way to surface these tools into an MCP server, but also allowing these tools to be invoked by other plugins when they see fit without using LLMs and MCP.
This means that the contract isn't exactly the same as MCP, but very transferrable. I think there's a few reasons why using the MCP spec would be problematic, especially seen as the spec changes very often and we'd like some sense of stability.
The interfaces for creating Distributed Actions using the ActionsRegistry are being iterated on as we speak, but they're very similar to tool definitions with the MCP SDK directly.
I think it makes sense not to tie the implementation of the "actions" themselves to MCP, but have an MCP server be one of the ways they can be exposed.
Authentication for MCP Servers and therefore tools is very much a moving target right now. Our intention is to ship the MCP backend initially with the default Backstage Token Authentication, with https://github.com/backstage/backstage/pull/27680 for Backstage becoming very much a priority in order to make authentication with Backstage MCP Servers as smooth as possible.
If I put this part in simpler terms, does that mean initially it will be possible to authentication with service tokens, but not on behalf of specific users until that related authentication work is complete?
This looks amazing!! it would be great to also expose the those actions to a cli tool too. if the registry can be exported as a cli or even a library, will enable a lot of automation around each implementation.
@niallthomson that's correct. There's a little bit of docs here which specifically callout that this is basically just an interim solution until we work out how to take forward device authentication which will power authentication for MCP tools as well as CLI's etc.
Thanks for the clarification!
One thing that is probably not necessary immediately but will likely come up before long is being able to configure what actions the MCP server actually exposes as tools. As more plugins implement the action registry this will lead to a couple of problems:
- More MCP tools tends to make these AI assistants less effective
- Some assistants actually have hard limits on the number of MCP tools, like Cursor (40 at time of writing)
We are already running in to this issue on the AWS side given the large number of services we have.
Edit: I see this is noted in the plugin, is the action list there going to be shared between something like a CLI and the MCP server or its only for the MCP server?
@niallthomson so the RFC outlines that this will be a possibility:
In order to allow for flexibility in the MCP servers available to end users, it will be configurable to allow for creation of multiple MCP servers, each with their own list of integrated actions. This makes it possible to configure what exact actions an integrator wants to expose as MCP tools.
We just haven't implemented this yet, but like you we also see the need to be able to configure what's exposed, and also configure different servers for different things.
I've also seen differences in opinions around the webs into if more tools > more servers, and less tools > more tools, so we wanna keep this open for people to configure how they see fit of course.
is the action list there going to be shared between something like a CLI and the MCP server or its only for the MCP server?
Might be misunderstanding here, but the pluginSources config bit in the backend.actions config, basically tells the Actions service what plugins to index. You can effectively deploy multiple versions of the mcp-actions-backend with different configs there to pull actions from different sources, but as mentioned above there's no way right now to filter actions that are exposed as MCP tools right now.
One thing that is probably not necessary immediately but will likely come up before long is being able to configure what actions the MCP server actually exposes as tools.
Not a bad thing to think about, but most Agent frameworks provide a way to filter tools returned by the server to manage the issue of too many tools causing a performance fall off. However, having the tools list being dynamically refreshed via push (to those clients who support it) would be a very good thing.
Not a bad thing to think about, but most Agent frameworks provide a way to filter tools returned by the server to manage the issue of too many tools causing a performance fall off. However, having the tools list being dynamically refreshed via push (to those clients who support it) would be a very good thing.
Agent frameworks yes, but I think that a lot of dev tools like Cline, Roo, Q Developer so far don't let you filter tools, just servers. This may change but its pretty common right now.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Hopefully not stale
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Not stale