Skip to content

Fix MCP server URL-based transport support#1830

Closed
Copilot wants to merge 2 commits into
mainfrom
copilot/vscode1754377581423
Closed

Fix MCP server URL-based transport support#1830
Copilot wants to merge 2 commits into
mainfrom
copilot/vscode1754377581423

Conversation

Copy link
Copy Markdown

Copilot AI commented Aug 5, 2025

Fixes #1829 where MCP servers configured with url parameter instead of command were throwing "Missing required parameter: command" error.

Problem

Previously, GenAIScript only supported stdio-based MCP servers that required command and args parameters:

mcpServers: {
  memory: {
    command: "npx",
    args: ["-y", "@modelcontextprotocol/server-memory"]
  }
}

Attempting to configure URL-based transports resulted in validation errors:

// This would fail with "Missing required parameter: command"
mcpServers: {
  remote: {
    url: "http://localhost:8080/mcp"
  }
}

Solution

This PR adds comprehensive support for URL-based MCP transports while maintaining full backward compatibility:

1. Enhanced Interface Definition

  • Made command and args optional in McpServerConfig
  • Added url?: string for HTTP/WebSocket/SSE transports
  • Added type?: "stdio" | "http" | "sse" for explicit transport specification

2. Multiple Transport Support

  • HTTP Transport: Uses StreamableHTTPClientTransport for HTTP-based MCP servers
  • SSE Transport: Uses SSEClientTransport for Server-Sent Events
  • Stdio Transport: Maintains existing StdioClientTransport functionality

3. Intelligent Configuration Validation

  • Auto-detects transport type when type is not specified:
    • url provided → defaults to HTTP transport
    • command provided → defaults to stdio transport
  • Validates that appropriate parameters are provided for each transport type
  • Prevents invalid configurations (e.g., both command and url)

4. Updated System Scripts

Both system.mcp and system.agent_mcp now support the new parameters with proper validation.

Usage Examples

Stdio Transport (existing - unchanged):

mcpServers: {
  memory: {
    command: "npx",
    args: ["-y", "@modelcontextprotocol/server-memory"]
  }
}

HTTP Transport (new):

mcpServers: {
  remote: {
    url: "http://localhost:8080/mcp",
    type: "http" // optional, inferred from url
  }
}

SSE Transport (new):

mcpServers: {
  events: {
    url: "http://localhost:8080/sse",
    type: "sse"
  }
}

Backward Compatibility

All existing configurations continue to work without any changes. The implementation includes comprehensive validation that provides clear error messages for invalid configurations while automatically detecting the appropriate transport type for valid ones.

This enables GenAIScript to work seamlessly with remote MCP servers over HTTP and SSE protocols, expanding the ecosystem of compatible MCP servers beyond just local stdio-based implementations.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cdn.sheetjs.com
    • Triggering command: node /usr/local/bin/yarn install (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

// Regular expression for matching GitHub Flavored Markdown style warnings.
// Example: > [!WARNING]
// > This is a warning message.
const GITHUB_MARKDOWN_WARNINGS_RX = /^\s*>\s*\[!(?<severity>NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*\n>\s*(?<message>.+)(?:\s*\n>\s*.*?)*?$/gim;

Check failure

Code scanning / CodeQL

Inefficient regular expression High

This part of the regular expression may cause exponential backtracking on strings starting with '>[!tip]\n>a\n>' and containing many repetitions of ' \n>'.

Copilot Autofix

AI 10 months ago

To fix the inefficient regular expression, we need to remove the ambiguity caused by .*? inside a repeated group. The problematic part is (?:\s*\n>\s*.*?)*?, which matches additional lines in a Markdown warning block. Instead of using .*?, we can match everything except a newline, e.g., ([^\n]*), which is unambiguous and matches the content of each line. The revised pattern for the repeated group should be (?:\s*\n>\s*[^\n]*)*, which matches zero or more lines starting with >, followed by any content except a newline. This change preserves the original functionality while eliminating the risk of exponential backtracking.

Only line 24 in packages/core/dist/browser/annotations.js needs to be changed.


Suggested changeset 1
packages/core/dist/browser/annotations.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/core/dist/browser/annotations.js b/packages/core/dist/browser/annotations.js
--- a/packages/core/dist/browser/annotations.js
+++ b/packages/core/dist/browser/annotations.js
@@ -23,3 +23,3 @@
 // > This is a warning message.
-const GITHUB_MARKDOWN_WARNINGS_RX = /^\s*>\s*\[!(?<severity>NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*\n>\s*(?<message>.+)(?:\s*\n>\s*.*?)*?$/gim;
+const GITHUB_MARKDOWN_WARNINGS_RX = /^\s*>\s*\[!(?<severity>NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*\n>\s*(?<message>[^\n]+)(?:\s*\n>\s*[^\n]*)*$/gim;
 // Regular expression for TypeScript compiler errors with parentheses format
EOF
@@ -23,3 +23,3 @@
// > This is a warning message.
const GITHUB_MARKDOWN_WARNINGS_RX = /^\s*>\s*\[!(?<severity>NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*\n>\s*(?<message>.+)(?:\s*\n>\s*.*?)*?$/gim;
const GITHUB_MARKDOWN_WARNINGS_RX = /^\s*>\s*\[!(?<severity>NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*\n>\s*(?<message>[^\n]+)(?:\s*\n>\s*[^\n]*)*$/gim;
// Regular expression for TypeScript compiler errors with parentheses format
Copilot is powered by AI and may make mistakes. Always verify output.
value = "";
// Enclose in quotes if the value contains newlines or quotes, and escape quotes
if (value.includes("\n") || value.includes('"')) {
value = value.replace(/"/g, '\\"'); // Escape existing quotes

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding High

This does not escape backslash characters in the input.

Copilot Autofix

AI 10 months ago

To fix the problem, we need to ensure that both backslashes and double quotes are properly escaped in the value before wrapping it in double quotes. The correct order is to first replace all backslashes (\) with double backslashes (\\), and then replace all double quotes (") with escaped quotes (\"). This ensures that any existing backslashes are not interpreted as escape characters for the quotes. The change should be made in the dotEnvStringify function, specifically on line 46. No new imports are needed, as this can be accomplished with standard JavaScript string methods.


Suggested changeset 1
packages/core/dist/browser/dotenv.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/core/dist/browser/dotenv.js b/packages/core/dist/browser/dotenv.js
--- a/packages/core/dist/browser/dotenv.js
+++ b/packages/core/dist/browser/dotenv.js
@@ -45,3 +45,3 @@
         if (value.includes("\n") || value.includes('"')) {
-            value = value.replace(/"/g, '\\"'); // Escape existing quotes
+            value = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); // Escape backslashes, then quotes
             return `${key}="${value}"`;
EOF
@@ -45,3 +45,3 @@
if (value.includes("\n") || value.includes('"')) {
value = value.replace(/"/g, '\\"'); // Escape existing quotes
value = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); // Escape backslashes, then quotes
return `${key}="${value}"`;
Copilot is powered by AI and may make mistakes. Always verify output.
...
*/
if (/file=\w+\.\w+/.test(label)) {
const m = /^\s*\`{3,}\w*\r?\n((.|\s)*)\r?\n\`{3,}\s*$/.exec(text);

Check failure

Code scanning / CodeQL

Inefficient regular expression High

This part of the regular expression may cause exponential backtracking on strings containing many repetitions of ' '.

Copilot Autofix

AI 10 months ago

To fix the inefficient regular expression, we should remove the ambiguity in the alternation. The goal of the regex is to match the content inside a code fence, including all characters (including newlines). Instead of (.|\s)*, which matches any character or whitespace, we can use [\s\S]*, which matches any character, including whitespace and non-whitespace, without ambiguity. This is a common idiom in JavaScript regex to match "any character including newlines".
Change:

  • In packages/core/dist/browser/fence.js, line 155, replace ((.|\s)*) with ([\s\S]*) in the regular expression.

No new imports or definitions are needed.


Suggested changeset 1
packages/core/dist/browser/fence.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/core/dist/browser/fence.js b/packages/core/dist/browser/fence.js
--- a/packages/core/dist/browser/fence.js
+++ b/packages/core/dist/browser/fence.js
@@ -154,3 +154,3 @@
         if (/file=\w+\.\w+/.test(label)) {
-            const m = /^\s*\`{3,}\w*\r?\n((.|\s)*)\r?\n\`{3,}\s*$/.exec(text);
+            const m = /^\s*\`{3,}\w*\r?\n([\s\S]*)\r?\n\`{3,}\s*$/.exec(text);
             if (m)
EOF
@@ -154,3 +154,3 @@
if (/file=\w+\.\w+/.test(label)) {
const m = /^\s*\`{3,}\w*\r?\n((.|\s)*)\r?\n\`{3,}\s*$/.exec(text);
const m = /^\s*\`{3,}\w*\r?\n([\s\S]*)\r?\n\`{3,}\s*$/.exec(text);
if (m)
Copilot is powered by AI and may make mistakes. Always verify output.
@sinedied sinedied closed this Aug 5, 2025
Copilot AI changed the title [WIP] Fix MCP server URL-based transport support Fix MCP server URL-based transport support Aug 5, 2025
Copilot AI requested a review from sinedied August 5, 2025 07:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP client support issues

3 participants