{"schema_version":"flylab.webmcp-contracts.v3","name":"FlyLab WebMCP contracts","site":"https://flylab-neuroethology.d-lougen.chatgpt.site/","transport":{"api":"document.modelContext.registerTool","required_first_call":"inspect_flylab_state","scope":"current_open_page","context_contract":"flylab.agent-context.v3","result_contract":"flylab.tool-result.v3","provenance_manifest_contract":"flylab.provenance-manifest.v1","execution_note":"This document describes the live site tools but is not a fallback transport. Tool calls require a browser and workspace where WebMCP site tools are available."},"discovery":{"webmcp_standard_discovery":false,"catalog_kind":"FlyLab-specific read-only documentation","browser_documentation_url":"/agent","manifest_url":"/flylab-agent-manifest.json","contract_url":"/flylab-tool-contracts.json","evidence_export_schema_url":"https://flylab-neuroethology.d-lougen.chatgpt.site/schemas/flylab-evidence-export-v3.schema.json","evidence_export_media_type":"application/vnd.flylab.evidence+json","inline_state_selector":"#flylab-agent-context","inline_runtime_selector":"#flylab-agent-runtime","inline_handoff_selector":"#flylab-agent-handoff","control_plane_selector":"[aria-label=\"WebMCP agent control plane\"]","capability_diagnostic_path":"#flylab-agent-runtime / capability_diagnostic"},"result_contract":{"schema_version":"flylab.tool-result.v3","success_fields":["ok","result_version","tool","summary","page_session_id","previous_state_revision","state_revision","created_artifact_ids","operation_id","idempotent_replay","next_action","verification","provenance","provenance_scope","provenance_manifest","data"],"failure_fields":["ok","result_version","tool","page_session_id","state_revision","error","recovery"],"failure_error_fields":["code","message","retryable","details"],"domain_error_codes":["INVALID_INPUT","NOT_FOUND","EVIDENCE_MISMATCH","UNSUPPORTED_TARGET","INVALID_TIMING","STALE_STATE","APPROVAL_REQUIRED","RUN_LIMIT_EXCEEDED","SIMULATION_UNAVAILABLE","INCOMPLETE_BATCH","METRIC_UNAVAILABLE","INCOMPARABLE_ANALYSES","INCOMPLETE_PROVENANCE"],"cancellation":"A cancellation observed before commit rejects with AbortError and publishes no prepared batch or evidence bundle.","recovery":"After any interruption, cancellation, stale-state response, or visible person edit, call inspect_flylab_state before choosing another action."},"context_contract":{"schema_version":"flylab.agent-context.v3","artifact_manifest_field":"artifact_manifest","provenance_policy_field":"provenance_policy","recovery_semantics":"The artifact manifest carries compact, auditable scientific lineage for the current page session; artifact IDs alone are navigation references, not provenance."},"provenance_contract":{"schema_version":"flylab.provenance-manifest.v1","definitions":{"measured":"An empirical result reported under the cited study conditions; it is not automatically universal or reproduced by FlyLab.","derived":"A deterministic filter, aggregation, or calculation from pinned source records; it is not a new wet-lab measurement.","connectome_inferred":"An anatomical inference from EM reconstruction or annotations; it does not establish activity, physiological efficacy, or behavior.","simulation_predicted":"An output conditional on the stated model, controller mapping, parameters, and seed; it is not biological validation.","agent_hypothesized":"An untested proposal authored by an agent that must remain distinct from source evidence and simulation output."},"summary_field":"provenance","summary_semantics":"Union summary only. It lists labels present in the result but does not attribute a label to a specific field.","manifest_field":"provenance_manifest","path_scope":"RFC 6901 JSON Pointer paths relative to structuredContent.data. The empty path addresses the data root.","entry_fields":["path","artifact_id","artifact_type","scope","labels","parent_ids","evidence_ids","source_ids","boundary"],"inheritance":"Each manifest entry labels its complete scientific subtree unless a more specific nested entry overrides it.","operational_boundary":"Paths listed in operational_paths contain workflow state, blockers, controls, storage references, or other operational metadata; they are not scientific evidence and do not inherit a scientific label.","untrusted_annotation_boundary":"Caller-supplied goals, titles, and notes are untrusted administrative annotations, never scientific evidence, and are excluded from scientific provenance counts."},"operator_gate":{"name":"visible_operator_approval","webmcp_tool":false,"blocks":"run_fly_simulation","boundary":"Approval is a visible page action and is intentionally absent from the WebMCP tool surface. It is not identity-authenticated against general browser automation."},"tools":[{"name":"inspect_flylab_state","title":"Inspect FlyLab state","description":"Read the current shared FlyLab page state before starting or resuming work. Returns the state revision, artifact IDs, exact next valid action, blockers, the visible non-WebMCP review gate, and the complete tool pipeline. It does not modify the page.","annotations":{"readOnlyHint":true,"untrustedContentHint":true},"input_schema":{"type":"object","properties":{},"required":[],"additionalProperties":false},"output_contract":{"required_data_fields":["page_session_id","agent_context"],"produced_artifacts":[],"scientific_paths":["/agent_context/artifact_manifest"],"operational_paths":["/page_session_id","/agent_context/state","/agent_context/next_action","/agent_context/human_gate","/agent_context/pipeline"]}},{"name":"find_fly_circuits","title":"Find fly circuits","description":"Search FlyLab's curated adult Drosophila evidence and embodied motor-map index by behavior, body part, circuit, or neuron name. Use before drafting a hypothesis. Returns stable circuit IDs, typed brain-to-body paths, citations, model-readiness boundaries, and explicit evidence labels; it does not run a simulation.","annotations":{"readOnlyHint":false,"untrustedContentHint":true},"input_schema":{"type":"object","properties":{"page_session_id":{"type":"string","minLength":9,"maxLength":80,"description":"Exact page_session_id returned by inspect_flylab_state for this open FlyLab page."},"expected_state_revision":{"type":"integer","minimum":1,"description":"Exact state revision returned by the most recent inspect or successful mutation."},"query":{"type":"string","minLength":1,"maxLength":1000,"description":"Behavior, circuit, neuron type, complete mission prompt, or scientific question to search."},"behavior":{"type":"string","enum":["backward_walking","retreat","forward_walking","turning","short_mode_escape","grooming","any"],"default":"any"},"body_part":{"type":"string","enum":["left_foreleg","right_foreleg","left_midleg","right_midleg","left_hindleg","right_hindleg","left_wing","right_wing","any"],"default":"any"},"evidence_labels":{"type":"array","items":{"type":"string","enum":["measured","derived","connectome_inferred","simulation_predicted","agent_hypothesized"]},"minItems":1,"maxItems":5,"uniqueItems":true},"limit":{"type":"integer","minimum":1,"maximum":20,"default":8,"description":"Minimum top-k cutoff. Every candidate tied at the cutoff score is retained, so the returned candidate count may exceed this value."}},"required":["page_session_id","expected_state_revision","query"],"additionalProperties":false},"output_contract":{"required_data_fields":["discovery_decision","candidate_circuit_records","candidate_circuits","selection_status","disambiguation","circuits","evidence","connectome_records","dataset_versions","embodiment_coverage","selected_circuit_id","candidate_match_count","hypothesis_eligible_evidence_ids","causal_evidence_ids_by_perturbation","evidence_role_policy","coverage_warning","next_action"],"produced_artifacts":["discovery_decision","circuit_selection","evidence_record","connectome_record","embodied_motor_map"],"scientific_paths":["/discovery_decision","/candidate_circuit_records","/circuits","/evidence","/connectome_records","/dataset_versions","/embodiment_coverage"],"operational_paths":["/discovery_decision/missionGoal","/discovery_decision/search","/candidate_circuits","/selection_status","/disambiguation","/selected_circuit_id","/candidate_match_count","/hypothesis_eligible_evidence_ids","/causal_evidence_ids_by_perturbation","/evidence_role_policy","/coverage_warning","/next_action"]}},{"name":"draft_fly_hypothesis","title":"Draft fly hypothesis","description":"Create a visible, editable and falsifiable hypothesis from a selected circuit and discovered evidence. At least one cited role=hypothesis_support record must have kind=perturbation_effect matching the requested perturbation and behavior; structural, inventory, and motor-context records are supplemental only. Returns an agent_hypothesized record and does not run a simulation.","annotations":{"readOnlyHint":false,"untrustedContentHint":true},"input_schema":{"type":"object","properties":{"page_session_id":{"type":"string","minLength":9,"maxLength":80,"description":"Exact page_session_id returned by inspect_flylab_state for this open FlyLab page."},"expected_state_revision":{"type":"integer","minimum":1,"description":"Exact state revision returned by the most recent inspect or successful mutation."},"circuit_id":{"type":"string","minLength":1,"maxLength":100},"claim":{"type":"string","minLength":10,"maxLength":500},"predicted_behavior":{"type":"string","enum":["backward_walking","retreat","forward_walking","turning","short_mode_escape","grooming"]},"perturbation":{"type":"string","enum":["activate","silence"]},"primary_outcome":{"type":"string","enum":["backward_distance_mm","signed_speed_mm_s","response_latency_ms","heading_change_deg","stance_stability","short_mode_escape_probability","vertical_displacement_mm","wing_recruitment","leg_recruitment"],"description":"Stable simulation metric ID used as the hypothesis primary outcome."},"expected_direction":{"type":"string","enum":["increase","decrease"]},"controls":{"type":"array","items":{"type":"string","enum":["condition_baseline","condition_sham"]},"minItems":2,"maxItems":2,"uniqueItems":true,"description":"Must include the exact baseline and model-sham condition IDs."},"evidence_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"minItems":1,"maxItems":20,"uniqueItems":true,"description":"Discovered hypothesis-support IDs. Must include at least one perturbation_effect record matching perturbation and predicted_behavior; structural, inventory, and motor-context IDs may only supplement it."},"evidence_limitations":{"type":"array","items":{"type":"string","minLength":5,"maxLength":300},"minItems":1,"maxItems":10,"uniqueItems":true,"description":"Explicit limits on what the cited evidence and reduced-order model can establish."},"falsification_criterion":{"type":"string","minLength":5,"maxLength":300}},"required":["page_session_id","expected_state_revision","circuit_id","claim","predicted_behavior","perturbation","primary_outcome","expected_direction","controls","evidence_ids","evidence_limitations","falsification_criterion"],"additionalProperties":false},"output_contract":{"required_data_fields":["hypothesis","next_action"],"produced_artifacts":["hypothesis"],"scientific_paths":["/hypothesis"],"operational_paths":["/next_action"]}},{"name":"design_stimulation_trial","title":"Design stimulation trial","description":"Create and display a controlled adult-fly perturbation protocol for a saved hypothesis. Returns baseline, sham and perturbation conditions, visible effective-drive derivations, timing, seeds and model assumptions; operator approval is still required before execution.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"input_schema":{"type":"object","properties":{"page_session_id":{"type":"string","minLength":9,"maxLength":80,"description":"Exact page_session_id returned by inspect_flylab_state for this open FlyLab page."},"expected_state_revision":{"type":"integer","minimum":1,"description":"Exact state revision returned by the most recent inspect or successful mutation."},"hypothesis_id":{"type":"string","minLength":1,"maxLength":100},"target_circuit_id":{"type":"string","minLength":1,"maxLength":100},"perturbation":{"type":"string","enum":["activate","silence"]},"laterality":{"type":"string","enum":["bilateral","left","right"]},"activation_level":{"type":"number","minimum":0,"maximum":1,"description":"Unitless simulation control; not biological light power."},"onset_ms":{"type":"integer","minimum":0,"maximum":5000},"duration_ms":{"type":"integer","minimum":50,"maximum":5000},"trial_duration_ms":{"type":"integer","minimum":1000,"maximum":10000},"replicates":{"type":"integer","minimum":1,"maximum":20,"default":5},"include_baseline":{"type":"boolean","const":true,"default":true,"description":"Required for the controlled FlyLab vertical slice."},"include_sham_control":{"type":"boolean","const":true,"default":true,"description":"Required for the controlled FlyLab vertical slice."},"seed":{"type":"integer","minimum":0,"maximum":2147483647}},"required":["page_session_id","expected_state_revision","hypothesis_id","target_circuit_id","perturbation","laterality","activation_level","onset_ms","duration_ms","trial_duration_ms","replicates","include_baseline","include_sham_control","seed"],"additionalProperties":false},"output_contract":{"required_data_fields":["experiment","approval_required","agent_status","blocked_by","agent_actionable","human_gate","next_action"],"produced_artifacts":["experiment","trial_condition","embodied_motor_map"],"scientific_paths":["/experiment","/experiment/motorMap","/experiment/model","/experiment/model/controllerMapping"],"operational_paths":["/experiment/approved","/approval_required","/agent_status","/blocked_by","/agent_actionable","/human_gate","/next_action"]}},{"name":"run_fly_simulation","title":"Run fly simulation","description":"Execute one approved, bounded FlyLab experiment and make exact seeded runs replayable in the shared arena. The caller must echo the approved_protocol_hash from the visible operator gate; any protocol or seed-manifest change revokes authorization. Returns effective-drive derivations, state/event timelines, complete per-run trajectories, model/controller identities, legacy lineage hash, and SHA-256 content hash with field-level attribution.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"input_schema":{"type":"object","properties":{"page_session_id":{"type":"string","minLength":9,"maxLength":80,"description":"Exact page_session_id returned by inspect_flylab_state for this open FlyLab page."},"expected_state_revision":{"type":"integer","minimum":1,"description":"Exact state revision returned by the most recent inspect or successful mutation."},"experiment_id":{"type":"string","minLength":1,"maxLength":100},"approved_protocol_hash":{"type":"string","minLength":71,"maxLength":71,"pattern":"^sha256:[a-f0-9]{64}$","description":"Exact protocol hash returned after visible operator approval and exposed by inspect_flylab_state."},"operation_id":{"type":"string","minLength":1,"maxLength":120,"description":"Stable caller-generated ID for one logical simulation operation. Retry the same operation with the same ID."}},"required":["page_session_id","expected_state_revision","experiment_id","approved_protocol_hash","operation_id"],"additionalProperties":false},"output_contract":{"required_data_fields":["id","experimentId","targetCircuitId","behavior","motorMap","status","conditionRuns","runHash","runHashScope","runHashSerialization","runContentHash","runContentHashScope","runContentHashSerialization","protocol","approval","model","provenance","boundary","next_action"],"produced_artifacts":["simulation_batch","simulation_run","per_run_trajectory","illustrative_trajectory","experiment_approval","embodied_motor_map"],"scientific_paths":["","/motorMap","/conditionRuns","/protocol","/approval/protocol","/approval/seed_manifest","/model","/model/controllerMapping","/boundary"],"operational_paths":["/status","/approval/approved_at","/approval/protocol_hash","/approval/seed_manifest_hash","/next_action"]}},{"name":"analyze_fly_behavior","title":"Analyze fly behavior","description":"Compute and save the selected motor map's complete five-metric panel from summaries derived from each run's authoritative state trajectory. The required metric IDs are returned on the circuit motor map and simulation batch. The shared arena can replay the exact selected seeded run; a legacy condition illustration remains compatibility-only and excluded from analysis. Outputs are not wet-lab evidence.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"input_schema":{"type":"object","properties":{"page_session_id":{"type":"string","minLength":9,"maxLength":80,"description":"Exact page_session_id returned by inspect_flylab_state for this open FlyLab page."},"expected_state_revision":{"type":"integer","minimum":1,"description":"Exact state revision returned by the most recent inspect or successful mutation."},"batch_id":{"type":"string","minLength":1,"maxLength":100},"metrics":{"type":"array","items":{"type":"string","enum":["backward_distance_mm","signed_speed_mm_s","response_latency_ms","heading_change_deg","stance_stability","short_mode_escape_probability","vertical_displacement_mm","wing_recruitment","leg_recruitment"]},"minItems":5,"maxItems":5,"uniqueItems":true,"description":"The complete five-metric panel declared by the selected circuit motor map; partial or mixed panels are rejected."}},"required":["page_session_id","expected_state_revision","batch_id","metrics"],"additionalProperties":false},"output_contract":{"required_data_fields":["analysis","metric_definitions","response_initiation_summary_definition","response_observation_summary_definition","per_run_results","unit_boundary","next_action"],"produced_artifacts":["behavior_analysis","simulation_run_summary"],"scientific_paths":["/analysis","/metric_definitions","/response_initiation_summary_definition","/response_observation_summary_definition","/per_run_results","/unit_boundary"],"operational_paths":["/next_action"]}},{"name":"compare_fly_trials","title":"Compare fly trials","description":"Rank conditions from one or more saved analyses against a behavioral objective and create one bounded next-experiment proposal. It never executes the proposal automatically.","annotations":{"readOnlyHint":false,"untrustedContentHint":false},"input_schema":{"type":"object","properties":{"page_session_id":{"type":"string","minLength":9,"maxLength":80,"description":"Exact page_session_id returned by inspect_flylab_state for this open FlyLab page."},"expected_state_revision":{"type":"integer","minimum":1,"description":"Exact state revision returned by the most recent inspect or successful mutation."},"analysis_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"minItems":1,"maxItems":8,"uniqueItems":true},"objective_metric":{"type":"string","enum":["backward_distance_mm","signed_speed_mm_s","response_latency_ms","heading_change_deg","stance_stability","short_mode_escape_probability","vertical_displacement_mm","wing_recruitment","leg_recruitment"]},"objective":{"type":"string","enum":["maximize","minimize"]}},"required":["page_session_id","expected_state_revision","analysis_ids","objective_metric","objective"],"additionalProperties":false},"output_contract":{"required_data_fields":["comparison","execution_authorized","next_action"],"produced_artifacts":["trial_comparison","follow_up_proposal"],"scientific_paths":["/comparison","/comparison/proposal"],"operational_paths":["/execution_authorized","/next_action"]}},{"name":"save_fly_evidence","title":"Save fly evidence","description":"Commit a complete FlyLab hypothesis, experiment, runs, analyses, comparison, citations, model versions and seeds to the visible browser-local evidence ledger. Verifies the simulation content hash and returns stable bundle metadata, the exact portable evidence-export envelope, its manifest hash, media type, and published JSON Schema URL.","annotations":{"readOnlyHint":false,"untrustedContentHint":true},"input_schema":{"type":"object","properties":{"page_session_id":{"type":"string","minLength":9,"maxLength":80,"description":"Exact page_session_id returned by inspect_flylab_state for this open FlyLab page."},"expected_state_revision":{"type":"integer","minimum":1,"description":"Exact state revision returned by the most recent inspect or successful mutation."},"scope":{"type":"string","enum":["experiment","mission"],"description":"experiment saves the exact selected lineage; mission additionally preserves the goal, discovery decision, alternatives, exclusions, and coverage gaps."},"title":{"type":"string","minLength":1,"maxLength":120,"description":"Optional caller-entered administrative title. Omit it to use FlyLab system metadata; it is never scientific evidence."},"hypothesis_id":{"type":"string","minLength":1,"maxLength":100},"experiment_id":{"type":"string","minLength":1,"maxLength":100},"batch_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"minItems":1,"maxItems":1,"uniqueItems":true},"analysis_ids":{"type":"array","items":{"type":"string","minLength":1,"maxLength":100},"minItems":1,"maxItems":8,"uniqueItems":true},"comparison_id":{"type":"string","minLength":1,"maxLength":100},"note":{"type":"string","maxLength":500},"operation_id":{"type":"string","minLength":1,"maxLength":120,"description":"Stable caller-generated ID for one logical evidence-save operation. Retry the same operation with the same ID."}},"required":["page_session_id","expected_state_revision","scope","hypothesis_id","experiment_id","batch_ids","analysis_ids","comparison_id","operation_id"],"additionalProperties":false},"output_contract":{"required_data_fields":["bundle","evidence_export","export_media_type","export_schema_url","export_filename","local_reference","storage_scope","next_action"],"produced_artifacts":["evidence_bundle","portable_evidence_export"],"scientific_paths":["/bundle","/evidence_export"],"operational_paths":["/export_media_type","/export_schema_url","/export_filename","/local_reference","/storage_scope","/next_action"]}}]}