Module: Mcpeye::RequestCapability

Defined in:
lib/mcpeye/request_capability.rb

Overview

The active missing-capability contract — the reserved ‘mcpeye_request_capability` tool the SDK adds to the server’s tool registry.

The passive ‘mcpeyeIntent` param (see intent.rb) only sees a missing capability when the agent still calls SOME tool and self-reports the gap in the intent text. Its blind spot is the silent miss: when no tool fits, the correct behavior is to call no tool at all — so there is no intent string and no tool_call row, yet that is the highest-value roadmap signal (a user need with zero matching tool).

This closes the gap actively: the SDK adds a reserved tool the agent can call to voice a capability the available tools do not cover. The SDK answers it locally (the host never sees it), returns a friendly acknowledgement, and records it as a normal tool_call with tool_name = “mcpeye_request_capability”. The report folds these explicit calls into topMissingCapabilities as high-confidence entries.

Keep these strings byte-for-byte in sync with @mcpeye/core (packages/core/src/request-capability.ts) and the Python SDK (packages/sdk-python/src/mcpeye/request_capability.py). spec/request_capability_spec.rb asserts them against the canonical text.

Constant Summary collapse

TOOL_NAME =
"mcpeye_request_capability"
TOOL_DESCRIPTION =

Byte-for-byte identical to packages/core/src/request-capability.ts. The lower-the-bar framing (“even if an existing tool could be a fallback”) is what pulls calls; a timid framing leaves the signal near zero. Change all SDKs together.

"Use this tool whenever the user wants something the available tools do not cover, " \
"or whenever the task might benefit from a more specialized capability even if an " \
"existing tool could be used as a fallback. Describe the capability the user actually " \
"needs, in their own words (for example: 'export the report as a PDF'). This signal is " \
"used only to improve which tools are offered; calling it has no side effects and does " \
"not perform the action."
CAPABILITY_DESCRIPTION =
"The capability the user needs that the available tools do not provide, in the user's " \
"own words (for example: 'export the report as a PDF')."
CONTEXT_DESCRIPTION =
"Optional: what the user was trying to accomplish when they reached for this capability."
ACK =
"Thanks. This capability request has been recorded for the server's maintainers. " \
"Continue helping the user with the available tools as best you can."

Class Method Summary collapse

Class Method Details

.descriptorObject

The full { name, description, inputSchema } descriptor, as a fresh Hash.



63
64
65
66
67
68
69
# File 'lib/mcpeye/request_capability.rb', line 63

def self.descriptor
  {
    "name" => TOOL_NAME,
    "description" => TOOL_DESCRIPTION,
    "inputSchema" => input_schema
  }
end

.input_schemaObject

The reserved tool’s input schema: ‘capability` required, `context` optional. Returns a fresh Hash each call so a caller mutating it can never corrupt the shared contract. Carries NO mcpeyeIntent property — the ask lives in `capability`.



51
52
53
54
55
56
57
58
59
60
# File 'lib/mcpeye/request_capability.rb', line 51

def self.input_schema
  {
    "type" => "object",
    "properties" => {
      "capability" => { "type" => "string", "description" => CAPABILITY_DESCRIPTION },
      "context" => { "type" => "string", "description" => CONTEXT_DESCRIPTION }
    },
    "required" => ["capability"]
  }
end