Class: Msf::MCP::Tools::ServiceInfo

Inherits:
MCP::Tool
  • Object
show all
Extended by:
ToolHelper
Defined in:
lib/msf/core/mcp/tools/service_info.rb

Overview

MCP Tool: Query Metasploit Database Services

Retrieves service information from the Metasploit database including ports, protocols, and service banners.

Class Method Summary collapse

Methods included from ToolHelper

tool_error_response

Class Method Details

.call(workspace: 'default', names: nil, ports: nil, host: nil, protocol: nil, only_up: false, limit: Msf::MCP::Security::InputValidator::LIMIT_DEFAULT, offset: 0, server_context:) ⇒ MCP::Tool::Response

Execute service query

Parameters:

  • workspace (String) (defaults to: 'default')

    Workspace name (default: ‘default’)

  • names (String, nil) (defaults to: nil)

    Comma-separated service names to filter

  • ports (String, nil) (defaults to: nil)

    Port number or range to filter

  • host (String, nil) (defaults to: nil)

    Host IP address

  • protocol (String, nil) (defaults to: nil)

    Protocol to filter (tcp or udp)

  • only_up (Boolean) (defaults to: false)

    Filter to only return services on hosts that are up

  • limit (Integer) (defaults to: Msf::MCP::Security::InputValidator::LIMIT_DEFAULT)

    Maximum results (default: 100)

  • offset (Integer) (defaults to: 0)

    Results offset (default: 0)

  • server_context (Hash)

    Server context with msf_client, rate_limiter, config

Returns:

  • (MCP::Tool::Response)

    Structured response with service information



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/msf/core/mcp/tools/service_info.rb', line 119

def call(workspace: 'default', names: nil, ports: nil, host: nil, protocol: nil, only_up: false, limit: Msf::MCP::Security::InputValidator::LIMIT_DEFAULT, offset: 0, server_context:)
  start_time = Time.now

  # Extract dependencies from server context
  msf_client = server_context[:msf_client]
  rate_limiter = server_context[:rate_limiter]

  # Check rate limit
  rate_limiter.check_rate_limit!('service_info')

  # Validate inputs
  Msf::MCP::Security::InputValidator.validate_pagination!(limit, offset)
  Msf::MCP::Security::InputValidator.validate_only_up!(only_up)
  Msf::MCP::Security::InputValidator.validate_protocol!(protocol) if protocol
  Msf::MCP::Security::InputValidator.validate_ip_address!(host) if host
  Msf::MCP::Security::InputValidator.validate_port_range!(ports) if ports

  # Call Metasploit API
  # Note that `workspace` is optional in the MSF API, the default workspace is used if not provided.
  # The default value is sent anyway for clarity.
  options = { workspace: workspace }
  options[:only_up] = only_up if only_up
  options[:proto] = protocol if protocol
  # The API is misleading, it only supports a single address filter, not multiple.
  options[:addresses] = host if host
  options[:ports] = ports if ports
  options[:names] = names if names
  raw_services = msf_client.db_services(options)

  # Transform response
  transformed = Metasploit::ResponseTransformer.transform_services(raw_services)

  # Apply pagination
  #
  # Note that to get the total number of entries, we gather the entire data set and apply pagination here
  # instead of sending the limit and offset to the API call to be processed by MSF.
  # This is needed to provide accurate total_items count in the metadata.
  total_items = transformed.size
  paginated_data = transformed[offset, limit] || []

  # Build metadata
   = {
    workspace: workspace,
    query_time: (Time.now - start_time).round(3),
    total_items: total_items,
    returned_items: paginated_data.size,
    limit: limit,
    offset: offset
  }

  # Return MCP response
  ::MCP::Tool::Response.new(
    [
      {
        type: 'text',
        text: JSON.generate(
          metadata: ,
          data: paginated_data
        )
      }
    ],
    structured_content: {
      metadata: ,
      data: paginated_data
    }
  )
rescue Msf::MCP::Security::RateLimitExceededError => e
  tool_error_response("Rate limit exceeded: #{e.message}")
rescue Msf::MCP::Metasploit::AuthenticationError => e
  tool_error_response("Authentication failed: #{e.message}")
rescue Msf::MCP::Metasploit::APIError => e
  tool_error_response("Metasploit API error: #{e.message}")
rescue Msf::MCP::Security::ValidationError => e
  tool_error_response(e.message)
end