-
Notifications
You must be signed in to change notification settings - Fork 256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
flowing env vars to the client app for inspector #258
base: main
Are you sure you want to change the base?
flowing env vars to the client app for inspector #258
Conversation
This allows you to set the SERVER_PORT or MCP_PROXY_FULL_ADDRESS as an environment variable and the value will be injected into the static app when it's run. Fixes modelcontextprotocol#256
import http from "http"; | ||
import { dirname, join } from "path"; | ||
import handler from "serve-handler"; | ||
import { fileURLToPath } from "url"; | ||
|
||
const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
const distPath = join(__dirname, "../dist"); | ||
|
||
const server = http.createServer((request, response) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would a better approach be to expose an endpoint in this server to return the config ? That would simplify this part of the code (and not have to deal with runtime injection).
Something like that is being done here (although it contacts the proxy server):
Line 228 in ce1a9d3
fetch(`${getMCPProxyAddress(config)}/config`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The runtime config stuff further down in the client code definitely would be simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in, create an API in the client/bin/cli.js
that provides an endpoint in which you load the config file? It would but doesn't that add overhead to the startup of the app in that you have to make an API call to get the config, then make an API call to get the config from the server.
Maybe they could be combined, make the /config
exist on the client app, which then proxies the SERVER/config
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aaronpowell Could we get a mermaid sequence diagram showing how this is intended to work? That would give us a better starting point for understanding how best to plumb this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sequenceDiagram
participant SPA
participant ClientHost
participant ProxyServer
Note over SPA: Application starts
SPA->>ClientHost: GET /config
activate ClientHost
ClientHost->>ProxyServer: GET /config
activate ProxyServer
ProxyServer-->>ClientHost: Return configuration data
deactivate ProxyServer
ClientHost-->>SPA: Return configuration data
deactivate ClientHost
Note over SPA: Process configuration
With this we can simplify the "Client Host" (the server run from client/bin/cli.js
to not have to worry about much heavy lifting other than "where is the server endpoint" and pass through the request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reimplementing as an endpoint that the app calls rather than the runtime injection scheme into the window seems simpler.
client/src/App.tsx
Outdated
: DEFAULT_INSPECTOR_CONFIG; | ||
|
||
// Override with runtime injected values if available | ||
if (runtimeConfig.MCP_PROXY_FULL_ADDRESS) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be more like:
if (runtimeConfig.MCP_PROXY_FULL_ADDRESS) {
configFromStorage = {
...configFromStorage,
MCP_PROXY_FULL_ADDRESS: {
value: runtimeConfig.MCP_PROXY_FULL_ADDRESS,
},
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are there properties other than value
on MCP_PROXY_FULL_ADDRESS
that are important?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a ConfigItem.
import http from "http"; | ||
import { dirname, join } from "path"; | ||
import handler from "serve-handler"; | ||
import { fileURLToPath } from "url"; | ||
|
||
const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
const distPath = join(__dirname, "../dist"); | ||
|
||
const server = http.createServer((request, response) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The runtime config stuff further down in the client code definitely would be simpler.
import http from "http"; | ||
import { dirname, join } from "path"; | ||
import handler from "serve-handler"; | ||
import { fileURLToPath } from "url"; | ||
|
||
const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
const distPath = join(__dirname, "../dist"); | ||
|
||
const server = http.createServer((request, response) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in, create an API in the client/bin/cli.js
that provides an endpoint in which you load the config file? It would but doesn't that add overhead to the startup of the app in that you have to make an API call to get the config, then make an API call to get the config from the server.
Maybe they could be combined, make the /config
exist on the client app, which then proxies the SERVER/config
.
client/src/App.tsx
Outdated
: DEFAULT_INSPECTOR_CONFIG; | ||
|
||
// Override with runtime injected values if available | ||
if (runtimeConfig.MCP_PROXY_FULL_ADDRESS) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are there properties other than value
on MCP_PROXY_FULL_ADDRESS
that are important?
client/bin/cli.js
Outdated
|
||
// Create a runtime config object with environment variables | ||
const runtimeConfig = { | ||
MCP_PROXY_FULL_ADDRESS: process.env.MCP_PROXY_FULL_ADDRESS || "", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MCP_PROXY_FULL_ADDRESS
and MCP_PROXY_PORT
should be ConfigItems.
This means that when you set environment variables we read them on the server and add them to the config info obtained by the proxy, resulting in the proxy server being the 'winner' in terms of what the config should look like.
e041581
to
d76a79a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please include detailed steps for testing in the PR header.
This allows you to set the SERVER_PORT or MCP_PROXY_FULL_ADDRESS as an environment variable and the value will be injected into the static app when it's run. Also making the transport type provided by the config.
Fixes #256 and #255
Motivation and Context
How Has This Been Tested?
Breaking Changes
Types of changes
Checklist
Additional context