MCP Research Contract (Hyperagent Pack)
This document defines additive MCP tool contracts intended for self-improving research loops.
MCP Research Contract (Hyperagent Pack)
This document defines additive MCP tool contracts intended for self-improving research loops.
Stability note (v1.5.0 release line)
The following fields are considered stable in the v1.2.7+ research pack surface (current RUNTIME_VERSION 1.5.0):
ainl_validate(...).diagnostics[].llm_repair_hintainl_ir_diff(...).diff.changed_nodes[]as a list of{label_id, node_id, changes}ainl_fitness_report(...).metrics.fitness_scoreainl_fitness_report(...).metrics.fitness_components.weightsainl_compile(...).frame_hints[]as a list of{name, type, source}— added v1.4.3 (present only whenok: true)
Future versions may add fields but should not remove or rename these without a versioned migration note.
Tools
-
ainl_validate(code, strict=True)- Returns:
ok,errors,warnings,diagnostics[] - Contract: each diagnostic includes
llm_repair_hint.
- Returns:
-
ainl_compile(code, strict=True)- Returns:
ok,ir,frame_hints[] frame_hintsis a list of{"name": str, "type": str, "source": "comment"|"inferred"}entries describing variables the caller should supply viaframewhen callingainl_run. Authoritative entries come from# frame: name: type(or# frame: name, which setstypeto"any") comment lines in source; additional heuristic entries are inferred from IR variables referenced but never assigned. Best-effort — may include false positives for inferred entries.- Workflow: call
ainl_compilefirst to discoverframe_hints, then construct theframedict and callainl_run.
- Returns:
-
ainl_ir_diff(file1, file2, strict=True)- Returns:
ok,diff diffkeys:added_nodes,removed_nodes,changed_nodes,added_edges,removed_edges,rewired_edges,human_summary.- Contract:
changed_nodesincludes payload-leveldatadeltas when node op shape is unchanged but node data changed.
- Returns:
-
ainl_fitness_report(file, runs=5, strict=True)- Returns:
ok,metrics,sample_runs,last_error metricskeys:latency_ms,step_count,adapter_callsmemory_deltas(trace-derived frame-key proxy)operation_histogramtoken_use_estimatereliability_scorefitness_scorein[0,1]fitness_componentswith explicit component values andweights
- Returns:
Scoring stability guidance
- Treat
fitness_components.weightsas the live source of truth. - Consumers should not hard-code weight constants without checking the payload.
- Rank by
fitness_score; use component breakdown for tie-breaks and debugging.
ainl_run execution contract (v1.4.3+; current package 1.5.0)
Variable shadowing in R arguments
String literals in R arg positions (e.g. "records") are compiled without quotes and resolved against the live frame before being treated as literals. If a frame variable named records exists, R core.GET data "records" will pass the list, not the string. Prevention: use unique variable name prefixes per label scope.
Per-workspace limit overrides
Place ainl_mcp_limits.json at <fs.root>/ainl_mcp_limits.json to adjust limits for that workspace without modifying global server config:
{"max_steps": 500000, "max_time_ms": 900000, "max_adapter_calls": 50000}
The server default ceiling still wins via restrictive merge — this file can only tighten or match defaults, not exceed the server ceiling.
If ainl_mcp_limits.json is present but cannot be parsed as JSON, limits fall back to server defaults and a successful ainl_run may include warnings (string list) explaining that the file was ignored.
max_adapter_calls: A value of 0 is a real ceiling (no adapter calls). Positive integers cap total adapter dispatches (R lines, cache/queue helpers, etc.).
Auto-registered cache adapter
When the fs adapter is enabled in ainl_run and no cache adapter is explicitly listed in adapters.enable, the MCP server will automatically register the cache adapter if any of these files exist:
<fs.root>/output/cache.json<fs.root>/cache.json
This makes per-workspace caching zero-config for scripts that already have a cache file. Explicit "cache" in adapters.enable always takes precedence.
Before registration, a non-empty candidate file must contain valid JSON; otherwise ainl_run returns {"ok": false, "error": "adapter_config_error", "details": "…"}. An empty file (0 bytes) is skipped by the pre-check and handled by the adapter as an empty object store.
Interaction with RuntimeEngine: graphs that reference cache may still get a default file-backed cache adapter from the engine when no MCP-scoped adapter was registered — that default uses AINL_CACHE_JSON / MONITOR_CACHE_JSON / ~/.openclaw/ainl_cache.json. To prove the workspace path in tests, isolate HOME and seed only <fs.root>/…/cache.json.
frame declaration convention
Document expected frame variables in source using comment lines:
# frame: search_body: dict
# frame: req_headers: dict
S app core noop
...
These are picked up by ainl_compile and returned in frame_hints so agents can auto-construct the frame argument before calling ainl_run.
Authoring wizard, strict-valid family index, and contract alignment (v1.7.x)
The MCP server also ships:
ainl_get_started— passwizard_state_jsonto continue a wizard session; returns checkpoints andwizard_statefor hosts that persist digests to graph memory.ainl_step_examples— strict-valid snippets and optional corpus paths by topic, without advancing wizard state; includesschema_versionin the response.ainl://strict-valid-families— JSON mined intocorpus/strict_valid_family_index.json(regenerate withtooling/corpus_mining.py).- On successful
ainl_validate/ainl_compile:contract_validation_statusandcontract_alignment, withmismatched_callslisting adapter/verb rows that do not match the get-startedADAPTER_CONTRACTSbundle (non-fatal warnings; see source for exact schema).
Full reference: MCP_AINL_WIZARD_AND_CORPUS.md. ArmaraOS prompt and graph tags: armaraos/docs/mcp-a2a.md.