Skip to content

feat: add support for stdio MCP servers#19

Merged
hrntknr merged 1 commit intomainfrom
feat/support-stdio-mcp
Aug 18, 2025
Merged

feat: add support for stdio MCP servers#19
hrntknr merged 1 commit intomainfrom
feat/support-stdio-mcp

Conversation

@hrntknr
Copy link
Copy Markdown
Member

@hrntknr hrntknr commented Aug 18, 2025

Summary

  • Replace PROXY_URL with command-line arguments for MCP target specification
  • Add backend package to handle both HTTP proxying and stdio MCP server execution
  • Integrate mcp-go library for MCP protocol support over stdio
  • Update Dockerfile to include Node.js, npm, Python, and uv for MCP server execution
  • Add graceful shutdown handling for all server components
  • Update documentation with new usage examples for stdio MCP servers

Type of Change

  • feat: A new feature
  • fix: A bug fix
  • docs: Documentation only changes
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
  • refactor: A code change that neither fixes a bug nor adds a feature
  • perf: A code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • build: Changes that affect the build system or external dependencies
  • ci: Changes to our CI configuration files and scripts
  • chore: Other changes that don't modify src or test files
  • revert: Reverts a previous commit

Related Issues

- Replace PROXY_URL with command-line arguments for MCP target specification
- Add backend package to handle both HTTP proxying and stdio MCP server execution
- Integrate mcp-go library for MCP protocol support over stdio
- Update Dockerfile to include Node.js, npm, Python, and uv for MCP server execution
- Add graceful shutdown handling for all server components
- Update documentation with new usage examples for stdio MCP servers
Copilot AI review requested due to automatic review settings August 18, 2025 10:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for stdio MCP (Model Context Protocol) servers alongside the existing HTTP proxy functionality. The change enables the proxy to launch and communicate with MCP servers via stdin/stdout instead of only proxying to existing HTTP endpoints.

Key changes include:

  • Replaced PROXY_URL environment variable/flag with command-line arguments for flexible target specification
  • Added new backend package to handle both HTTP proxying and stdio MCP server execution
  • Integrated graceful shutdown handling for all server components

Reviewed Changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pkg/proxy/main.go Updated ProxyRouter to accept generic http.Handler instead of URL string
pkg/mcp-proxy/main.go Added backend support, graceful shutdown, and command-line argument handling
pkg/backend/main.go New package implementing stdio MCP server execution and HTTP proxy bridge
main.go Removed PROXY_URL flag in favor of command-line arguments
go.mod Added mcp-go dependency and updated related packages
README.md Updated documentation with new usage examples for both HTTP and stdio targets
Dockerfile Added Node.js, npm, Python, and uv for MCP server execution

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread pkg/backend/main.go
handler = _handler
done <- struct{}{}
}()
select {
Copy link

Copilot AI Aug 18, 2025

Choose a reason for hiding this comment

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

The select statement doesn't handle a timeout case. If the setupProxy goroutine hangs indefinitely, this could block forever. Consider adding a timeout using MCPClientInitTimeout or context.WithTimeout.

Copilot uses AI. Check for mistakes.
Comment thread pkg/mcp-proxy/main.go
go func() {
defer wg.Done()
if be != nil {
if err := be.Wait(); err != nil && ctx.Err() != context.Canceled {
Copy link

Copilot AI Aug 18, 2025

Choose a reason for hiding this comment

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

The condition ctx.Err() != context.Canceled should check against context.Canceled directly or use errors.Is(ctx.Err(), context.Canceled) for proper error comparison.

Suggested change
if err := be.Wait(); err != nil && ctx.Err() != context.Canceled {
if err := be.Wait(); err != nil && !errors.Is(ctx.Err(), context.Canceled) {

Copilot uses AI. Check for mistakes.
Comment thread pkg/mcp-proxy/main.go
exit <- struct{}{}
}
}()

Copy link

Copilot AI Aug 18, 2025

Choose a reason for hiding this comment

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

This goroutine only executes when be != nil, but it's always added to the WaitGroup count of 3. This could cause the WaitGroup to wait indefinitely if be is nil. Consider conditionally adding to WaitGroup or restructuring the logic.

Suggested change
if be != nil {
wg.Add(1)
go func() {
defer wg.Done()
if err := be.Wait(); err != nil && ctx.Err() != context.Canceled {
lock.Lock()
errs = append(errs, err)
lock.Unlock()
}
exit <- struct{}{}
}()
}

Copilot uses AI. Check for mistakes.
@hrntknr hrntknr merged commit b159d26 into main Aug 18, 2025
4 checks passed
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.

2 participants