Module: Mcpeye

Defined in:
lib/mcpeye.rb,
lib/mcpeye/intent.rb,
lib/mcpeye/tracker.rb,
lib/mcpeye/version.rb,
lib/mcpeye/redaction.rb,
lib/mcpeye/request_capability.rb

Overview

mcpeye — intent-gap analytics for MCP servers. “See why your agent is failing.”

This gem instruments a Ruby/Rails MCP server: it injects the optional ‘mcpeyeIntent` parameter into your tool schemas, captures every tool call (redacting secrets/PII client-side), buffers them, and POSTs the same IngestPayload JSON contract that every mcpeye SDK speaks to your self-hosted mcpeye instance at “#ingest_url/ingest”.

Defined Under Namespace

Modules: Intent, Redaction, RequestCapability Classes: Tracker

Constant Summary collapse

INTENT_PARAM_NAME =

Re-export at the top level so callers can use Mcpeye::INTENT_PARAM_NAME.

Intent::INTENT_PARAM_NAME
INTENT_PARAM_DESCRIPTION =
Intent::INTENT_PARAM_DESCRIPTION
VERSION =
"0.1.0"
REQUEST_CAPABILITY_TOOL_NAME =

Re-export at the top level for parity with INTENT_PARAM_NAME.

RequestCapability::TOOL_NAME

Class Method Summary collapse

Class Method Details

.track(server, project_id, ingest_url: nil, ingest_secret: nil, redact: true, identity: {}, identify: nil, flush_interval: nil, on_error: nil, **opts) ⇒ Object

Instrument an MCP server and return a Tracker.

tracker = Mcpeye.track(
  server,
  "my-project-id",
  ingest_url: "http://localhost:3001",          # or ENV["MCPEYE_INGEST_URL"]
  ingest_secret: ENV["MCPEYE_INGEST_SECRET"],
  redact: true,
  flush_interval: 5,                            # background flush every 5s (opt-in)
  identify: -> { { userId: Current.user_id } }, # per-flush identity (opt-in)
  on_error: ->(e) { Rails.logger.warn(e) }      # diagnostics sink (opt-in)
)

The intent param is injected into discoverable tool schemas and discoverable handlers are wrapped. For servers whose internals can’t be introspected, use the returned Tracker’s #wrap / #record / #flush directly.

When ‘flush_interval` is set, a background flush thread is started for you. A drain is registered via at_exit, so callers no longer must remember it (the explicit `at_exit { tracker.flush }` still works — it’s idempotent). In a forking server (Puma/Unicorn cluster) the thread does not survive fork: call ‘tracker.start_flush_thread` from `on_worker_boot`. See the README.

Returns the Tracker.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/mcpeye.rb', line 41

def self.track(server, project_id,
               ingest_url: nil,
               ingest_secret: nil,
               redact: true,
               identity: {},
               identify: nil,
               flush_interval: nil,
               on_error: nil,
               **opts)
  tracker = Tracker.new(
    project_id,
    ingest_url: ingest_url,
    ingest_secret: ingest_secret,
    redact: redact,
    identity: identity,
    identify: identify,
    flush_interval: flush_interval,
    on_error: on_error,
    **opts
  )
  tracker.instrument(server)
  tracker.start_flush_thread
  at_exit { tracker.at_exit_drain }
  tracker
end