SwaggerMCPTool
A Ruby gem that automatically generates MCP (Model Context Protocol) tools from Swagger/OpenAPI specifications. This gem allows you to create both HTTP and STDIO MCP servers that dynamically generate tools based on API endpoints defined in Swagger/OpenAPI documentation.
Features
- Automatic Tool Generation: Dynamically creates MCP tools from Swagger/OpenAPI specifications
- Dual Server Support: Both HTTP server and STDIO server implementations
- Path Parameter Handling: Properly substitutes path parameters in API endpoints (e.g.,
/pet/{petId}) - Multiple Server Types: Supports Puma and other Rack-compatible servers
- Authentication Support: Token-based authentication with configurable headers
- Comprehensive Logging: Detailed request/response logging with configurable levels
- Error Handling: Robust error handling for API failures and edge cases
- User Context: Passes user context from LLM to API calls
- Easy Configuration: Simple Ruby-based configuration system
- Command Line Interface: Built-in CLI for quick server startup
Dependencies
- Ruby 3.2 or higher
- Gems:
- sinatra
- sinatra-contrib
- mcp
- json
- puma
- rackup
- pry (development)
- rake (development)
Installation
From RubyGems
gem install swagger_mcp_tool
From Source
Clone the repository:
git clone https://github.com/yourusername/swagger_mcp_tool.git
cd swagger_mcp_tool
Build and install the gem:
gem build swagger_mcp_tool.gemspec
gem install swagger_mcp_tool-0.1.0.gem
Using Bundler
Add this line to your application's Gemfile:
gem 'swagger_mcp_tool'
And then execute:
bundle install
Starting the Server
Command Line Interface
The gem provides a command-line executable for quick server startup:
# Start with default settings (Petstore API)
swagger_mcp_server
# Start with custom port and Swagger URL
swagger_mcp_server --port 3001 --swagger-url https://api.example.com/swagger.json
# Show help
swagger_mcp_server --help
STDIO Server (Recommended for MCP Integration)
Use the provided example for direct integration with MCP clients like Kiro IDE:
File: examples/mcp_stdio_server.rb
require 'swagger_mcp_tool'
SwaggerMCPTool.configure do |config|
# Swagger settings
config.swagger_url = 'https://petstore.swagger.io/v2/swagger.json'
# MCP settings
config.mcp_name = 'my_company_api'
config.mcp_name_for_human = 'My Company API'
config.mcp_description_for_human = "Tools for interacting with My Company's API"
config.auth_header_name = :'Token'
config.protocol_version = "2025-03-26"
# Force stdio mode
config.stdio_mode = true if config.respond_to?(:stdio_mode=)
end
# Start the MCP server in stdio mode
SwaggerMCPTool.start_stdio_server
OR
#!/usr/bin/env ruby
gem install swagger_mcp_tool
# Load swagger_mcp_tool modules
require 'swagger_mcp_tool'
class WorkingSwaggerMCPStdioServer
include SwaggerMCPTool::Logging
include SwaggerMCPTool::Helpers::ToolRegister
def initialize
@logger = Logger.new($stderr)
@logger.level = Logger::INFO
@logger.info 'Initializing WorkingSwaggerMCPStdioServer with swagger_mcp_tool'
# Configure the swagger_mcp_tool
@config = SwaggerMCPTool.configure do |config|
# to switch to other swagger documentation just change url here
config.swagger_url = 'https://petstore.swagger.io/v2/swagger.json'
config.mcp_name = 'swagger_api_tools12'
config.mcp_name_for_human = 'Swagger API Tools'
config.mcp_description_for_human = 'Tools for interacting with APIs via Swagger/OpenAPI specifications'
config.mcp_description_for_model = 'This MCP server provides tools for interacting with APIs via Swagger/OpenAPI specifications.'
# Add default prompts
end
setup_tool_registry
initialize_tools
@logger.info 'Configuration set, generating tools using swagger_mcp_tool components'
# Generate tools using the swagger_mcp_tool components directly
@tools = tool_registry.dynamic_tools
@logger.info "Generated #{@tools.size} tools from Swagger specification"
# Log all tool names
@tools.each { |tool| @logger.info "Available tool: #{tool.name}" }
end
def start_stdio_server
@logger.info "Starting MCP stdio server with #{@tools.size} tools"
# Create MCP server with our dynamically generated tools
mcp_server = MCP::Server.new(
name: 'swagger_api_tools',
tools: @tools,
server_context: { user_id: 1 }
)
@logger.info 'MCP server created, starting stdio loop'
# Handle stdio communication
$stdin.each_line do |line|
line = line.strip
next if line.empty?
@logger.debug "Received: #{line}"
# Validate JSON-RPC request format
begin
request_data = JSON.parse(line)
unless request_data.is_a?(Hash) && request_data['jsonrpc'] && request_data['method']
@logger.error "Invalid JSON-RPC request format: #{line}"
next
end
rescue JSON::ParserError => e
@logger.error "Invalid JSON in request: #{e.}"
next
end
# Process the JSON-RPC request
@logger.info "Processing JSON-RPC request: #{request_data['method']}"
response = mcp_server.handle_json(line)
@logger.info "Generated response for method: #{request_data['method']}"
# Send response to stdout
puts response
$stdout.flush
rescue StandardError => e
@logger.error "Error processing request: #{e.}"
@logger.error "Error class: #{e.class}"
@logger.error e.backtrace.join("\n")
# Extract request ID if possible
request_id = nil
begin
parsed_request = JSON.parse(line)
request_id = parsed_request['id']
rescue StandardError
# Ignore parsing errors for error response
end
# Send error response
error_response = {
jsonrpc: '2.0',
id: request_id,
error: {
code: -32_603,
message: "Internal error: #{e.}"
}
}
error_json = error_response.to_json
@logger.debug "Sending error response: #{error_json}"
puts error_json
$stdout.flush
end
end
end
# Start the server if this file is executed directly
if __FILE__ == $0
server = WorkingSwaggerMCPStdioServer.new
server.start_stdio_server
end
Run the STDIO server:
ruby examples/mcp_stdio_server.rb
HTTP Server
Use the provided example for HTTP-based integration:
File: examples/start_server.rb
#!/usr/bin/env ruby
gem install swagger_mcp_tool
require 'swagger_mcp_tool'
SwaggerMCPTool.configure do |config|
# Server settings
config.server_port = 3001
config.server_bind = '0.0.0.0'
# Swagger settings
config.swagger_url = 'https://petstore.swagger.io/v2/swagger.json'
# MCP settings
config.mcp_name = 'my_company_api'
config.mcp_name_for_human = 'My Company API'
config.mcp_description_for_human = "Tools for interacting with My Company's API"
config.auth_header_name = :'X-Auth-Token'
end
# Start the server
SwaggerMCPTool.start_server
Run the HTTP server:
ruby examples/start_server.rb
Configuration
The gem uses a singleton Config class for configuration. You can configure it using a block:
SwaggerMCPTool.configure do |config|
# Server settings
config.server_port = 3001
config.server_bind = '0.0.0.0'
config.server_type = :puma
config.log_level = Logger::INFO
config.log_file = 'mcp_server.log'
# Swagger settings
config.swagger_url = "https://petstore.swagger.io/v2/swagger.json"
# MCP settings
config.mcp_name = "swagger_api_tools"
config.mcp_name_for_human = "Swagger API Tools"
config.mcp_description_for_human = "Tools for interacting with APIs via Swagger/OpenAPI specifications"
config.mcp_description_for_model = "This MCP server provides tools for interacting with APIs via Swagger/OpenAPI specifications."
# Auth settings
config.auth_type = "none" # or "bearer", "basic", etc.
config.auth_header_name = "Token" # Default header name for auth
config.default_token = nil
config.prompts = []
config.resources = []
end
Configuration Options
| Option | Default | Description |
|---|---|---|
server_port |
3001 | HTTP server port |
server_bind |
'0.0.0.0' | Server bind address |
server_type |
:puma | Server type (Puma, etc.) |
log_level |
Logger::INFO | Logging level |
log_file |
'mcp_server.log' | Log file path |
swagger_url |
Petstore demo | Swagger/OpenAPI spec URL |
mcp_name |
'swagger_api_tools' | MCP server name |
auth_type |
'none' | Authentication type |
auth_header_name |
'Token' | Auth header name |
protocol_version |
'2025-03-26' | Protocol Version Supported by Client |
Working with Prompts
Add Prompts
The gem comes with some built-in prompts that you can use:
SwaggerMCPTool.configure do |config|
# Add built-in prompts
config.prompts = ['prompt1', 'prompt2']
end
Adding Resources
You can add resources that will be passed to the MCP server:
SwaggerMCPTool.configure do |config|
# Add a simple text resource
config.resources = ['resource1', 'resouce2']
end
MCP Integration
Kiro IDE Integration
To use with Kiro IDE, add the server to your MCP configuration file (.kiro/settings/mcp.json):
{
"mcpServers": {
"swagger-mcp-tool": {
"command": "/Users/<user>/.rbenv/versions/3.2.2/bin/ruby",
"args": [
"/Users/<user>/projects/dummy/swagger_mcp_tool/examples/mcp_stdio_server.rb"
],
"env": {
"RBENV_VERSION": "3.2.2",
"PATH": "/Users/<user>/.rbenv/versions/3.2.2/bin:/Users/<user>/.rbenv/shims:/usr/local/bin:/usr/bin:/bin"
},
"disabled": false,
"autoApprove": []
}
}
}
Note: Update the paths to match your Ruby installation and project location.
Generated Tools
The server automatically generates MCP tools based on your Swagger specification. For example, with the Petstore API:
getInventory- Get pet inventory by statusgetPetById- Find pet by ID (handles path parameters)findPetsByStatus- Find pets by status (handles query parameters)addPet- Add a new pet (handles request body)updatePet- Update an existing petdeletePet- Delete a petgetUserByName- Get user by usernamedeleteUser- Delete user
Tool Features
- Path Parameters: Automatically substitutes
{petId}with actual values - Query Parameters: Handles array and single-value query parameters
- Request Bodies: Processes JSON request bodies for POST/PUT operations
- Error Handling: Returns proper error responses for 404, 400, etc.
- Type Validation: Validates parameter types based on Swagger schema
Authentication
Setting an Auth Token (HTTP Server)
You can set an auth token for a user by making a POST request to the /set_auth_token endpoint:
curl -X POST http://localhost:3001/set_auth_token \
-H "Content-Type: application/json" \
-d '{"user_id": "user123", "auth_token": "Bearer token123"}'
Passing User Context (HTTP Server)
When making requests to the HTTP MCP server, you can pass user context in the headers:
curl -X POST http://localhost:3001/mcp \
-H "Content-Type: application/json" \
-H "X-User-ID: user123" \
-H "X-Username: John Doe" \
-H "X-Email: [email protected]" \
-H "X-Auth-Token: Bearer token123" \
-d '{"jsonrpc":"2.0","id":"1","method":"tools/list"}'
Usage Examples
Using the Examples
The gem includes working examples in the examples/ directory:
- STDIO Server:
examples/mcp_stdio_server.rb- For MCP client integration - HTTP Server:
examples/start_server.rb- For web-based integration - CLI Tool:
bin/swagger_mcp_server- Command-line interface
Customizing for Your API
To use with your own API, modify the Swagger URL in the examples:
# In examples/mcp_stdio_server.rb or examples/start_server.rb
SwaggerMCPTool.configure do |config|
config.swagger_url = 'https://your-api.com/swagger.json' # Change this
config.mcp_name = 'your_api_tools'
config.mcp_name_for_human = 'Your API Tools'
# ... other configuration
end
Available Endpoints (HTTP Server)
When running the HTTP server, the following endpoints are available:
GET /mcp/manifest- MCP manifest for integrationPOST /mcp- MCP JSON-RPC requestsPOST /set_auth_token- Set authentication tokensPOST /generate_tools- Regenerate tools from Swagger URLGET /health- Health check and server statusGET /logo.png- Server logo (if available)
Testing Your Tools
With Kiro IDE
Once configured in Kiro, you can test tools directly:
# Test getInventory (no parameters)
Use the getInventory tool
# Test getPetById (path parameter)
Use getPetById with petId: 1
# Test findPetsByStatus (query parameter)
Use findPetsByStatus with status: ["available"]
# Test addPet (request body)
Use addPet with name: "Fluffy", photoUrls: ["http://example.com/photo.jpg"], status: "available"
With HTTP Server
Test tools via HTTP requests:
# List available tools
curl -X POST http://localhost:3001/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":"1","method":"tools/list"}'
# Call a tool
curl -X POST http://localhost:3001/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":"1",
"method":"tools/call",
"params":{
"name":"getInventory",
"arguments":{}
}
}'
Expected Tool Output
For the Petstore API, you'll see tools like:
getInventory: Returns inventory counts by status
{ "available": 487, "pending": 10, "sold": 22 }getPetById: Returns pet details
{ "id": 1, "name": "Fluffy", "status": "available", "photoUrls": ["http://example.com/photo.jpg"] }
Troubleshooting
Common Issues
- Path Parameter Substitution: Ensure your Swagger spec properly defines path parameters like
{petId} - Authentication: Check that auth headers are properly configured in your config
- CORS Issues: The HTTP server includes CORS headers for web integration
- Tool Generation: Verify your Swagger URL is accessible and returns valid JSON
- Ruby Version: Ensure you're using Ruby 3.2 or higher
Debug Mode
Enable debug logging in your configuration:
SwaggerMCPTool.configure do |config|
config.log_level = Logger::DEBUG
end
Checking Logs
- STDIO Server: Logs go to stderr, check your terminal output
- HTTP Server: Logs go to the configured log file (default:
mcp_server.log) - Kiro Integration: Check Kiro's MCP server logs in the IDE
Verifying Tool Generation
Check if tools are being generated correctly:
# Run the STDIO server and check stderr output
ruby examples/mcp_stdio_server.rb
# Look for messages like:
# "Generated 15 tools from Swagger specification"
# "Available tool: getInventory"
# "Available tool: getPetById"
Testing Swagger URL
Verify your Swagger URL is accessible:
curl -s https://petstore.swagger.io/v2/swagger.json | jq .info.title
# Should return: "Swagger Petstore"
Vs code config for stdio
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": [
"mcp-server-fetch"
],
"env": {},
"disabled": false,
"autoApprove": []
},
"swagger-api-tools": {
"command": "/Users/<user>/.rbenv/shims/ruby",
"args": [
"< absolute path to mcp_stdio_server.rb >"
],
"disabled": false,
"autoApprove": [
"getInventory",
"getPetById",
"findPetsByStatus"
]
}
}
}
Architecture
The gem consists of several key components:
- Config: Singleton configuration management
- SwaggerClient: Fetches and parses Swagger/OpenAPI specifications
- ToolGenerator: Converts Swagger operations to tool definitions
- ApiClient: Handles HTTP requests with proper parameter substitution
- ToolRegistry: Manages dynamic tool registration
- Server: HTTP server implementation
- STDIO Server: Direct MCP integration server
Development
After checking out the repo, run bundle install to install dependencies.
To install this gem onto your local machine, run bundle exec rake install.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/yourusername/swagger_mcp_tool.
License
The gem is available as open source under the terms of the MIT License.