Skip to content

Add stateless http transport #59

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

Conversation

Chrisbattarbee
Copy link
Contributor

@Chrisbattarbee Chrisbattarbee commented Jan 22, 2025

Add Context Support and Gin Transport

This PR adds support for passing context through the MCP transport layer and introduces a new Gin transport implementation. The changes enable better integration with web frameworks and middleware.

These new transports are stateless. Meaning that they dont support any functionality around sending notifications etc but can very easily be added to existing http servers.

Key Changes

  1. Added context support throughout the transport layer:

    • Modified Transport interface to include context in Send and SetMessageHandler
    • Updated all transport implementations (HTTP, Gin, stdio) to handle context
    • Added context support to tool handlers
  2. Added Gin transport implementation:

    • New GinTransport type that works with Gin's router
    • Support for accessing Gin context in tool handlers via context.Value("ginContext")
    • Example implementation showing middleware integration
  3. Refactored HTTP transports:

    • Created baseTransport to share common functionality between HTTP and Gin transports
    • Reduced code duplication in message handling and response management
    • Improved error handling consistency
  4. Fixed client initialization:

    • Updated Initialize method to use empty map instead of nil for params

Example Usage

// Create a Gin transport
transport := http.NewGinTransport()

// Register a tool that uses Gin context
server.RegisterTool("mytool", "Description", func(ctx context.Context, args Args) (*ToolResponse, error) {
    if ginCtx, ok := ctx.Value("ginContext").(*gin.Context); ok {
        // Access Gin features (headers, middleware values, etc.)
        userAgent := ginCtx.GetHeader("User-Agent")
    }
    return mcp_golang.NewToolResponse(mcp_golang.NewTextContent("Done")), nil
})

server.Serve()

// Add middleware
r.Use(func(c *gin.Context) {
    c.Set("customValue", "example")
    c.Next()
})

// Add MCP endpoint to Gin router
r.POST("/mcp", transport.Handler())

Breaking Changes

  1. Tool handler signature now supports context:

    • Old: func(args Args) (*ToolResponse, error)
    • New: func(ctx context.Context, args Args) (*ToolResponse, error)
    • Note: The old signature is still supported for backward compatibility
  2. Transport interface changes:

    • Send now takes a context parameter
    • SetMessageHandler callback now includes context

Testing

  • Added tests for context handling in tool handlers
  • Updated existing transport tests to use context
  • Added example implementation demonstrating Gin integration

@Chrisbattarbee Chrisbattarbee merged commit 219a972 into metoro-io:main Jan 22, 2025
1 check passed
@Chrisbattarbee Chrisbattarbee deleted the cbattarbee/stateless-http-transport branch January 22, 2025 13:15
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.

1 participant