Add UI for viewing and configuring environment variables

This commit is contained in:
Justin Spahr-Summers
2024-11-07 15:26:39 +00:00
parent 193032533b
commit 76e2cf6fdc
2 changed files with 68 additions and 3 deletions

View File

@@ -93,6 +93,7 @@ const App = () => {
const [mcpClient, setMcpClient] = useState<Client | null>(null);
const [notifications, setNotifications] = useState<ServerNotification[]>([]);
const [roots, setRoots] = useState<Root[]>([]);
const [env, setEnv] = useState<Record<string, string>>({});
const [pendingSampleRequests, setPendingSampleRequests] = useState<
Array<
@@ -145,6 +146,15 @@ const App = () => {
localStorage.setItem("lastArgs", args);
}, [args]);
useEffect(() => {
fetch("http://localhost:3000/default-environment")
.then((response) => response.json())
.then((data) => setEnv(data))
.catch((error) =>
console.error("Error fetching default environment:", error),
);
}, []);
const pushHistory = (request: object, response: object) => {
setRequestHistory((prev) => [
...prev,
@@ -284,6 +294,7 @@ const App = () => {
if (transportType === "stdio") {
backendUrl.searchParams.append("command", command);
backendUrl.searchParams.append("args", args);
backendUrl.searchParams.append("env", JSON.stringify(env));
} else {
backendUrl.searchParams.append("url", url);
}
@@ -371,6 +382,50 @@ const App = () => {
Connect
</Button>
</div>
{transportType === "stdio" && (
<div className="mt-4">
<h3 className="text-md font-semibold mb-2">
Environment Variables
</h3>
{Object.entries(env).map(([key, value]) => (
<div key={key} className="flex space-x-2 mb-2">
<Input
placeholder="Key"
value={key}
onChange={(e) =>
setEnv((prev) => ({
...prev,
[e.target.value]: value,
}))
}
/>
<Input
placeholder="Value"
value={value}
onChange={(e) =>
setEnv((prev) => ({ ...prev, [key]: e.target.value }))
}
/>
<Button
onClick={() =>
setEnv((prev) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { [key]: _, ...rest } = prev;
return rest;
})
}
>
Remove
</Button>
</div>
))}
<Button
onClick={() => setEnv((prev) => ({ ...prev, "": "" }))}
>
Add Environment Variable
</Button>
</div>
)}
</div>
{mcpClient ? (
<Tabs defaultValue="resources" className="w-full p-4">

View File

@@ -2,7 +2,10 @@ import cors from "cors";
import EventSource from "eventsource";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import {
StdioClientTransport,
getDefaultEnvironment,
} from "@modelcontextprotocol/sdk/client/stdio.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import express from "express";
import mcpProxy from "./mcpProxy.js";
@@ -24,8 +27,11 @@ const createTransport = async (query: express.Request["query"]) => {
if (transportType === "stdio") {
const command = query.command as string;
const args = (query.args as string).split(/\s+/);
console.log(`Stdio transport: command=${command}, args=${args}`);
const transport = new StdioClientTransport({ command, args });
const env = query.env ? JSON.parse(query.env as string) : undefined;
console.log(
`Stdio transport: command=${command}, args=${args}, env=${JSON.stringify(env)}`,
);
const transport = new StdioClientTransport({ command, args, env });
await transport.start();
console.log("Spawned stdio transport");
return transport;
@@ -79,6 +85,10 @@ app.post("/message", async (req, res) => {
await transport.handlePostMessage(req, res);
});
app.get("/default-environment", (req, res) => {
res.json(getDefaultEnvironment());
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);