scout_apm_mcp
Ruby gem providing ScoutAPM API client and MCP (Model Context Protocol) server tools for fetching traces, endpoints, metrics, errors, and insights. Integrates with MCP-compatible clients like Cursor IDE, Claude Desktop, and other MCP-enabled tools.
Sponsored by Kisko Labs.
Requirements
- Ruby 3.1 or higher (Ruby 3.0 and earlier are not supported)
Quick Start
- In scoutapm create API key under Organization settings: https://scoutapm.com/settings
- In 1Password create an item with the name "Scout APM API" and store the API key in a new field named API_KEY
- Configure your favorite service to use local MCP server, ensure OP_ENV_ENTRY_PATH has correct vault and item names (both are visible in 1Password UI)
Installation
gem install scout_apm_mcpCursor IDE Configuration
For Cursor IDE, create or update .cursor/mcp.json in your project:
{
"mcpServers": {
"scout-apm": {
"command": "scout_apm_mcp",
"env": {
"OP_ENV_ENTRY_PATH": "op://Vault Name/Item Name"
}
}
}
}Claude Desktop Configuration
For Claude Desktop, edit the MCP configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"scout-apm": {
"command": "scout_apm_mcp",
"env": {
"OP_ENV_ENTRY_PATH": "op://Vault Name/Item Name"
}
}
}
}Note: After updating the configuration, restart Claude Desktop for changes to take effect.
Security Best Practice
Do not store API keys or tokens in MCP configuration files. Instead, use one of these methods:
-
1Password Integration: Set
OP_ENV_ENTRY_PATHenvironment variable (e.g.,op://Vault/Item) to automatically load credentials via opdotenv - 1Password CLI: The gem will automatically fall back to 1Password CLI if opdotenv is not available
-
Environment Variables: Set
API_KEYorSCOUT_APM_API_KEYin your shell environment (not recommended for production - use secret vault for in-memory provisioning)
The gem will automatically detect and use credentials from your environment or 1Password integration.
Testing with MCP Inspector
You can test the MCP server using the MCP Inspector tool:
# Set your 1Password entry path (or use API_KEY/SCOUT_APM_API_KEY)
export OP_ENV_ENTRY_PATH="op://Vault/Scout APM"
# Run the MCP inspector with the server
npx @modelcontextprotocol/inspector bundle exec scout_apm_mcpThe inspector will:
- Start a proxy server and open a browser interface
- Connect to your MCP server via STDIO
- Allow you to test all available tools interactively
- Display request/response messages and any errors
This is useful for:
- Testing tool functionality before integrating with MCP clients
- Debugging MCP protocol communication
- Verifying API key configuration
- Exploring available tools and their parameters
Running the MCP Server manually
After installation, you can start the MCP server immediately:
# With bundler
gem install scout_apm_mcp && bundle exec scout_apm_mcp
# Or if installed globally
scout_apm_mcpThe server will start and communicate via STDIN/STDOUT using the MCP protocol. Make sure you have your ScoutAPM API key configured (see API Key Management section below).
Upgrading
To upgrade to the latest version of the gem:
gem update scout_apm_mcpIf you're using Bundler, update your Gemfile.lock:
bundle update scout_apm_mcpNote: As of version 0.1.3, client methods return extracted data (arrays, hashes) instead of full API response structures. This is a breaking change from previous versions. See the CHANGELOG.md for details on breaking changes and new features.
Features
- ScoutAPM API Client: Full-featured client for ScoutAPM REST API
- MCP Server Integration: Ready-to-use MCP server compatible with Cursor IDE, Claude Desktop, and other MCP-enabled tools
-
API Key Management: Supports environment variables and 1Password integration (via optional
opdotenvgem) - URL Parsing: Helper methods to parse ScoutAPM URLs and extract IDs
- Time Utilities: Helper methods for formatting, parsing, and working with ISO 8601 time strings
- Input Validation: Validates metric types, insight types, and time ranges before API calls
- Custom Error Handling: Dedicated exception classes for better error handling and debugging
- Comprehensive API Coverage: Supports all ScoutAPM API endpoints (apps, metrics, endpoints, traces, errors, insights)
- Data Extraction: Client methods return extracted data instead of full API response structure for easier usage
Basic Usage
API Client
Note: As of version 0.1.3, all client methods return extracted data (arrays, hashes) instead of the full API response structure. This is a breaking change from previous versions.
require "scout_apm_mcp"
# Get API key (from environment or 1Password)
api_key = ScoutApmMcp::Helpers.get_api_key
# Create client
client = ScoutApmMcp::Client.new(api_key: api_key)
# List applications (returns Array<Hash>)
apps = client.list_apps
# List applications filtered by active_since
apps = client.list_apps(active_since: "2025-11-01T00:00:00Z")
# Get application details (returns Hash)
app = client.get_app(123)
# List endpoints
endpoints = client.list_endpoints(123)
# Fetch trace
trace = client.fetch_trace(123, 456)
# Get metrics (returns Hash with series data)
metrics = client.get_metric(123, "response_time", from: "2025-01-01T00:00:00Z", to: "2025-01-02T00:00:00Z")
# List error groups
errors = client.list_error_groups(123, from: "2025-01-01T00:00:00Z", to: "2025-01-02T00:00:00Z")
# Get insights
insights = client.get_all_insights(123, limit: 20)URL Parsing
# Parse a ScoutAPM trace URL
url = "https://scoutapm.com/apps/123/endpoints/.../trace/456"
parsed = ScoutApmMcp::Helpers.parse_scout_url(url)
# => { app_id: 123, endpoint_id: "...", trace_id: 456, decoded_endpoint: "...", query_params: {...} }Time and Duration Helpers
# Format Time object to ISO 8601 string
time_str = ScoutApmMcp::Helpers.format_time(Time.now)
# => "2025-11-21T12:00:00Z"
# Parse ISO 8601 string to Time object
time = ScoutApmMcp::Helpers.parse_time("2025-11-21T12:00:00Z")
# => #<Time: 2025-11-21 12:00:00 UTC>
# Create duration hash from two ISO 8601 strings
duration = ScoutApmMcp::Helpers.make_duration("2025-11-21T00:00:00Z", "2025-11-21T12:00:00Z")
# => { start: #<Time: ...>, end: #<Time: ...> }
# Extract endpoint ID from endpoint hash
endpoint_id = ScoutApmMcp::Helpers.get_endpoint_id(endpoint_hash)
# => "base64-encoded-endpoint-id"API Key Management
The gem supports multiple methods for API key retrieval (checked in order):
-
Direct parameter: Pass
api_key:when callingHelpers.get_api_key -
Environment variable: Set
API_KEYorSCOUT_APM_API_KEY -
1Password via OP_ENV_ENTRY_PATH: Set
OP_ENV_ENTRY_PATHenvironment variable (e.g.,op://Vault/Item) -
1Password via opdotenv: Automatically loads from 1Password if
opdotenvgem is available andop_vault/op_itemare provided -
1Password CLI: Falls back to direct
opCLI command
# From environment variable (recommended: use in-memory vault or shell environment)
# Set API_KEY or SCOUT_APM_API_KEY in your environment
api_key = ScoutApmMcp::Helpers.get_api_key
# From 1Password using OP_ENV_ENTRY_PATH (recommended for 1Password users)
# Set OP_ENV_ENTRY_PATH in your environment (e.g., op://Vault/Item)
ENV["OP_ENV_ENTRY_PATH"] = "op://YourVault/YourItem"
api_key = ScoutApmMcp::Helpers.get_api_key
# From 1Password with explicit vault/item (requires opdotenv gem or op CLI)
api_key = ScoutApmMcp::Helpers.get_api_key(
op_vault: "YourVault",
op_item: "Your ScoutAPM API",
op_field: "API_KEY"
)Security Note: Never hardcode API keys in your code or configuration files. Always use environment variables, in-memory vaults, or secure credential management systems like 1Password.
API Methods
Applications
-
list_apps(active_since:)- List all applications (optionally filtered by last reported time) -
get_app(app_id)- Get application details
Metrics
-
list_metrics(app_id)- List available metric types -
get_metric(app_id, metric_type, from:, to:)- Get time-series metric data
Endpoints
-
list_endpoints(app_id, from:, to:)- List all endpoints -
get_endpoint(app_id, endpoint_id)- Get endpoint details -
get_endpoint_metrics(app_id, endpoint_id, metric_type, from:, to:)- Get endpoint metrics -
list_endpoint_traces(app_id, endpoint_id, from:, to:)- List endpoint traces
Traces
-
fetch_trace(app_id, trace_id)- Fetch detailed trace information
Errors
-
list_error_groups(app_id, from:, to:, endpoint:)- List error groups -
get_error_group(app_id, error_id)- Get error group details -
get_error_group_errors(app_id, error_id)- Get errors within a group
Insights
-
get_all_insights(app_id, limit:)- Get all insight types -
get_insight_by_type(app_id, insight_type, limit:)- Get specific insight type -
get_insights_history(app_id, from:, to:, limit:, pagination_cursor:, pagination_direction:, pagination_page:)- Get historical insights -
get_insights_history_by_type(app_id, insight_type, from:, to:, limit:, pagination_cursor:, pagination_direction:, pagination_page:)- Get historical insights by type
OpenAPI Schema
-
fetch_openapi_schema- Fetch the ScoutAPM OpenAPI schema
MCP Server Integration
This gem includes a ready-to-use MCP server that can be run directly:
# After installing the gem
bundle exec scout_apm_mcpOr if installed globally:
gem install scout_apm_mcp
scout_apm_mcpThe server will communicate via STDIN/STDOUT using the MCP protocol. Configure it in your MCP client (e.g., Cursor IDE, Claude Desktop, or other MCP-enabled tools).
Error Handling
The client uses custom exception classes for better error handling:
-
ScoutApmMcp::Error- Base exception class for all ScoutAPM SDK errors -
ScoutApmMcp::AuthError- Raised when authentication fails (401 Unauthorized) -
ScoutApmMcp::APIError- Raised for API errors (includesstatus_codeandresponse_dataattributes)
The client also validates input parameters and raises ArgumentError for:
- Invalid metric types (must be one of:
apdex,response_time,response_time_95th,errors,throughput,queue_time) - Invalid insight types (must be one of:
n_plus_one,memory_bloat,slow_query) - Invalid time ranges (from_time must be before to_time, and range cannot exceed 2 weeks)
- Trace queries older than 7 days (for
list_endpoint_traces)
begin
client.get_metric(123, "invalid_metric", from: "2025-01-01T00:00:00Z", to: "2025-01-02T00:00:00Z")
rescue ScoutApmMcp::AuthError => e
puts "Authentication failed: #{e.message}"
rescue ScoutApmMcp::APIError => e
puts "API error (#{e.status_code}): #{e.message}"
puts "Response data: #{e.response_data}"
rescue ArgumentError => e
puts "Invalid parameter: #{e.message}"
rescue ScoutApmMcp::Error => e
puts "Error: #{e.message}"
endDevelopment
# Install dependencies
bundle install
# Run tests
bundle exec rspec
# Run tests across multiple Ruby versions
bundle exec appraisal install
bundle exec appraisal rspec
# Run linting
bundle exec standardrb --fix
# Validate RBS type signatures
bundle exec rbs validateContributing
Bug reports and pull requests are welcome on GitHub at https://github.com/amkisko/scout_apm_mcp.rb.
Contribution policy:
- New features are not necessarily added to the gem
- Pull request should have test coverage for affected parts
- Pull request should have changelog entry
Review policy:
- It might take up to 2 calendar weeks to review and merge critical fixes
- It might take up to 6 calendar months to review and merge pull request
- It might take up to 1 calendar year to review an issue
For more information, see CONTRIBUTING.md.
Security
If you discover a security vulnerability, please report it responsibly. See SECURITY.md for details.
License
The gem is available as open source under the terms of the MIT License.