@@ -237,6 +237,44 @@ def genesis_proposals_path() -> Path:
237237 return repo_root () / "examples" / "genesis" / "proposals.jsonl"
238238
239239
240+ DOC_RESOURCES : tuple [JsonMap , ...] = (
241+ {
242+ "uri" : "zero://docs/strategy-runner" ,
243+ "name" : "Strategy Runner Docs" ,
244+ "description" : "Read-only contributor docs for declarative paper strategy runners." ,
245+ "path" : "examples/strategy-runner/README.md" ,
246+ "fallback" : (
247+ "# Strategy Runner Docs\n \n "
248+ "Declarative strategy runners are paper-only examples for coding agents and "
249+ "contributors. Use `examples/strategy-runner/close-strength.yaml` as the "
250+ "reference fixture and keep new runners deterministic.\n "
251+ ),
252+ },
253+ {
254+ "uri" : "zero://docs/strategy-plugin" ,
255+ "name" : "Strategy Plugin Docs" ,
256+ "description" : "Read-only contributor docs for deterministic paper strategy plugins." ,
257+ "path" : "examples/strategy-plugin/README.md" ,
258+ "fallback" : (
259+ "# Strategy Plugin Docs\n \n "
260+ "Strategy plugins are the smallest paper-only contributor path. Keep plugin "
261+ "fixtures deterministic, avoid credentials, and include a focused smoke test.\n "
262+ ),
263+ },
264+ {
265+ "uri" : "zero://docs/market-data-adapters" ,
266+ "name" : "Market Data Adapter Docs" ,
267+ "description" : "Read-only contributor docs for deterministic market-data adapters." ,
268+ "path" : "examples/market-data-adapter/README.md" ,
269+ "fallback" : (
270+ "# Market Data Adapter Docs\n \n "
271+ "Market-data adapters should load public-safe deterministic fixtures for tests "
272+ "and examples. Do not add exchange credentials or live-only dependencies.\n "
273+ ),
274+ },
275+ )
276+
277+
240278def load_demo_scenario () -> Any :
241279 root = find_repo_root ()
242280 if root is None :
@@ -746,7 +784,7 @@ def tool_definitions() -> list[JsonMap]:
746784
747785
748786def resource_definitions () -> list [JsonMap ]:
749- return [
787+ resources = [
750788 {
751789 "uri" : "zero://paper/scenario" ,
752790 "name" : "Bundled Paper Scenario" ,
@@ -862,6 +900,16 @@ def resource_definitions() -> list[JsonMap]:
862900 "mimeType" : "application/json" ,
863901 },
864902 ]
903+ resources .extend (
904+ {
905+ "uri" : str (resource ["uri" ]),
906+ "name" : str (resource ["name" ]),
907+ "description" : str (resource ["description" ]),
908+ "mimeType" : "text/markdown" ,
909+ }
910+ for resource in DOC_RESOURCES
911+ )
912+ return resources
865913
866914
867915def read_resource (uri : str ) -> str :
@@ -906,6 +954,19 @@ def read_resource(uri: str) -> str:
906954 return json .dumps (get_evidence_bundle (), indent = 2 , sort_keys = True )
907955 if uri == "zero://mcp/safety" :
908956 return json .dumps (safety_catalog (), indent = 2 , sort_keys = True )
957+ for resource in DOC_RESOURCES :
958+ if uri == resource ["uri" ]:
959+ root = find_repo_root ()
960+ if root is None :
961+ return str (resource ["fallback" ])
962+ return (root / str (resource ["path" ])).read_text (encoding = "utf-8" )
963+ raise KeyError (uri )
964+
965+
966+ def resource_mime_type (uri : str ) -> str :
967+ for resource in resource_definitions ():
968+ if resource ["uri" ] == uri :
969+ return str (resource ["mimeType" ])
909970 raise KeyError (uri )
910971
911972
@@ -969,11 +1030,12 @@ def handle_request(request: JsonMap) -> JsonMap | None:
9691030 uri = str (params .get ("uri" , "" ))
9701031 try :
9711032 text = read_resource (uri )
1033+ mime_type = resource_mime_type (uri )
9721034 except KeyError :
9731035 return error_response (request_id , - 32602 , f"unknown ZERO resource: { uri } " )
9741036 return result_response (
9751037 request_id ,
976- {"contents" : [{"uri" : uri , "mimeType" : "application/json" , "text" : text }]},
1038+ {"contents" : [{"uri" : uri , "mimeType" : mime_type , "text" : text }]},
9771039 )
9781040 return error_response (request_id , - 32601 , f"method not found: { method } " )
9791041
0 commit comments