Aihydro Tools — the complete, unedited output of the deterministic mcptrustchecker engine v1.9.0, scanned . Every finding, capability tag and score component below is exactly what the engine produced — no AI, no post-processing.
{
"tool": {
"name": "mcptrustchecker",
"version": "1.9.0",
"methodologyVersion": "mcptrustchecker-1.9"
},
"target": {
"id": "aihydro-tools",
"source": {
"kind": "package",
"origin": "aihydro-tools"
},
"server": {
"name": "aihydro-tools"
}
},
"grade": "B",
"score": {
"score": 89,
"threatScore": 100,
"grade": "B",
"band": "B",
"categorySubtotals": {
"injection": 0,
"exfiltration": 0,
"permissions": 0,
"supply-chain": 0,
"network": 0,
"hygiene": 0
},
"vector": [
{
"kind": "client",
"term": "capability-exposure",
"level": "critical",
"label": "capability blast radius (critical) — client exposure if the model is manipulated",
"appliedPenalty": 10
},
{
"kind": "client",
"term": "verification-discount",
"level": "repo",
"label": "publisher verification (public source) — no provenance, but the source is public and inspectable",
"appliedPenalty": 1
},
{
"kind": "client",
"term": "coverage-honesty",
"level": "source",
"label": "inspection depth (source) — how much of the target the scan could see",
"appliedPenalty": 0
}
],
"gatesFired": [],
"methodologyVersion": "mcptrustchecker-1.9"
},
"capability": {
"level": "critical",
"reasons": [
"ingests untrusted external content (a prompt-injection entry point)",
"can send data / act on an external service",
"reads sensitive or local data",
"has a read → egress path (a data-exfiltration surface)",
"can execute shell commands or code",
"untrusted-input, sensitive-source and egress co-exist across tools (toxic-flow surface)",
"untrusted input can reach code execution"
],
"tags": [
"untrusted-input",
"external-sink",
"sensitive-source",
"code-exec"
]
},
"coverage": {
"level": "source",
"inputs": {
"toolSurface": true,
"implementationSource": true,
"packageMetadata": true,
"liveTransport": false
},
"caveats": [
"Tools were statically extracted from the published source (147 recovered), not enumerated from a running server. Tool-poisoning, Unicode-smuggling, capability and toxic-flow analysis ran on this inferred surface, but a mis-parsed registration could be missed or mis-attributed, so tool-derived findings are capped below “confirmed”. To grade the real runtime surface, scan the running server: --command \"npx -y <package>\"."
]
},
"findings": [
{
"ruleId": "MTC-FLOW-002",
"title": "Completed toxic-flow trifecta across tools",
"category": "exfiltration",
"severity": "critical",
"confidence": "strong",
"description": "This server (without client built-ins) exposes a complete data-exfiltration chain: check_record_length → list_available_tools → preview_list_modules. Untrusted input is ingested, private data is read, and it can be sent to an external sink via the agent composing the tools (→). Static analysis proves the primitive exists, not that a specific run will occur.",
"remediation": "Remove one leg of the trifecta: isolate untrusted-input tools from secret-reading tools and from egress tools, or require human approval between them.",
"location": {
"kind": "flow",
"name": "check_record_length → list_available_tools → preview_list_modules"
},
"owasp": "LLM02:2025 Sensitive Information Disclosure",
"references": [],
"data": {
"untrusted": [
"fetch_streamflow_data",
"fetch_forcing_data",
"fetch_camels_us",
"compute_flow_duration_curve",
"data_fetch_background",
"get_data_fetch_result",
"describe_tool",
"describe_tools",
"check_record_length",
"check_usgs_qualification_codes"
],
"sources": [
"list_available_tools"
],
"sinks": [
"preview_list_modules"
],
"path": [
"check_record_length",
"list_available_tools",
"preview_list_modules"
],
"edges": [
{
"from": "check_record_length",
"to": "list_available_tools",
"kind": "agent-mediated"
},
{
"from": "list_available_tools",
"to": "preview_list_modules",
"kind": "agent-mediated"
}
],
"wired": false
}
},
{
"ruleId": "MTC-SRC-002",
"title": "Shell/command execution in server code (ai_hydro/gee/auth.py)",
"category": "permissions",
"severity": "high",
"confidence": "strong",
"description": "In the server's implementation (`ai_hydro/gee/auth.py:84`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.",
"remediation": "Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.",
"location": {
"kind": "server",
"name": "ai_hydro/gee/auth.py"
},
"evidence": "try: proc = subprocess.run( [\"gcloud\", \"projects\", \"list\", \"--format=json(projectId,name,project",
"owasp": "LLM05:2025 Improper Output Handling",
"data": {
"rule": "MTC-SRC-002",
"file": "ai_hydro/gee/auth.py",
"line": 84,
"nonRuntime": false
}
},
{
"ruleId": "MTC-SRC-002",
"title": "Shell/command execution in server code (ai_hydro/mcp/tools_execution.py)",
"category": "permissions",
"severity": "high",
"confidence": "strong",
"description": "In the server's implementation (`ai_hydro/mcp/tools_execution.py:90`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.",
"remediation": "Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.",
"location": {
"kind": "server",
"name": "ai_hydro/mcp/tools_execution.py"
},
"evidence": "onic() result = subprocess.run( [sys.executable, \"-\"], input=full_script, ca",
"owasp": "LLM05:2025 Improper Output Handling",
"data": {
"rule": "MTC-SRC-002",
"file": "ai_hydro/mcp/tools_execution.py",
"line": 90,
"nonRuntime": false
}
},
{
"ruleId": "MTC-SRC-002",
"title": "Shell/command execution in server code (ai_hydro/mcp/tools_session.py)",
"category": "permissions",
"severity": "high",
"confidence": "strong",
"description": "In the server's implementation (`ai_hydro/mcp/tools_session.py:56`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.",
"remediation": "Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.",
"location": {
"kind": "server",
"name": "ai_hydro/mcp/tools_session.py"
},
"evidence": "p. result = subprocess.run( [sys.executable, \"-m\", \"pip\", \"list\", \"--format=json\"],",
"owasp": "LLM05:2025 Improper Output Handling",
"data": {
"rule": "MTC-SRC-002",
"file": "ai_hydro/mcp/tools_session.py",
"line": 56,
"nonRuntime": false
}
},
{
"ruleId": "MTC-SRC-003",
"title": "Hardcoded egress to an external endpoint (ai_hydro/gee/auth.py)",
"category": "exfiltration",
"severity": "medium",
"confidence": "strong",
"description": "In the server's implementation (`ai_hydro/gee/auth.py:131`): A hardcoded outbound call to a fixed external host inside server code is a classic exfiltration/telemetry channel — especially paired with reads of local data. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.",
"remediation": "Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.",
"location": {
"kind": "server",
"name": "ai_hydro/gee/auth.py"
},
"evidence": "t()) response = requests.get( \"https://cloudresourcemanager.googleapis.com/v1/projects\",",
"owasp": "LLM02:2025 Sensitive Information Disclosure",
"data": {
"rule": "MTC-SRC-003",
"file": "ai_hydro/gee/auth.py",
"line": 131,
"nonRuntime": false
}
},
{
"ruleId": "MTC-SRC-002",
"title": "Shell/command execution in packaging/dev tooling (bench/gen_scorecard.py)",
"category": "permissions",
"severity": "low",
"confidence": "heuristic",
"description": "In a packaging/dev/install script (shipped, but not the server runtime) (`bench/gen_scorecard.py:99`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.",
"remediation": "Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.",
"location": {
"kind": "server",
"name": "bench/gen_scorecard.py"
},
"evidence": "lush=True) result = subprocess.run(cmd, capture_output=False) print(f\"Exit code: {result.returncode}\", flush=Tru",
"owasp": "LLM05:2025 Improper Output Handling",
"data": {
"rule": "MTC-SRC-002",
"file": "bench/gen_scorecard.py",
"line": 99,
"nonRuntime": true
}
},
{
"ruleId": "MTC-SRC-002",
"title": "Shell/command execution in packaging/dev tooling (tests/test_capsule.py)",
"category": "permissions",
"severity": "low",
"confidence": "heuristic",
"description": "In a packaging/dev/install script (shipped, but not the server runtime) (`tests/test_capsule.py:448`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.",
"remediation": "Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.",
"location": {
"kind": "server",
"name": "tests/test_capsule.py"
},
"evidence": "eypatch) proc = subprocess.run( [sys.executable, str(cap / \"replay.py\")], capture_output",
"owasp": "LLM05:2025 Improper Output Handling",
"data": {
"rule": "MTC-SRC-002",
"file": "tests/test_capsule.py",
"line": 448,
"nonRuntime": true
}
}
],
"toxicFlows": [
{
"id": "flow-1",
"severity": "critical",
"confidence": "strong",
"untrustedInput": [
"fetch_streamflow_data",
"fetch_forcing_data",
"fetch_camels_us",
"compute_flow_duration_curve",
"data_fetch_background",
"get_data_fetch_result",
"describe_tool",
"describe_tools",
"check_record_length",
"check_usgs_qualification_codes"
],
"sensitiveSource": [
"list_available_tools"
],
"externalSink": [
"preview_list_modules"
],
"selfContained": false,
"path": [
"check_record_length",
"list_available_tools",
"preview_list_modules"
],
"pathWired": false,
"description": "A cross-tool exfiltration chain exists: check_record_length → list_available_tools → preview_list_modules."
}
],
"capabilities": [
{
"tool": "delineate_watershed",
"tags": [],
"reasons": {}
},
{
"tool": "merit_ensure_basin",
"tags": [],
"reasons": {}
},
{
"tool": "merit_ensure_routing_region",
"tags": [],
"reasons": {}
},
{
"tool": "merit_ensure_basins_region",
"tags": [],
"reasons": {}
},
{
"tool": "delineation_doctor",
"tags": [],
"reasons": {}
},
{
"tool": "merit_ensure_region",
"tags": [],
"reasons": {}
},
{
"tool": "merit_add_map_layers",
"tags": [],
"reasons": {}
},
{
"tool": "delineate_watershed_from_point",
"tags": [],
"reasons": {}
},
{
"tool": "fetch_streamflow_data",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "extract_hydrological_signatures",
"tags": [],
"reasons": {}
},
{
"tool": "extract_geomorphic_parameters",
"tags": [],
"reasons": {}
},
{
"tool": "compute_twi",
"tags": [],
"reasons": {}
},
{
"tool": "map_flood_inundation",
"tags": [],
"reasons": {}
},
{
"tool": "map_flood_inundation_hydrograph",
"tags": [],
"reasons": {}
},
{
"tool": "create_cn_grid",
"tags": [],
"reasons": {}
},
{
"tool": "fetch_forcing_data",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "fetch_camels_us",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "separate_baseflow",
"tags": [],
"reasons": {}
},
{
"tool": "compute_flow_duration_curve",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "compute_flood_frequency",
"tags": [],
"reasons": {}
},
{
"tool": "compute_drought_index",
"tags": [],
"reasons": {}
},
{
"tool": "compute_soil_loss_rusle",
"tags": [],
"reasons": {}
},
{
"tool": "compute_design_hydrograph",
"tags": [],
"reasons": {}
},
{
"tool": "get_library_reference",
"tags": [],
"reasons": {}
},
{
"tool": "show_on_map",
"tags": [],
"reasons": {}
},
{
"tool": "show_html_preview",
"tags": [],
"reasons": {}
},
{
"tool": "audit_interpretation",
"tags": [],
"reasons": {}
},
{
"tool": "lookup_citation",
"tags": [],
"reasons": {}
},
{
"tool": "get_citation_by_doi",
"tags": [],
"reasons": {}
},
{
"tool": "list_cached_citations",
"tags": [],
"reasons": {}
},
{
"tool": "course_get_state",
"tags": [],
"reasons": {}
},
{
"tool": "course_get_curriculum",
"tags": [],
"reasons": {}
},
{
"tool": "course_set_progress",
"tags": [],
"reasons": {}
},
{
"tool": "course_navigate",
"tags": [],
"reasons": {}
},
{
"tool": "course_scaffold",
"tags": [],
"reasons": {}
},
{
"tool": "data_fetch_background",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "get_data_fetch_result",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "aihydro_describe_capability",
"tags": [],
"reasons": {}
},
{
"tool": "describe_tool",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "describe_tools",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "run_python",
"tags": [],
"reasons": {}
},
{
"tool": "list_relevant_clis",
"tags": [],
"reasons": {}
},
{
"tool": "define_experiment",
"tags": [],
"reasons": {}
},
{
"tool": "run_experiment",
"tags": [],
"reasons": {}
},
{
"tool": "get_experiment_table",
"tags": [],
"reasons": {}
},
{
"tool": "gee.status",
"tags": [],
"reasons": {}
},
{
"tool": "gee.preview_layer",
"tags": [],
"reasons": {}
},
{
"tool": "gee.extract_timeseries",
"tags": [],
"reasons": {}
},
{
"tool": "compute_spectral_index",
"tags": [],
"reasons": {}
},
{
"tool": "list_spectral_indices",
"tags": [],
"reasons": {}
},
{
"tool": "run_inundation_physics_validation",
"tags": [],
"reasons": {}
},
{
"tool": "get_inundation_physics_result",
"tags": [],
"reasons": {}
},
{
"tool": "export_inundation_surrogate_dataset",
"tags": [],
"reasons": {}
},
{
"tool": "train_inundation_surrogate",
"tags": [],
"reasons": {}
},
{
"tool": "get_inundation_surrogate_result",
"tags": [],
"reasons": {}
},
{
"tool": "get_variable_definition",
"tags": [],
"reasons": {}
},
{
"tool": "list_known_variables",
"tags": [],
"reasons": {}
},
{
"tool": "get_metric_definition",
"tags": [],
"reasons": {}
},
{
"tool": "list_known_metrics",
"tags": [],
"reasons": {}
},
{
"tool": "get_dataset_info",
"tags": [],
"reasons": {}
},
{
"tool": "list_known_datasets",
"tags": [],
"reasons": {}
},
{
"tool": "get_equation_definition",
"tags": [],
"reasons": {}
},
{
"tool": "index_passages",
"tags": [],
"reasons": {}
},
{
"tool": "search_passages_tool",
"tags": [],
"reasons": {}
},
{
"tool": "resolve_passage",
"tags": [],
"reasons": {}
},
{
"tool": "add_claim",
"tags": [],
"reasons": {}
},
{
"tool": "update_claim_status",
"tags": [],
"reasons": {}
},
{
"tool": "add_assumption",
"tags": [],
"reasons": {}
},
{
"tool": "list_claims",
"tags": [],
"reasons": {}
},
{
"tool": "list_assumptions",
"tags": [],
"reasons": {}
},
{
"tool": "promote_claim_to_registry",
"tags": [],
"reasons": {}
},
{
"tool": "check_registry_staleness",
"tags": [],
"reasons": {}
},
{
"tool": "list_registry_claims",
"tags": [],
"reasons": {}
},
{
"tool": "draft_claim_from_run",
"tags": [],
"reasons": {}
},
{
"tool": "register_research_plan",
"tags": [],
"reasons": {}
},
{
"tool": "map_get_state",
"tags": [],
"reasons": {}
},
{
"tool": "map_set_roi",
"tags": [],
"reasons": {}
},
{
"tool": "map_show",
"tags": [],
"reasons": {}
},
{
"tool": "map_set_working_geometry",
"tags": [],
"reasons": {}
},
{
"tool": "map_fit_extent",
"tags": [],
"reasons": {}
},
{
"tool": "map_list_layers",
"tags": [],
"reasons": {}
},
{
"tool": "map_update_layer",
"tags": [],
"reasons": {}
},
{
"tool": "map_apply_symbology",
"tags": [],
"reasons": {}
},
{
"tool": "map_remove_layer",
"tags": [],
"reasons": {}
},
{
"tool": "map_set_basemap",
"tags": [],
"reasons": {}
},
{
"tool": "map_fit_layer",
"tags": [],
"reasons": {}
},
{
"tool": "map_fly_to",
"tags": [],
"reasons": {}
},
{
"tool": "map_add_layer_from_run",
"tags": [],
"reasons": {}
},
{
"tool": "map_set_time_range",
"tags": [],
"reasons": {}
},
{
"tool": "map_save_roi",
"tags": [],
"reasons": {}
},
{
"tool": "train_hydro_model",
"tags": [],
"reasons": {}
},
{
"tool": "get_training_status",
"tags": [],
"reasons": {}
},
{
"tool": "cancel_job",
"tags": [],
"reasons": {}
},
{
"tool": "list_jobs",
"tags": [],
"reasons": {}
},
{
"tool": "wait_for_job",
"tags": [],
"reasons": {}
},
{
"tool": "describe_model_space",
"tags": [],
"reasons": {}
},
{
"tool": "propose_and_train",
"tags": [],
"reasons": {}
},
{
"tool": "run_autoresearch",
"tags": [],
"reasons": {}
},
{
"tool": "get_leaderboard",
"tags": [],
"reasons": {}
},
{
"tool": "get_model_results",
"tags": [],
"reasons": {}
},
{
"tool": "preview_get_state",
"tags": [],
"reasons": {}
},
{
"tool": "preview_recent_events",
"tags": [],
"reasons": {}
},
{
"tool": "preview_list_modules",
"tags": [
"external-sink"
],
"reasons": {
"external-sink": [
"keyword \"open_pr\""
]
}
},
{
"tool": "preview_focus_cell",
"tags": [],
"reasons": {}
},
{
"tool": "preview_revise_section",
"tags": [],
"reasons": {}
},
{
"tool": "preview_address_comment",
"tags": [],
"reasons": {}
},
{
"tool": "preview_get_pending_changes",
"tags": [],
"reasons": {}
},
{
"tool": "start_project",
"tags": [],
"reasons": {}
},
{
"tool": "get_project_summary",
"tags": [],
"reasons": {}
},
{
"tool": "add_session_to_project",
"tags": [],
"reasons": {}
},
{
"tool": "search_experiments",
"tags": [],
"reasons": {}
},
{
"tool": "index_literature",
"tags": [],
"reasons": {}
},
{
"tool": "search_literature",
"tags": [],
"reasons": {}
},
{
"tool": "add_journal_entry",
"tags": [],
"reasons": {}
},
{
"tool": "get_researcher_profile",
"tags": [],
"reasons": {}
},
{
"tool": "update_researcher_profile",
"tags": [],
"reasons": {}
},
{
"tool": "log_researcher_observation",
"tags": [],
"reasons": {}
},
{
"tool": "start_session",
"tags": [],
"reasons": {}
},
{
"tool": "get_session_summary",
"tags": [],
"reasons": {}
},
{
"tool": "get_session_health",
"tags": [],
"reasons": {}
},
{
"tool": "clear_session",
"tags": [],
"reasons": {}
},
{
"tool": "add_note",
"tags": [],
"reasons": {}
},
{
"tool": "archive_session",
"tags": [],
"reasons": {}
},
{
"tool": "get_session_raw_state",
"tags": [],
"reasons": {}
},
{
"tool": "merge_session_shards",
"tags": [],
"reasons": {}
},
{
"tool": "write_research_interpretation",
"tags": [],
"reasons": {}
},
{
"tool": "list_available_tools",
"tags": [
"sensitive-source"
],
"reasons": {
"sensitive-source": [
"keyword \"dump\""
]
}
},
{
"tool": "export_session",
"tags": [],
"reasons": {}
},
{
"tool": "aihydro_rebind_chat",
"tags": [],
"reasons": {}
},
{
"tool": "aihydro_chat_status",
"tags": [],
"reasons": {}
},
{
"tool": "register_feature",
"tags": [],
"reasons": {}
},
{
"tool": "list_features",
"tags": [],
"reasons": {}
},
{
"tool": "set_active_feature",
"tags": [],
"reasons": {}
},
{
"tool": "bind_map_to_claim",
"tags": [],
"reasons": {}
},
{
"tool": "run_skeptic",
"tags": [],
"reasons": {}
},
{
"tool": "list_skills",
"tags": [],
"reasons": {}
},
{
"tool": "load_skill",
"tags": [],
"reasons": {}
},
{
"tool": "save_skill",
"tags": [],
"reasons": {}
},
{
"tool": "check_water_balance_consistency",
"tags": [],
"reasons": {}
},
{
"tool": "check_temporal_alignment",
"tags": [],
"reasons": {}
},
{
"tool": "check_unit_consistency",
"tags": [],
"reasons": {}
},
{
"tool": "check_record_length",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "check_usgs_qualification_codes",
"tags": [
"untrusted-input"
],
"reasons": {
"untrusted-input": [
"keyword \"fetch\""
]
}
},
{
"tool": "check_regulated_basin",
"tags": [],
"reasons": {}
},
{
"tool": "check_stationarity",
"tags": [],
"reasons": {}
},
{
"tool": "list_available_workflows",
"tags": [],
"reasons": {}
},
{
"tool": "get_workflow_manifest",
"tags": [],
"reasons": {}
}
],
"surfaceDigest": "9f1b1bc8a982111e0103c36b211f470320d09bc11ebf23d0b472a3f71789dc41",
"stats": {
"tools": 147,
"prompts": 0,
"resources": 0,
"findingsBySeverity": {
"critical": 1,
"high": 3,
"medium": 1,
"low": 2,
"info": 0
}
}
}