Skip to content
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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

aaronpowell
Copy link

@aaronpowell aaronpowell commented Apr 3, 2025

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

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

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) => {
Copy link
Contributor

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):

fetch(`${getMCPProxyAddress(config)}/config`)

Copy link
Contributor

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.

Copy link
Author

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.

Copy link
Contributor

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.

Copy link
Author

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
Loading

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't the proxy server address part of the config?
Screenshot 2025-04-08 at 1 19 31 PM

Copy link
Contributor

@cliffhall cliffhall left a 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.

: DEFAULT_INSPECTOR_CONFIG;

// Override with runtime injected values if available
if (runtimeConfig.MCP_PROXY_FULL_ADDRESS) {
Copy link
Contributor

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,
        },
      };

Copy link
Author

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?

Copy link
Contributor

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) => {
Copy link
Contributor

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.

@cliffhall cliffhall added enhancement New feature or request waiting on submitter Waiting for the submitter to provide more info labels Apr 3, 2025
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) => {
Copy link
Author

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.

: DEFAULT_INSPECTOR_CONFIG;

// Override with runtime injected values if available
if (runtimeConfig.MCP_PROXY_FULL_ADDRESS) {
Copy link
Author

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?


// Create a runtime config object with environment variables
const runtimeConfig = {
MCP_PROXY_FULL_ADDRESS: process.env.MCP_PROXY_FULL_ADDRESS || "",
Copy link
Contributor

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.
@aaronpowell aaronpowell force-pushed the aaronpowell/issue-256 branch from e041581 to d76a79a Compare April 8, 2025 01:20
@aaronpowell aaronpowell requested a review from cliffhall April 8, 2025 01:21
Copy link
Contributor

@cliffhall cliffhall left a 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request waiting on submitter Waiting for the submitter to provide more info
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Setting SERVER_PORT doesn't cascade through to launching the client endpoint
3 participants