Skip to content

RFC for internal MCP server in substitution of the current go version - #232

Open
chargio wants to merge 6 commits into
mainfrom
updating_MCP_to_reuse_internal_tools
Open

RFC for internal MCP server in substitution of the current go version#232
chargio wants to merge 6 commits into
mainfrom
updating_MCP_to_reuse_internal_tools

Conversation

@chargio

@chargio chargio commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Description

RFC to describe the actions required to implement the MCP server as a web server instead of an external go application.

Fixes #
Reduces complexity of the implementation and test of the MCP server, reducing duplicated code.

Documentation changes

Yes

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an RFC describing a proposed migration from the current external Go-based MCP server to an internal Elixir/Phoenix-hosted MCP server, aiming to simplify deployment and reduce duplicated tooling between Trento and the internal agent (Liz).

Changes:

  • Introduces RFC 0005 outlining motivation, security model, and configuration implications for an internal MCP server.
  • Compares current Go MCP bridge configuration with an internal Anubis-based approach.
  • Documents migration caveats and endpoint/configuration considerations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc
Comment thread content/rfc/0005-migrate-to-internal-MCP-sever.adoc Outdated
Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated
Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated
Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated
Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated
Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated
Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated

@antgamdia antgamdia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for writing it up! Before jumping to major discussion, just some minor notes and typos.

Edit: copilot was faster 😅

* As a user, I want to have a similar experience when I am using the internal AI agent (Liz) and when I am using the external MCP agent, so that I can use Trento in a consistent way.
* As a user, I want to be able to enable/disable the MCP server
* As a user, I want to be able to configure the MCP server.
* As a user, I want to use MCPHost to connect to the MCP server in SLES 16.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* As a user, I want to use MCPHost to connect to the MCP server in SLES 16.
* As a user, I want to use MCPHost/Kit to connect to the MCP server in SLES 16.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: are we talking about https://github.com/mark3labs/mcphost and https://github.com/mark3labs/kit? Or something else?

Let's add a reference in any case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarified the text and added a link to kit, as mcphost is deprecated and substituted by it and it will be updated in SLES

Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated
* define the changes required to migrate to an internal MCP server, and what would be the tradeoffs.
* define a migration path to move from the current MCP server to the new internal one.

THe current MCP server is a Go application that implements the MCP protocol, and it is used by the external agent to communicate with Trento. Installing the MCP server requires indepedent configuration and connection to an existing installation, introducing a bigger attack surface and configuration problems. The Trento MCP server requires:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
THe current MCP server is a Go application that implements the MCP protocol, and it is used by the external agent to communicate with Trento. Installing the MCP server requires indepedent configuration and connection to an existing installation, introducing a bigger attack surface and configuration problems. The Trento MCP server requires:
The current MCP server is a Go application that implements the MCP protocol, and it is used by the external agent to communicate with Trento. Installing the MCP server requires independent configuration and connection to an existing installation, introducing a bigger attack surface and configuration problems. The Trento MCP server requires:

- A Trento Personal Access Token (PAT), generated from your Trento user profile for secure API access.
- Configuration in /etc/trento/mcp-server-trento

The Trento MCP server today is a Go applcation, that acts as a bridge between the MCP clients and the Trento API, automatically generating MCP tools from the OpenAPI specification.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The Trento MCP server today is a Go applcation, that acts as a bridge between the MCP clients and the Trento API, automatically generating MCP tools from the OpenAPI specification.
The Trento MCP server today is a Go application that acts as a bridge between the MCP clients and the Trento API, automatically generating MCP tools from the OpenAPI specification.


The Trento MCP server today is a Go applcation, that acts as a bridge between the MCP clients and the Trento API, automatically generating MCP tools from the OpenAPI specification.

The trento MCP server generates a list of tools based on the OpenAPI specification, using labels to define which tools are available for the MCP clients.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: for that we actually use a 3rd-party dependency, https://pkg.go.dev/github.com/evcc-io/openapi-mcp, to which we usually contribute whenever we find bugs... but it is not widely used right now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the link to the text.

Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated
Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc
Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated
== Additional considerations
- It would be optional to create a solution that can provide the MCP server as an application inside the BEAM (umbrella application). In that case, it would be possible to define via configuration if the MCP server is started or not, and it would be possible to run it standalone. In an umbrella application, tests for each application are independent. Umbrella applications would imply additional complexity, and it is not clear if it would be worth the effort. The current proposal is to have the MCP server as part of the Trento application, and it would be started automatically when Trento is started. An application inside the BEAM would be a nice to have, but it would require additional work to transition from a single application to a series of applications, in which case the MCP would be one of them.

- The endpoint is currently defined as `trento-server/mcp-server_endpoint/mcp`. It would make sense to simplify the endpoint to be `trento-server/mcp`, as the endpoint is already defined in the Trento application, and it is not necessary to have a separate endpoint for the MCP server. The current proposal is to keep the endpoint as it is, but it would be nice to have a simpler endpoint or even double it and deprecate the old one. No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please explain how is this consideration consistent with the desire/need to have a configurableTRENTO_MCP_PORT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current solution is puslished at the trento-server/mcp-server_endpoint/mcp endpoint in port 5000. With the new to decide if we want to have it in the same port or we want to have it in a different port (no longer needed as the pipeline is the same and not a different component in the same system requiring a separate port)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also noticed the same inconsistency and left a similar related comment elsewhere.

TLDR: I don't see, yet, a need to have a different endpoint (as in the Phoenix.Endpoint meaning) for the embedded mcp server. It could very well be a route in the current endpoint.

Unless I am missing something.

== Additional considerations
- It would be optional to create a solution that can provide the MCP server as an application inside the BEAM (umbrella application). In that case, it would be possible to define via configuration if the MCP server is started or not, and it would be possible to run it standalone. In an umbrella application, tests for each application are independent. Umbrella applications would imply additional complexity, and it is not clear if it would be worth the effort. The current proposal is to have the MCP server as part of the Trento application, and it would be started automatically when Trento is started. An application inside the BEAM would be a nice to have, but it would require additional work to transition from a single application to a series of applications, in which case the MCP would be one of them.

- The endpoint is currently defined as `trento-server/mcp-server_endpoint/mcp`. It would make sense to simplify the endpoint to be `trento-server/mcp`, as the endpoint is already defined in the Trento application, and it is not necessary to have a separate endpoint for the MCP server. The current proposal is to keep the endpoint as it is, but it would be nice to have a simpler endpoint or even double it and deprecate the old one. No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please explain further what would "even double it and deprecate the old one" mean in more concrete terms?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have both endpoints available in routes, the existing one and the simplified ones, pointing to the same application.
Then we can deprecate the old one and migrate in time to the new one.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this part,

|Environment variable | default value | Detail
| TRENTO_MCP_ENABLED | false | Whether the internal MCP server is enabled or not. If false, the internal MCP server will not be started.
| TRENTO_MCP_PORT | 5000 | The port on which the MCP server listens for incoming connections with HTTP transport
| TRENTO_MCP_LOG_LEVEL | info | The verbosity level of the MCP server logs. Possible values are: debug, info, warn, error

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any thoughts/opinions on mapping MCP server logs to ActivityLogs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you ellaborate?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Activity log is not related to the mentioned log level here. I understand we are talking about application logs.

Besides this, in the context of an elixir embedded MCP server I would start by only relying on the global web logger and its configuration.

Yes, I believe we can configure multiple loggers and what not, it's just a matter of avoiding accidental complexity where we have more than enough inherent complexity 😅

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding an additional consideration to decide if we map the current log level to a new log level configuration or we merge it with the current log level.

@nelsonkopliku nelsonkopliku left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @chargio for the effort.

I am assuming that this RFC is coming from a clarification of the fact that from a broader product perspective we DO NOT NEED a separate artifact called mcp-server-trento

If that is the case then TLDR:

I think the idea of simplifying the overall system by embedding the mcp server inside trento-web would have several benefits:

  • for customers as they would have less operational burden
  • for us as we would improve maintainability
  • for the feature stability as it would reduce the networking roundtrip needed with the current proxy

However, as mentioned in the long-ish comment inline I believe this is a delicate decision that requires even more careful thinking and iteration on actual options.

If there was an expectation for this to happen before trento 3.2, I am afraid we will need to revisit that expectation.

Happy to discuss more, either in this RFC and/or sync.


* As a user, I want to be able to publish capabilities of Trento using the MCP protocol, so that it can be used by an external agent.
* As a user, I want to have a similar experience when I am using the internal AI agent (Liz) and when I am using the external MCP agent, so that I can use Trento in a consistent way.
* As a user, I want to be able to enable/disable the MCP server

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: we need to define whether the MCP server is enabled/disabled at startup via env variables or via UI.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that if the RFC is approved, we will need to work to refine the implementation.
Whether is done in 3.2 or later is a question of priorities and roadmap.
This adds the requirement to the backlog

* As a user, I want to be able to publish capabilities of Trento using the MCP protocol, so that it can be used by an external agent.
* As a user, I want to have a similar experience when I am using the internal AI agent (Liz) and when I am using the external MCP agent, so that I can use Trento in a consistent way.
* As a user, I want to be able to enable/disable the MCP server
* As a user, I want to be able to configure the MCP server.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: what kind of configuration does this entail?

Is it about configuring the endpoint/port where the MCP server listens to, if even necessary? Or is it about configuring which tools are exposed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current MCP requires configuration (you provide the port and the log level) and a bunch of other configurations in the mcp-server-trento.example.

I understand that supporting MCP server configuration to substitute MCP server configurations for the old server is just standard practice and does not require further explanation.

* As a user, I want to have a similar experience when I am using the internal AI agent (Liz) and when I am using the external MCP agent, so that I can use Trento in a consistent way.
* As a user, I want to be able to enable/disable the MCP server
* As a user, I want to be able to configure the MCP server.
* As a user, I want to use MCPHost to connect to the MCP server in SLES 16.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: are we talking about https://github.com/mark3labs/mcphost and https://github.com/mark3labs/kit? Or something else?

Let's add a reference in any case.

* As a user, I want to be able to enable/disable the MCP server
* As a user, I want to be able to configure the MCP server.
* As a user, I want to use MCPHost to connect to the MCP server in SLES 16.
* As a user, I want to use both streamable and sse as the transport protocols for the MCP server, so that I can use the one that is more suitable for my environment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: in latest MCP spec, SSE seems to be the legacy way https://modelcontextprotocol.io/specification/2025-11-25/basic/transports.

Let's agree which transport we should support.

* As a user, I want to be able to configure the MCP server.
* As a user, I want to use MCPHost to connect to the MCP server in SLES 16.
* As a user, I want to use both streamable and sse as the transport protocols for the MCP server, so that I can use the one that is more suitable for my environment.
* As a developer, I want to reduce the maintenance needed for the alignment of tools used by Liz and by the MCP server, so that the customer gets the same capabilities and responses independently of how they use it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: this is already the case currently. "MCP" tagged open api endpoints become automatically available tools to MCP server and Liz implementation.


1. The Go bridge that we were using before gives you the API for free, only taking into account the tags required to expose it. Using Anubis in Elixir is already automated. The same "MCP" tags used in the Trento server are used to configure the AI assistant's toolset and so that they continue being aligned automatically. The only new work is the authentication plug.

2. Additional work needs to be done to add a health check endpoint to the internal MCP server, as the current health check is done by the Go bridge. The health check should be implemented in Elixir, reusing the existing liveness/readiness endpoints.

@nelsonkopliku nelsonkopliku Jul 22, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: besides the fact that removing the extra artifact clearly removes also all it involves, in the context of an embedded mcp server in trento web, what would the existing /healthz and /readyz endpoints need to do differently?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently the endpoints are related to the endpoints in a different port. We publish endpoints for healthchecks at /mcp-server_endpoint/mcp /healthz and /readyz.
If we decide to update the endpoint to /mcp reusing Trento web endpoint, the healthz and readyz endpoints will be those of web, so we need to publish/develop new ones at /mcp/healthz and /mcp/readyz or drop them completely.


2. Additional work needs to be done to add a health check endpoint to the internal MCP server, as the current health check is done by the Go bridge. The health check should be implemented in Elixir, reusing the existing liveness/readiness endpoints.

3. There is no way to install the MCP server as a separate application. By design, the internal MCP server is part of the Trento application, and it is not possible to install it separately.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: not necessary content IMHO, the whole RFC is about removing a separate application.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the whole RFC is about removing it as a separate application, but I am highlighting that point. If the expectation is that it can be run as a separate application, it is not possible unless we evolve the architecture to support an umbrella app.


3. There is no way to install the MCP server as a separate application. By design, the internal MCP server is part of the Trento application, and it is not possible to install it separately.

4. You can't use command-line flags to configure the internal MCP server. The configuration is done via the Elixir config files or environment variables. Additional UX design should be done to include them as part of the command line for Trento itself.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: not necessary content IMHO. The what and the how about configuration is an implementation detail at this stage.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a list of things that will require additional design or that can become a problem, in the idea that are not. Listing things that can be considered is not defining an implementation

Comment thread content/rfc/0005-migrate-to-internal-mcp-server.adoc Outdated
== Additional considerations
- It would be optional to create a solution that can provide the MCP server as an application inside the BEAM (umbrella application). In that case, it would be possible to define via configuration if the MCP server is started or not, and it would be possible to run it standalone. In an umbrella application, tests for each application are independent. Umbrella applications would imply additional complexity, and it is not clear if it would be worth the effort. The current proposal is to have the MCP server as part of the Trento application, and it would be started automatically when Trento is started. An application inside the BEAM would be a nice to have, but it would require additional work to transition from a single application to a series of applications, in which case the MCP would be one of them.

- The endpoint is currently defined as `trento-server/mcp-server_endpoint/mcp`. It would make sense to simplify the endpoint to be `trento-server/mcp`, as the endpoint is already defined in the Trento application, and it is not necessary to have a separate endpoint for the MCP server. The current proposal is to keep the endpoint as it is, but it would be nice to have a simpler endpoint or even double it and deprecate the old one. No newline at end of file

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also noticed the same inconsistency and left a similar related comment elsewhere.

TLDR: I don't see, yet, a need to have a different endpoint (as in the Phoenix.Endpoint meaning) for the embedded mcp server. It could very well be a route in the current endpoint.

Unless I am missing something.

@chargio chargio self-assigned this Aug 6, 2026
@chargio

chargio commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

I had a strange behaviour where 3 files that were not touched by my PR were failing because of differences...
I've rebased and got again a weird behaviour.

@chargio
chargio force-pushed the updating_MCP_to_reuse_internal_tools branch from 6f26106 to 7c7c77d Compare August 12, 2026 08:24

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

6 participants