Class: WorldMonitor::Client
- Inherits:
-
Object
- Object
- WorldMonitor::Client
- Defined in:
- lib/worldmonitor.rb
Overview
Thin client for the World Monitor MCP server and REST API.
All keyword arguments are optional; unset values fall back to the
WORLDMONITOR_API_KEY (or WM_API_KEY), WORLDMONITOR_BASE_URL, and
WORLDMONITOR_MCP_URL environment variables, then to the public production
endpoints. transport is injectable for offline tests: a callable
(request_hash, timeout) -> [status, content_type, body].
Instance Attribute Summary collapse
-
#api_key ⇒ Object
readonly
Returns the value of attribute api_key.
-
#base_url ⇒ Object
readonly
Returns the value of attribute base_url.
-
#mcp_url ⇒ Object
readonly
Returns the value of attribute mcp_url.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
Class Method Summary collapse
-
.parse_body(text, content_type = "") ⇒ Object
Decode an MCP/REST response body.
- .truncate(value, limit = 300) ⇒ Object
Instance Method Summary collapse
-
#call_tool(name, arguments = {}) ⇒ Object
Call an MCP tool by name and return the unwrapped JSON-RPC result.
-
#conflict_events(args = {}) ⇒ Object
Recent conflict events (country:, min_fatalities:, limit: ...).
-
#country_brief(country_code, args = {}) ⇒ Object
AI strategic brief for a country (ISO 3166-1 alpha-2 code).
-
#country_risk(country_code, args = {}) ⇒ Object
Country risk / resilience scores (ISO 3166-1 alpha-2 code).
-
#cyber_threats(args = {}) ⇒ Object
Cyber-threat indicators (min_severity:, threat_type:, country: ...).
-
#forecast_predictions(args = {}) ⇒ Object
Scenario forecasts (domain:, region: ...).
-
#get(path, params = {}) ⇒ Object
GET a raw REST path (host-relative, e.g. "/api/health").
-
#health ⇒ Object
API status / health check.
-
#initialize(api_key: nil, base_url: nil, mcp_url: nil, timeout: DEFAULT_TIMEOUT, transport: nil, env: ENV) ⇒ Client
constructor
A new instance of Client.
-
#list_prompts ⇒ Object
List MCP prompt templates (public).
-
#list_resources ⇒ Object
List MCP resources (public).
-
#list_tools ⇒ Object
List every MCP tool (public - no key needed).
-
#maritime_activity(country_code, args = {}) ⇒ Object
Maritime / port activity for a country (ISO 3166-1 alpha-2 code).
-
#market_data(args = {}) ⇒ Object
Equities, commodities, crypto and FX quotes.
-
#natural_disasters(args = {}) ⇒ Object
Earthquakes, fires and storms (dataset:, active_only:, min_magnitude: ...).
-
#news_intelligence(args = {}) ⇒ Object
Classified news intelligence (topic:, country:, alerts_only: ...).
-
#sanctions_data(args = {}) ⇒ Object
Sanctions designations (country:, entity_type:, query: ...).
-
#world_brief(args = {}) ⇒ Object
Live global situation brief.
Constructor Details
#initialize(api_key: nil, base_url: nil, mcp_url: nil, timeout: DEFAULT_TIMEOUT, transport: nil, env: ENV) ⇒ Client
Returns a new instance of Client.
83 84 85 86 87 88 89 90 |
# File 'lib/worldmonitor.rb', line 83 def initialize(api_key: nil, base_url: nil, mcp_url: nil, timeout: DEFAULT_TIMEOUT, transport: nil, env: ENV) @api_key = api_key || env["WORLDMONITOR_API_KEY"] || env["WM_API_KEY"] @base_url = (base_url || env["WORLDMONITOR_BASE_URL"] || DEFAULT_BASE_URL).sub(%r{/+\z}, "") @mcp_url = mcp_url || env["WORLDMONITOR_MCP_URL"] || DEFAULT_MCP_URL @timeout = timeout @transport = transport || method(:http_transport) end |
Instance Attribute Details
#api_key ⇒ Object (readonly)
Returns the value of attribute api_key.
81 82 83 |
# File 'lib/worldmonitor.rb', line 81 def api_key @api_key end |
#base_url ⇒ Object (readonly)
Returns the value of attribute base_url.
81 82 83 |
# File 'lib/worldmonitor.rb', line 81 def base_url @base_url end |
#mcp_url ⇒ Object (readonly)
Returns the value of attribute mcp_url.
81 82 83 |
# File 'lib/worldmonitor.rb', line 81 def mcp_url @mcp_url end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
81 82 83 |
# File 'lib/worldmonitor.rb', line 81 def timeout @timeout end |
Class Method Details
.parse_body(text, content_type = "") ⇒ Object
Decode an MCP/REST response body. MCP responses may arrive as
Server-Sent Events (Streamable HTTP): pull the last data: payload.
Otherwise parse the whole body as JSON, falling back to the raw text.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/worldmonitor.rb', line 202 def self.parse_body(text, content_type = "") payload = text if (content_type || "").include?("text/event-stream") || text =~ /^(event|data):/ data_lines = text.split(/\r?\n/).select { |l| l.start_with?("data:") } payload = data_lines.empty? ? "" : data_lines.last[5..-1].strip end return text if payload.nil? || payload.empty? begin JSON.parse(payload) rescue JSON::ParserError text end end |
.truncate(value, limit = 300) ⇒ Object
217 218 219 220 |
# File 'lib/worldmonitor.rb', line 217 def self.truncate(value, limit = 300) text = value.is_a?(String) ? value : JSON.generate(value) text.length <= limit ? text : "#{text[0, limit - 1]}…" end |
Instance Method Details
#call_tool(name, arguments = {}) ⇒ Object
Call an MCP tool by name and return the unwrapped JSON-RPC result. Keyword arguments become the tool's arguments:
call_tool("get_country_risk", country_code: "IR")
97 98 99 |
# File 'lib/worldmonitor.rb', line 97 def call_tool(name, arguments = {}) rpc("tools/call", { "name" => name, "arguments" => stringify_keys(arguments) }) end |
#conflict_events(args = {}) ⇒ Object
Recent conflict events (country:, min_fatalities:, limit: ...).
163 164 165 |
# File 'lib/worldmonitor.rb', line 163 def conflict_events(args = {}) call_tool("get_conflict_events", args) end |
#country_brief(country_code, args = {}) ⇒ Object
AI strategic brief for a country (ISO 3166-1 alpha-2 code).
148 149 150 |
# File 'lib/worldmonitor.rb', line 148 def country_brief(country_code, args = {}) call_tool("get_country_brief", args.merge(country_code: country_code)) end |
#country_risk(country_code, args = {}) ⇒ Object
Country risk / resilience scores (ISO 3166-1 alpha-2 code).
153 154 155 |
# File 'lib/worldmonitor.rb', line 153 def country_risk(country_code, args = {}) call_tool("get_country_risk", args.merge(country_code: country_code)) end |
#cyber_threats(args = {}) ⇒ Object
Cyber-threat indicators (min_severity:, threat_type:, country: ...).
168 169 170 |
# File 'lib/worldmonitor.rb', line 168 def cyber_threats(args = {}) call_tool("get_cyber_threats", args) end |
#forecast_predictions(args = {}) ⇒ Object
Scenario forecasts (domain:, region: ...).
188 189 190 |
# File 'lib/worldmonitor.rb', line 188 def forecast_predictions(args = {}) call_tool("get_forecast_predictions", args) end |
#get(path, params = {}) ⇒ Object
GET a raw REST path (host-relative, e.g. "/api/health").
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/worldmonitor.rb', line 117 def get(path, params = {}) raise ArgumentError, "get() needs a host-relative API path starting with '/'" unless path.start_with?("/") url = base_url + path query = stringify_keys(params) url += "?#{URI.encode_www_form(query.map { |k, v| [k, stringify_value(v)] })}" unless query.empty? status, content_type, body = @transport.call( { url: url, method: "GET", headers: headers(accept: "application/json") }, timeout ) value = self.class.parse_body(body, content_type) raise APIError.new(status, value) unless (200..299).cover?(status) value end |
#health ⇒ Object
API status / health check.
134 135 136 |
# File 'lib/worldmonitor.rb', line 134 def health get("/api/health") end |
#list_prompts ⇒ Object
List MCP prompt templates (public).
107 108 109 |
# File 'lib/worldmonitor.rb', line 107 def list_prompts rpc("prompts/list") end |
#list_resources ⇒ Object
List MCP resources (public).
112 113 114 |
# File 'lib/worldmonitor.rb', line 112 def list_resources rpc("resources/list") end |
#list_tools ⇒ Object
List every MCP tool (public - no key needed).
102 103 104 |
# File 'lib/worldmonitor.rb', line 102 def list_tools rpc("tools/list") end |
#maritime_activity(country_code, args = {}) ⇒ Object
Maritime / port activity for a country (ISO 3166-1 alpha-2 code).
193 194 195 |
# File 'lib/worldmonitor.rb', line 193 def maritime_activity(country_code, args = {}) call_tool("get_maritime_activity", args.merge(country_code: country_code)) end |
#market_data(args = {}) ⇒ Object
Equities, commodities, crypto and FX quotes.
158 159 160 |
# File 'lib/worldmonitor.rb', line 158 def market_data(args = {}) call_tool("get_market_data", args) end |
#natural_disasters(args = {}) ⇒ Object
Earthquakes, fires and storms (dataset:, active_only:, min_magnitude: ...).
178 179 180 |
# File 'lib/worldmonitor.rb', line 178 def natural_disasters(args = {}) call_tool("get_natural_disasters", args) end |
#news_intelligence(args = {}) ⇒ Object
Classified news intelligence (topic:, country:, alerts_only: ...).
173 174 175 |
# File 'lib/worldmonitor.rb', line 173 def news_intelligence(args = {}) call_tool("get_news_intelligence", args) end |
#sanctions_data(args = {}) ⇒ Object
Sanctions designations (country:, entity_type:, query: ...).
183 184 185 |
# File 'lib/worldmonitor.rb', line 183 def sanctions_data(args = {}) call_tool("get_sanctions_data", args) end |
#world_brief(args = {}) ⇒ Object
Live global situation brief.
143 144 145 |
# File 'lib/worldmonitor.rb', line 143 def world_brief(args = {}) call_tool("get_world_brief", args) end |