server

package module
v0.1.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2026 License: GPL-3.0 Imports: 18 Imported by: 0

README

MCP Wrapper for Echo Framework

Build Status Codecov branch Go Report Card Release

Wrap any existing Echo API into MCP tools, enabling AI agents to interact with your API through Model Context Protocol.

Inspired by gin-mcp but for the Echo framework.

Key Features

  • Zero Configuration: Works with any existing Echo API
  • Multiple Schema Sources: Support for Swaggo, raw OpenAPI YAML/JSON, and manual schemas
  • Filtering: Include/exclude endpoints with wildcard patterns
  • MCP Compatible: Works with any agent that supports MCP.

Installation

go get github.com/BrunoKrugel/echo-mcp

Quick Start

package main

import (
    "net/http"
    server "github.com/BrunoKrugel/echo-mcp"
    "github.com/labstack/echo/v4"
)

func main() {
    e := echo.New()

    // Existing API routes
    e.GET("/ping", func(c echo.Context) error {
        return c.JSON(http.StatusOK, map[string]string{"message": "pong"})
    })


    // Add MCP support
    mcp := server.New(e)
    mcp.Mount("/mcp")

    e.Start(":8080")
}

Now the API is accessible at http://localhost:8080/mcp

Advanced Usage

Automatic Swagger Schemas

If you already use Swaggo for Swagger documentation, enable automatic schema generation:

// @Summary Get user by ID
// @Description Retrieve detailed user information
// @Tags users
// @Param id path int true "User ID" minimum(1)
// @Success 200 {object} User
// @Router /users/{id} [get]
func GetUser(c echo.Context) error {
    // Your handler code
}

func main() {
    e := echo.New()
    e.GET("/users/:id", GetUser)

    // Enable automatic swagger schema generation
    mcp := server.NewWithConfig(e, &server.Config{
        BaseURL:              "http://localhost:8080",
        EnableSwaggerSchemas: true,
    })
    mcp.Mount("/mcp")

    e.Start(":8080")
}
Raw OpenAPI Schema Support

If you use other OpenAPI libraries like swaggest/openapi-go, you can pass a raw YAML or JSON schema string:

import (
    "github.com/swaggest/openapi-go/openapi3"
    server "github.com/BrunoKrugel/echo-mcp"
)

func main() {
    e := echo.New()

    // ... define your routes ...

    // Generate OpenAPI schema
    reflector := openapi3.Reflector{}
    reflector.SpecEns().WithOpenapi("3.0.3")
    reflector.SpecEns().Info.WithTitle("My API").WithVersion("1.0.0")

    // Add operations to reflector
    // ...

    // Export to YAML (or JSON)
    schema, _ := reflector.Spec.MarshalYAML()

    // Pass raw schema to MCP server
    // ... you can also embed the schema from an exiting openapi.yaml file
    mcp := server.NewWithConfig(e, &server.Config{
        OpenAPISchema: string(schema),
    })
    mcp.Mount("/mcp")

    e.Start(":8080")
}

The OpenAPISchema field accepts both YAML and JSON formatted strings. When provided, it automatically populates:

  • Server name from schema title
  • Description from schema description
  • Version from schema version
  • Tool schemas from operation definitions
Endpoint Filtering

Expose only the necessary endpoints to MCP tools:

mcp := server.New(e)

// Include only specific endpoints
mcp.RegisterEndpoints([]string{
    "/api/v1/users/:id",
    "/api/v1/orders",
})

// Or exclude internal endpoints
mcp.ExcludeEndpoints([]string{
    "/health",      // Exclude health checks
})
Manual Schema Registration (WIP)

For better control, register schemas manually:

type CreateUserRequest struct {
    Name  string `json:"name" jsonschema:"required,description=User full name"`
    Email string `json:"email" jsonschema:"required,description=User email address"`
    Age   int    `json:"age,omitempty" jsonschema:"minimum=0,maximum=150"`
}

type UserQuery struct {
    Page   int    `form:"page,default=1" jsonschema:"minimum=1"`
    Limit  int    `form:"limit,default=10" jsonschema:"maximum=100"`
    Active bool   `form:"active" jsonschema:"description=Filter by active status"`
}

mcp := server.New(e, &server.Config{BaseURL: "http://localhost:8080"})

// Register schemas for specific routes
mcp.RegisterSchema("POST", "/users", nil, CreateUserRequest{})
mcp.RegisterSchema("GET", "/users", UserQuery{}, nil)

Schema Generation Methods

Echo-MCP supports four schema generation approaches, with automatic fallback:

Method Use Case Priority
Raw OpenAPI Schema Using OpenAPI libraries like swaggest/openapi-go First (if OpenAPISchema is set)
Swagger Production APIs with Swaggo annotations First (if EnableSwaggerSchemas is set)
Manual Fine-grained control, complex validation Second
Automatic Quick prototyping, simple endpoints Fallback
// Option 1: Using raw OpenAPI schema (swaggest/openapi-go, etc.)
schema, _ := reflector.Spec.MarshalYAML()
mcp := server.New(e, &server.Config{
    OpenAPISchema: string(schema), // Use raw schema
})

// Option 2: Using Swaggo
mcp := server.New(e, &server.Config{
    EnableSwaggerSchemas: true, // Load from swaggo docs
})

// Option 3: Manual schemas for fine-grained control
mcp.RegisterSchema("POST", "/users", nil, CreateUserRequest{})

// Option 4: Automatic inference (fallback)
// No configuration needed - routes will use basic path/body inference

MCP Client Integration

Once your server is running:

Manual configuration
{
  "mcpServers": {
    "echo-api": {
      "type": "http",
      "url": "http://localhost:8080/mcp",
      "timeout": 120
    },
  }
}

Local Testing

For local testing, use MCP Inspector:

npx @modelcontextprotocol/inspector http://localhost:8080/mcp

Acknowledgments

Documentation

Overview

Package echo-mcp provides zero-configuration conversion of Echo web APIs to Model Context Protocol (MCP) tools.

This package automatically exposes your Echo routes as MCP tools that can be called by AI assistants and other MCP clients. It supports multiple schema generation methods including Swagger/OpenAPI documentation, manual schema registration, and automatic type inference.

Quick Start

package main

import (
	"net/http"
	server "github.com/BrunoKrugel/echo-mcp"
	"github.com/labstack/echo/v4"
)

func main() {
	e := echo.New()
	e.GET("/users/:id", getUserHandler)
	e.POST("/users", createUserHandler)

	// Create MCP server with auto-configuration
	mcp := server.New(e)

	// Mount MCP endpoint
	if err := mcp.Mount("/mcp"); err != nil {
		e.Logger.Fatal(err)
	}

	e.Start(":8080")
}

func getUserHandler(c echo.Context) error {
	userID := c.Param("id")
	return c.JSON(http.StatusOK, map[string]string{
		"id":   userID,
		"name": "John Doe",
	})
}

func createUserHandler(c echo.Context) error {
	var user map[string]any
	if err := c.Bind(&user); err != nil {
		return err
	}
	user["id"] = "123"
	return c.JSON(http.StatusCreated, user)
}

Advanced Configuration

Configure the MCP server with custom options:

config := &server.Config{
	BaseURL:              "http://localhost:8080",
	EnableSwaggerSchemas: true,
	Name:                 "My API",
	Version:             "1.0.0",
	Description:         "API converted to MCP tools",
}
mcp := server.NewWithConfig(e, config)

Endpoint Filtering

Control which endpoints become MCP tools:

// Include only specific endpoints
mcp.RegisterEndpoints([]string{
	"/api/v1/users/:id",
	"/api/v1/orders/*",
})

// Or exclude internal endpoints
mcp.ExcludeEndpoints([]string{
	"/health",
	"/metrics",
	"/debug/*",
})

Schema Registration

For type-safe schemas, register Go structs:

type UserQuery struct {
	Page  int `form:"page" jsonschema:"minimum=1"`
	Limit int `form:"limit" jsonschema:"maximum=100"`
}

type CreateUserRequest struct {
	Name  string `json:"name" jsonschema:"required"`
	Email string `json:"email" jsonschema:"required"`
}

mcp.RegisterSchema("GET", "/users", UserQuery{}, nil)
mcp.RegisterSchema("POST", "/users", nil, CreateUserRequest{})

Swagger Integration

When using Swagger/OpenAPI annotations, schemas are automatically generated:

// @title My API
// @version 1.0
// @description API with MCP support
// @host localhost:8080

// @Summary Get user by ID
// @Param id path string true "User ID"
// @Success 200 {object} User
// @Router /users/{id} [get]
func getUserHandler(c echo.Context) error {
	// handler implementation
}

Enable Swagger schema generation:

mcp := server.New(e, &server.Config{
	EnableSwaggerSchemas: true,
})

Schema Generation Priority

Echo-MCP uses a three-tier schema generation system:

1. Swagger/OpenAPI (highest priority) - Type-safe schemas from annotations 2. Manual Registration - Explicit schema registration with RegisterSchema 3. Automatic Inference (fallback) - Basic schemas inferred from routes

This ensures maximum compatibility while allowing precise control when needed.

Package server provides zero-configuration conversion of Echo web APIs to Model Context Protocol (MCP) tools.

This package automatically exposes your Echo routes as MCP tools that can be called by AI assistants and other MCP clients. It supports multiple schema generation methods including Swagger/OpenAPI documentation, manual schema registration, and automatic type inference.

Basic usage:

e := echo.New()
e.GET("/users/:id", getUserHandler)
e.POST("/users", createUserHandler)

// Convert to MCP server
mcp := server.New(e, &server.Config{
	BaseURL: "http://localhost:8080",
})

// Mount MCP endpoint
mcp.Mount("/mcp")

For advanced usage with Swagger schemas:

mcp := server.New(e, &server.Config{
	BaseURL:              "http://localhost:8080",
	EnableSwaggerSchemas: true,
})

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Capabilities

type Capabilities struct {
	Tools map[string]any `json:"tools"`
}

type Config

type Config struct {
	Name                       string
	Version                    string
	Description                string
	BaseURL                    string
	OpenAPISchema              string
	IncludeOperations          []string
	ExcludeOperations          []string
	IncludeTags                []string
	ExcludeTags                []string
	EnableSwaggerSchemas       bool
	DescribeAllResponses       bool
	DescribeFullResponseSchema bool
}

Config holds configuration options for the EchoMCP server.

type Content

type Content struct {
	Type string `json:"type"`
	Text string `json:"text"`
}

type EchoMCP

type EchoMCP struct {
	// contains filtered or unexported fields
}

EchoMCP represents an MCP server that exposes Echo routes as MCP tools. It handles the conversion of HTTP endpoints to MCP tool definitions and manages the execution of tool calls by forwarding them to the original Echo handlers.

func New

func New(e *echo.Echo) *EchoMCP

New creates a new EchoMCP instance with default configuration. EnableSwaggerSchemas is enabled by default. Name, Description, and Version are automatically populated from Swagger annotations if available.

This is equivalent to calling NewWithConfig with EnableSwaggerSchemas: true.

Example:

e := echo.New()
e.GET("/users/:id", getUserHandler)
mcp := server.New(e)
mcp.Mount("/mcp")

func NewWithConfig

func NewWithConfig(e *echo.Echo, config *Config) *EchoMCP

NewWithConfig creates a new EchoMCP instance with the provided configuration. The config parameter can be nil, in which case default values are used.

If EnableSwaggerSchemas is true and Name, Description, or Version are empty, they will be automatically populated from Swagger annotations if available.

Example:

config := &server.Config{
	BaseURL:              "http://localhost:8080",
	EnableSwaggerSchemas: true,
	ExcludeOperations:    []string{"/health", "/metrics"},
}
mcp := server.NewWithConfig(e, config)

func (*EchoMCP) ExcludeEndpoints

func (e *EchoMCP) ExcludeEndpoints(endpoints []string)

ExcludeEndpoints sets endpoints to exclude from MCP tools. Endpoints matching these paths will not be registered as MCP tools. This is ignored if RegisterEndpoints is set.

Supports exact paths and wildcard patterns:

  • "/health" - exact path match
  • "/admin/*" - prefix match (all paths starting with /admin/)

Example:

// Exclude internal and debug endpoints
mcp.ExcludeEndpoints([]string{
	"/health",
	"/metrics",
	"/debug/*",
	"/swagger/*",
})

func (*EchoMCP) GetServerInfo

func (e *EchoMCP) GetServerInfo() (string, string, string)

GetServerInfo returns the server information (useful for testing)

func (*EchoMCP) Mount

func (e *EchoMCP) Mount(path string) error

Mount mounts the MCP server at the specified path and registers it with the Echo instance. This creates the HTTP endpoint that MCP clients will connect to.

The mounted endpoint accepts POST requests with MCP protocol messages and returns appropriate responses for initialize, tools/list, and tools/call requests.

Example:

if err := mcp.Mount("/mcp"); err != nil {
	log.Fatal("Failed to mount MCP server:", err)
}

After mounting, the MCP server will be available at the specified path. MCP clients can connect to this endpoint to discover and execute tools.

func (*EchoMCP) RegisterEndpoints

func (e *EchoMCP) RegisterEndpoints(endpoints []string)

RegisterEndpoints sets the specific endpoints to include in MCP tools. Only endpoints matching these paths will be registered as MCP tools. If set, this takes precedence over ExcludeEndpoints.

Supports exact paths and wildcard patterns:

  • "/users/:id" - exact path match
  • "/admin/*" - prefix match (all paths starting with /admin/)

Example:

// Only expose user and order endpoints
mcp.RegisterEndpoints([]string{
	"/api/v1/users/:id",
	"/api/v1/users",
	"/api/v1/orders/*",
})

func (*EchoMCP) RegisterSchema

func (e *EchoMCP) RegisterSchema(method, path string, querySchema, bodySchema any)

RegisterSchema registers Go types for query parameters and request body for a specific route. This provides type-safe schema generation for routes that aren't covered by Swagger annotations.

Parameters:

  • method: HTTP method (e.g., "GET", "POST")
  • path: Route path as defined in Echo (e.g., "/users/:id")
  • querySchema: Go struct representing query parameters (can be nil)
  • bodySchema: Go struct representing request body (can be nil)

Example:

type UserQuery struct {
	Page  int  `form:"page" jsonschema:"minimum=1"`
	Limit int  `form:"limit" jsonschema:"maximum=100"`
}

type CreateUserRequest struct {
	Name  string `json:"name" jsonschema:"required"`
	Email string `json:"email" jsonschema:"required"`
}

mcp.RegisterSchema("GET", "/users", UserQuery{}, nil)
mcp.RegisterSchema("POST", "/users", nil, CreateUserRequest{})

type InitializeResponse

type InitializeResponse struct {
	Capabilities    *Capabilities `json:"capabilities"`
	ServerInfo      *ServerInfo   `json:"serverInfo"`
	ProtocolVersion string        `json:"protocolVersion"`
}

type ServerInfo

type ServerInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

type ToolCallRequest

type ToolCallRequest struct {
	Arguments map[string]any `json:"arguments"`
	Name      string         `json:"name"`
}

type ToolCallResponse

type ToolCallResponse struct {
	Content []Content `json:"content"`
}

type ToolsListResponse

type ToolsListResponse struct {
	Tools []types.Tool `json:"tools"`
}

Directories

Path Synopsis
examples
complex command
simple command
simple/docs
Package docs Code generated by swaggo/swag.
Package docs Code generated by swaggo/swag.
pkg
convert
Package convert handles the conversion of Echo routes to MCP tool definitions.
Package convert handles the conversion of Echo routes to MCP tool definitions.
swagger
Package swagger provides utilities for parsing Swagger/OpenAPI documentation and converting it to MCP-compatible schemas.
Package swagger provides utilities for parsing Swagger/OpenAPI documentation and converting it to MCP-compatible schemas.
types
Package types defines the core data structures used throughout the echo-mcp library.
Package types defines the core data structures used throughout the echo-mcp library.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL