0.0
A long-lived project that still receives updates
Ruby gem providing ScoutAPM API client and MCP server tools for fetching traces, endpoints, metrics, errors, and insights. Integrates with Cursor IDE via Model Context Protocol.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

Runtime

~> 0.3
>= 0.1, < 2.0
~> 1.0
~> 2.2, >= 2.2.0
 Project Readme

scout_apm_mcp

Gem Version Test Status codecov

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.

Sponsored by Kisko Labs

Requirements

  • Ruby 3.1 or higher (Ruby 3.0 and earlier are not supported)

Quick Start

  1. In scoutapm create API key under Organization settings: https://scoutapm.com/settings
  2. In 1Password create an item with the name "Scout APM API" and store the API key in a new field named API_KEY
  3. 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_mcp

Cursor 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:

  1. 1Password Integration: Set OP_ENV_ENTRY_PATH environment variable (e.g., op://Vault/Item) to automatically load credentials via opdotenv
  2. 1Password CLI: The gem will automatically fall back to 1Password CLI if opdotenv is not available
  3. Environment Variables: Set API_KEY or SCOUT_APM_API_KEY in 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_mcp

The inspector will:

  1. Start a proxy server and open a browser interface
  2. Connect to your MCP server via STDIO
  3. Allow you to test all available tools interactively
  4. 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_mcp

The 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_mcp

If you're using Bundler, update your Gemfile.lock:

bundle update scout_apm_mcp

Note: 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 opdotenv gem)
  • 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):

  1. Direct parameter: Pass api_key: when calling Helpers.get_api_key
  2. Environment variable: Set API_KEY or SCOUT_APM_API_KEY
  3. 1Password via OP_ENV_ENTRY_PATH: Set OP_ENV_ENTRY_PATH environment variable (e.g., op://Vault/Item)
  4. 1Password via opdotenv: Automatically loads from 1Password if opdotenv gem is available and op_vault/op_item are provided
  5. 1Password CLI: Falls back to direct op CLI 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_mcp

Or if installed globally:

gem install scout_apm_mcp
scout_apm_mcp

The 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 (includes status_code and response_data attributes)

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}"
end

Development

# 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 validate

Contributing

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.