Docs · Connect your AI
Results, errors, and access
Read the exact response shape, tell measured facts from inference, recover from refusal safely, and negotiate Noru contract 4 without confusing it with the MCP protocol.
Tool result shape
Every successful MCP tools/call response wraps a result with content,isError: false, and contract metadata. A capture that resolves also adds structuredContent. Locator rows and recovery guidance are text-only and do not add that sibling.
{
"content": [
{"type":"text","text":"Noru capture capture_2026-08-12_141502 (...)"},
{"type":"image","data":"<base64 PNG>","mimeType":"image/png"}
],
"structuredContent": {
"id": "capture_2026-08-12_141502",
"uri": "noru-capture://capture_2026-08-12_141502",
"captured_at": "2026-08-12T18:15:02Z",
"ocr_pending": false,
"images": [
{
"served_width": 1568,
"served_height": 980,
"downscaled_from": [2560, 1600]
}
],
"sources": [
{
"display_index": 1,
"display_name": "Built-in Retina Display",
"app_id": "com.example.Editor",
"app_name": "Editor",
"window_title": "Project - Editor",
"workspace_hint": "Project"
}
]
},
"isError": false,
"_meta": {"noru.contract": 4}
}The example values are illustrative. Fields are populated from the resolved capture; unknown source facts remain null or are omitted by the stored data, never guessed.
text_only removes image blocks.error instead.{"noru.contract":4} on every tool result without adding contract text to the model prompt.Capture metadata
capture_* address for get_capture.noru-capture:// resource URI.downscaled_from is the source dimensions when capped, otherwise null.A text-only or field projection that sends no pixels has an emptyimages array. Spatial regions are emitted once as a text content block rather than duplicated in structured content.
Provenance notation
Responses carrying capture facts end with a compact prov:line. The notation distinguishes what Noru measured from what a recognition system inferred, and it names absent facts rather than filling them in.
px), Accessibility text (ax), or display mode (dm).rec), optionally with its engine and confidence.Text found inside a screenshot is screen content, not a claim by Noru. A workspace hint is inferred from a window title; app and display values come from resolved capture-source metadata when available.
OCR settlement
A live request waits briefly for on-device text extraction. If it is still pending, Noru returns the complete image, setsocr_pending: true, and says that text is not ready. Call get_capture with the returned id a moment later.
Normal steering and recovery
Operational refusals are normal tool content with a concrete next action, not JSON-RPC errors. This lets an agent recover without treating a user-controlled pause or missing match as a broken protocol.
JSON-RPC errors
capture_* address, or cannot be resolved.resources/read was blocked because historical access is revoked.When history access is revoked, resources/listreturns an empty resource list instead of revealing local capture metadata.
Access controls
Protocol and contract versioning
Noru's contract version is not the MCP protocol revision and not the app version. Contract 4 names the meaning of Noru's tool vocabulary, response grammar, and provenance notation. The app version in serverInfo can change without changing this contract.
The server implements MCP revisions 2024-11-05,2025-03-26, and2025-06-18. It returns the requested revision when supported. With no requested revision it uses the oldest; for an unknown revision it answers with the newest revision it implements.
{
"protocolVersion": "2025-06-18",
"capabilities": {
"tools": {},
"resources": {},
"experimental": {
"noru.contract": {"version": 4}
}
},
"serverInfo": {"name": "noru", "version": "<app version>"},
"instructions": "<Noru's current routing instructions>"
}During initialization the contract appears atcapabilities.experimental["noru.contract"].version. Each tool result repeats the integer at_meta["noru.contract"]. Current tools are listed bytools/list; retired compatibility names are omitted there but continue to resolve to their argument-based replacements.