Fix MCP server URL-based transport support#1830
Conversation
| // 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
Show autofix suggestion
Hide autofix suggestion
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.
| @@ -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 |
| 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
Show autofix suggestion
Hide autofix suggestion
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.
| @@ -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}"`; |
| ... | ||
| */ | ||
| 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
Show autofix suggestion
Hide autofix suggestion
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.
| @@ -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) |
Fixes #1829 where MCP servers configured with
urlparameter instead ofcommandwere throwing "Missing required parameter: command" error.Problem
Previously, GenAIScript only supported stdio-based MCP servers that required
commandandargsparameters:Attempting to configure URL-based transports resulted in validation errors:
Solution
This PR adds comprehensive support for URL-based MCP transports while maintaining full backward compatibility:
1. Enhanced Interface Definition
commandandargsoptional inMcpServerConfigurl?: stringfor HTTP/WebSocket/SSE transportstype?: "stdio" | "http" | "sse"for explicit transport specification2. Multiple Transport Support
StreamableHTTPClientTransportfor HTTP-based MCP serversSSEClientTransportfor Server-Sent EventsStdioClientTransportfunctionality3. Intelligent Configuration Validation
typeis not specified:urlprovided → defaults to HTTP transportcommandprovided → defaults to stdio transportcommandandurl)4. Updated System Scripts
Both
system.mcpandsystem.agent_mcpnow support the new parameters with proper validation.Usage Examples
Stdio Transport (existing - unchanged):
HTTP Transport (new):
SSE Transport (new):
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.comnode /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.