Expand description
[[tools]] → ToolInfo + Arc<dyn ToolHandler> synthesizer.
Net-new code for Phase 83 TKIT-07. Turns curated [[tools]] config entries
into complete pmcp ToolInfo + Arc<dyn ToolHandler> pairs with zero
per-tool Rust handlers.
§Invariants enforced
-
JSON Schema object envelope, CHECKED HERE. Every synthesized
ToolInfocarries aninput_schemawith"type": "object", an explicitpropertiesmap, arequiredarray, and"additionalProperties": false(trueonly when[server.validation] additional_propertiesopts out). Unknown argument keys are refused bypmcp::server::schema_validation::validate_input, called from theValidatingToolHandlerdecorator thatenforce_input_schemawraps around every handler this module pushes — in the toolkit, before the backend call. Threat T-83-05-02.Both halves matter, and stating only the first is what made this comment a defect for two phases. Core
pmcp’stools/calldispatch does not validate request arguments against a tool’s declaredinputSchema; that wiring is deliberately deferred (Phase 128 D-01), so a comment locating the enforcement “upstream” described a mitigation that did not exist. It exists now, and it exists here.Condition: the
input-validationfeature must be on. It is on via this crate’sdefaultfeature set and by that route ALONE — measured:http = ["dep:reqwest", "dep:url", "dep:openapiv3", "dep:serde_yaml", "dep:base64", "dep:regex", "dep:tokio", "pmcp/streamable-http"]andopenapi-code-mode = ["http", "code-mode", "pmcp-code-mode/js-runtime"], neither of which names it. Those two umbrellas do NOT forward it, so a--no-default-features --features httpbuild — exactly the shape a consumer reaches for — turns it off, and thenenforce_input_schemais the identity function and says so in atracing::warn!. Second condition:[server.validation] enforce_input_schemamust not befalse.Backed by
tests/input_validation_acceptance.rs’sinput_validation_refuses_undeclared_argument_without_contacting_upstream(row 10) andinput_validation_refuses_absent_arguments_when_required_declared(row 9), each of which fails if thevalidate_inputcall is removed, plusinput_validation_accepts_compliant_call_with_one_upstream_request(row 11) as the passing control that catches an over-refusing decorator. -
handler.metadata()returnsSome(ToolInfo). Phase 82’stool_arcconsumeshandler.metadata()at registration; returningNonewould silently degrade the schema enforcement to “anything goes” (RESEARCH §Risks #2 — threat T-83-05-01). -
Constructors, never struct-literals. Both
ToolInfoandToolAnnotationsare#[non_exhaustive](PATTERNS §Pattern C). The synthesizer usesToolInfo::with_annotations/ToolInfo::newand theToolAnnotations::new()-then-.with_*fluent builder. -
Cognitive complexity ≤25 per function. Decomposed into [
build_input_schema], [build_param_property], and [build_annotations] per Phase 75 D-03 + PATTERNS §Pattern G. No#[allow]annotations.
Functions§
- synthesize_
from_ config - Synthesize one
ToolInfo+ handler per[[tools]]config entry. - synthesize_
from_ config_ and_ hooks synthesize_from_configwith registered E2 hooks (Phase 128).- synthesize_
from_ config_ with_ connector - Synthesize tools that execute against a wired
SqlConnector(Phase 84 CONN-01 / D-06). ADDITIVE variant alongsidesynthesize_from_config— the existing API is unchanged and all P83 callers compile without modification. - synthesize_
from_ config_ with_ connector_ and_ hooks synthesize_from_config_with_connectorwith registered E2 hooks (Phase 128).- synthesize_
from_ config_ with_ http_ connector - Synthesize one
ToolInfo+ handler per single-call[[tools]]entry, executing against a wiredHttpConnector(Phase 90 OAPI-02a / D-01). - synthesize_
from_ config_ with_ http_ connector_ and_ hooks synthesize_from_config_with_http_connectorwith registered E2 hooks (Phase 128).- synthesize_
from_ config_ with_ http_ connector_ and_ scripts - Synthesize single-call AND script
[[tools]]against a wiredHttpConnectorplus a sharedHttpCodeExecutor+ExecutionConfig(Phase 90 OAPI-02b / D-01 / D-02). - synthesize_
from_ config_ with_ http_ connector_ and_ scripts_ and_ hooks synthesize_from_config_with_http_connector_and_scriptswith registered E2 hooks (Phase 128).
Type Aliases§
- Synthesized
Tool - Type alias for one synthesized tool tuple:
(name, ToolInfo, Arc<dyn ToolHandler>).