code wiki / (root) / nx_tools_api_gate.nx

nx_tools_api_gate.nx source

↩ module page · 280 lines · 18591 B

1// nx_tools_api_gate.nx -- drives ta_handle_pfx IN-PROCESS (no socket, no curl): register two test tools, then 2// assert the REST surface (/api/tools) and the MCP surface (/mcp: tools/list, initialize, error) are well-formed. 3// Proves R0 = MCP-compatible + superset, sovereignly. license_tier: ORIGINAL 4import "nx_tools_api.nx" 5import "nx_gate.nx" 6 7func tg_has(out: *u8, n: i64, needle: *u8) -> i64 { if ta_indexof(out, n, needle) >= 0 { return 1 } return 0 } 8// NUL-terminated string at pointer `p` (an argv entry, stored as i64) equals the NUL-terminated `expect`? 9func tg_streq(p: i64, expect: *u8) -> i64 { 10 let a: *u8 = p as *u8 11 var i: i64 = 0 12 while expect[i] != (0 as u8) { if a[i] != expect[i] { return 0 } i = i + 1 } 13 if a[i] != (0 as u8) { return 0 } 14 return 1 15} 16// buf[o2[0], o2[0]+o2[1]) equals the NUL-terminated expect? (for offset/len pairs like ta_query_cap emits) 17func tg_slice_eq(buf: *u8, o2: *i64, expect: *u8) -> i64 { 18 var n: i64 = 0 19 while expect[n] != (0 as u8) { n = n + 1 } 20 if o2[1] != n { return 0 } 21 var i: i64 = 0 22 while i < n { if buf[o2[0] + i] != expect[i] { return 0 } i = i + 1 } 23 return 1 24} 25func tg_write(path: *u8, content: *u8) -> i64 { 26 let fd: i64 = __syscall(257, 0 - 100, path, 0x241, 0x1a4, 0, 0) // O_WRONLY|O_CREAT|O_TRUNC, 0644 27 if fd < 0 { return 0 - 1 } 28 var n: i64 = 0; while content[n] != (0 as u8) { n = n + 1 } 29 sys_write(fd, content, n); sys_close(fd) 30 return 0 31} 32 33func main() -> i64 { 34 gw("=== nx_tools_api_gate: sovereign agent-facing API (MCP-compatible + superset) ===\n" as *u8) 35 let TP: *u8 = "knowledge/toolreg-test-tapi-" as *u8 36 tool_register_pfx(TP, "nx_http_probe" as *u8, "sovereign HTTP GET probe" as *u8, "nx_http_probe <path>" as *u8, "gate-proven" as *u8) 37 tool_register_pfx(TP, "nx_mgmt_client" as *u8, "drive the control-plane over TLS-1.3" as *u8, "nx_mgmt_client <url> call ..." as *u8, "gate-10/10" as *u8) 38 39 var pass: i64 = 0 40 var tot: i64 = 0 41 let out: *u8 = sys_mmap(1048576) 42 43 // T1: GET /api/tools -> 200 + BOTH tools + the superset gate-status field (beyond MCP) 44 let r1: *u8 = "GET /api/tools HTTP/1.1\r\nHost: x\r\nConnection: close\r\n\r\n" as *u8 45 let n1: i64 = ta_handle_pfx(TP, r1, ta_slen(r1), out) 46 tot = tot + 1 47 var t1: i64 = 0 48 if tg_has(out, n1, "200 OK" as *u8) == 1 { if tg_has(out, n1, "nx_http_probe" as *u8) == 1 { if tg_has(out, n1, "nx_mgmt_client" as *u8) == 1 { if tg_has(out, n1, "\"status\":\"gate-proven\"" as *u8) == 1 { t1 = 1 } } } } 49 if t1 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 50 gw("T1 REST /api/tools: 200 + both tools + gate-status (the beyond-MCP field)\n" as *u8) 51 52 // T2: POST /mcp tools/list -> JSON-RPC 2.0, id echoed, MCP-shaped tools with inputSchema 53 let r2: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\nContent-Type: application/json\r\nContent-Length: 47\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":7,\"method\":\"tools/list\"}" as *u8 54 let n2: i64 = ta_handle_pfx(TP, r2, ta_slen(r2), out) 55 tot = tot + 1 56 var t2: i64 = 0 57 if tg_has(out, n2, "\"jsonrpc\":\"2.0\"" as *u8) == 1 { if tg_has(out, n2, "\"id\":7" as *u8) == 1 { if tg_has(out, n2, "\"inputSchema\"" as *u8) == 1 { if tg_has(out, n2, "nx_http_probe" as *u8) == 1 { t2 = 1 } } } } 58 if t2 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 59 gw("T2 MCP tools/list: JSON-RPC 2.0, id echoed, MCP-shaped tools\n" as *u8) 60 61 // T3: POST /mcp initialize -> protocolVersion + serverInfo (handshake) 62 let r3: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\nContent-Length: 46\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\"}" as *u8 63 let n3: i64 = ta_handle_pfx(TP, r3, ta_slen(r3), out) 64 tot = tot + 1 65 var t3: i64 = 0 66 if tg_has(out, n3, "\"protocolVersion\"" as *u8) == 1 { if tg_has(out, n3, "\"serverInfo\"" as *u8) == 1 { t3 = 1 } } 67 if t3 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 68 gw("T3 MCP initialize: protocolVersion + serverInfo\n" as *u8) 69 70 // T4: unknown method -> JSON-RPC error -32601 (fail-closed), id still echoed 71 let r4: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\nContent-Length: 44\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":9,\"method\":\"bogus/x\"}" as *u8 72 let n4: i64 = ta_handle_pfx(TP, r4, ta_slen(r4), out) 73 tot = tot + 1 74 var t4: i64 = 0 75 if tg_has(out, n4, "-32601" as *u8) == 1 { if tg_has(out, n4, "\"id\":9" as *u8) == 1 { t4 = 1 } } 76 if t4 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 77 gw("T4 MCP unknown method: JSON-RPC error -32601\n" as *u8) 78 79 // T5: unknown path -> 404 not_found 80 let r5: *u8 = "GET /nope HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 81 let n5: i64 = ta_handle_pfx(TP, r5, ta_slen(r5), out) 82 tot = tot + 1 83 var t5: i64 = 0 84 if tg_has(out, n5, "404" as *u8) == 1 { t5 = 1 } 85 if t5 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 86 gw("T5 unknown path: 404 not_found\n" as *u8) 87 88 // ---- R3: MCP resources (not tools-only) -- initialize advertises the capability; list + read serve content ---- 89 let rr1: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\"}" as *u8 90 let nr1: i64 = ta_handle_pfx(TP, rr1, ta_slen(rr1), out) 91 tot = tot + 1 92 var tr1: i64 = 0 93 if tg_has(out, nr1, "\"resources\"" as *u8) == 1 { if tg_has(out, nr1, "\"prompts\"" as *u8) == 1 { tr1 = 1 } } 94 if tr1 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 95 gw("T-R3a MCP initialize advertises the resources + prompts capabilities\n" as *u8) 96 97 let rr2: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"resources/list\"}" as *u8 98 let nr2: i64 = ta_handle_pfx(TP, rr2, ta_slen(rr2), out) 99 tot = tot + 1 100 var tr2: i64 = 0 101 if tg_has(out, nr2, "nishi://sota/ecosystem-maturity" as *u8) == 1 { if tg_has(out, nr2, "nishi://doctrine/operating" as *u8) == 1 { tr2 = 1 } } 102 if tr2 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 103 gw("T-R3b MCP resources/list -> 2 resource URIs (grade + doctrine)\n" as *u8) 104 105 let rr3: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"resources/read\",\"params\":{\"uri\":\"nishi://doctrine/operating\"}}" as *u8 106 let nr3: i64 = ta_handle_pfx(TP, rr3, ta_slen(rr3), out) 107 tot = tot + 1 108 var tr3: i64 = 0 109 if tg_has(out, nr3, "\"contents\"" as *u8) == 1 { if tg_has(out, nr3, "nx_ship" as *u8) == 1 { tr3 = 1 } } 110 if tr3 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 111 gw("T-R3c MCP resources/read doctrine -> contents with the operating text\n" as *u8) 112 113 let rp1: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":4,\"method\":\"prompts/list\"}" as *u8 114 let np1: i64 = ta_handle_pfx(TP, rp1, ta_slen(rp1), out) 115 tot = tot + 1 116 var tp1: i64 = 0 117 if tg_has(out, np1, "operate-nishi" as *u8) == 1 { if tg_has(out, np1, "ship-target" as *u8) == 1 { tp1 = 1 } } 118 if tp1 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 119 gw("T-R3d MCP prompts/list -> 2 prompt templates\n" as *u8) 120 121 let rp2: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":5,\"method\":\"prompts/get\",\"params\":{\"name\":\"ship-target\",\"arguments\":{\"target\":\"nx_widget\"}}}" as *u8 122 let np2: i64 = ta_handle_pfx(TP, rp2, ta_slen(rp2), out) 123 tot = tot + 1 124 var tp2: i64 = 0 125 if tg_has(out, np2, "\"messages\"" as *u8) == 1 { if tg_has(out, np2, "nx_widget" as *u8) == 1 { tp2 = 1 } } 126 if tp2 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 127 gw("T-R3e MCP prompts/get ship-target -> messages with the target arg filled\n" as *u8) 128 129 // ---- R2 argv passing: params.arguments.argv (JSON string array) -> native argv (multi-arg tools/call) ---- 130 let av: *i64 = sys_mmap(8192) as *i64 131 let sb: *u8 = sys_mmap(65536) 132 133 // T6: a realistic 4-element argv is parsed positionally (this is exactly nx_mgmt_client's call shape) 134 let jb6: *u8 = "{\"params\":{\"name\":\"nx_mgmt_client\",\"arguments\":{\"argv\":[\"https://nishifamily.com\",\"call\",\"GET\",\"/api/health\"]}}}" as *u8 135 let ac6: i64 = ta_json_str_array(jb6, ta_slen(jb6), "\"argv\"" as *u8, av, 1, 250, sb, 65536) 136 tot = tot + 1 137 var t6: i64 = 0 138 if ac6 == 4 { if tg_streq(av[1], "https://nishifamily.com" as *u8) == 1 { if tg_streq(av[2], "call" as *u8) == 1 { if tg_streq(av[3], "GET" as *u8) == 1 { if tg_streq(av[4], "/api/health" as *u8) == 1 { t6 = 1 } } } } } 139 if t6 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 140 gw("T6 tools/call argv: params.arguments.argv -> 4-element native argv (multi-arg organs callable)\n" as *u8) 141 142 // T7: no argv key -> 0 args (argless back-compat: already-working no-arg tools are unaffected) 143 let jb7: *u8 = "{\"params\":{\"name\":\"nx_http_probe\",\"arguments\":{}}}" as *u8 144 let ac7: i64 = ta_json_str_array(jb7, ta_slen(jb7), "\"argv\"" as *u8, av, 1, 250, sb, 65536) 145 tot = tot + 1 146 var t7: i64 = 0 147 if ac7 == 0 { t7 = 1 } 148 if t7 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 149 gw("T7 tools/call no argv -> 0 args (argless back-compat preserved)\n" as *u8) 150 151 // T8: empty array [] -> 0 args (not treated as one empty arg) 152 let jb8: *u8 = "{\"argv\":[]}" as *u8 153 let ac8: i64 = ta_json_str_array(jb8, ta_slen(jb8), "\"argv\"" as *u8, av, 1, 250, sb, 65536) 154 tot = tot + 1 155 var t8: i64 = 0 156 if ac8 == 0 { t8 = 1 } 157 if t8 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 158 gw("T8 tools/call empty argv [] -> 0 args\n" as *u8) 159 160 // T9: an escaped quote inside an arg must NOT terminate the string early. Build the input as RAW BYTES so no 161 // backslash source-literal is needed: {"argv":["a\"b"]} -> exactly one arg whose value is a"b (3 bytes). 162 let eb: *u8 = sys_mmap(64) 163 var eo: i64 = ta_cat(eb, 0, "{\"argv\":[\"a" as *u8) 164 eb[eo] = 92 as u8; eo = eo + 1 // literal backslash 165 eb[eo] = 34 as u8; eo = eo + 1 // literal quote 166 eo = ta_cat(eb, eo, "b\"]}" as *u8) 167 let ac9: i64 = ta_json_str_array(eb, eo, "\"argv\"" as *u8, av, 1, 250, sb, 65536) 168 tot = tot + 1 169 var t9: i64 = 0 170 if ac9 == 1 { if tg_streq(av[1], "a\"b" as *u8) == 1 { t9 = 1 } } 171 if t9 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 172 gw("T9 tools/call argv JSON-unescape: an escaped quote inside an arg does not split it\n" as *u8) 173 174 // T10: maxn is honored -- a 4-element array with maxn=2 yields exactly 2 (fail-closed, no overflow) 175 let ac10: i64 = ta_json_str_array(jb6, ta_slen(jb6), "\"argv\"" as *u8, av, 1, 2, sb, 65536) 176 tot = tot + 1 177 var t10: i64 = 0 178 if ac10 == 2 { t10 = 1 } 179 if t10 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 180 gw("T10 tools/call argv respects maxn cap (4 elems, maxn=2 -> 2, no overflow)\n" as *u8) 181 182 // ---- R1 rich MCP tool schemas: title + annotations (safety hints) + outputSchema, data-driven ---- 183 tg_write("/tmp/tg_schemas.conf" as *u8, "argecho\tEcho Args\t1\t0\t1\t0\tnewline argv echo\n" as *u8) 184 let sb2: *u8 = sys_mmap(4096) 185 186 // T11: a KNOWN tool emits its title + ACCURATE annotations (read-only, non-destructive, idempotent) + outputSchema 187 let l11: i64 = ta_emit_mcp_schema_from("/tmp/tg_schemas.conf" as *u8, "argecho" as *u8, 7, sb2, 0) 188 tot = tot + 1 189 var t11: i64 = 0 190 if tg_has(sb2, l11, "\"title\":\"Echo Args\"" as *u8) == 1 { if tg_has(sb2, l11, "\"readOnlyHint\":true" as *u8) == 1 { if tg_has(sb2, l11, "\"destructiveHint\":false" as *u8) == 1 { if tg_has(sb2, l11, "\"outputSchema\"" as *u8) == 1 { t11 = 1 } } } } 191 if t11 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 192 gw("T11 MCP rich schema: known tool -> title + accurate annotations + outputSchema (MCP tools-spec parity)\n" as *u8) 193 194 // T12: an UNKNOWN tool -> MCP-safe DEFAULT annotations (NOT read-only, POSSIBLY destructive) + NO title (cautious) 195 let l12: i64 = ta_emit_mcp_schema_from("/tmp/tg_schemas.conf" as *u8, "nosuchtool" as *u8, 10, sb2, 0) 196 tot = tot + 1 197 var t12: i64 = 0 198 if tg_has(sb2, l12, "\"readOnlyHint\":false" as *u8) == 1 { if tg_has(sb2, l12, "\"destructiveHint\":true" as *u8) == 1 { if tg_has(sb2, l12, "\"title\"" as *u8) == 0 { t12 = 1 } } } 199 if t12 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 200 gw("T12 MCP rich schema: unknown tool -> cautious default annotations, no title (safe-by-default)\n" as *u8) 201 202 // ---- 07-30 QUERY-STRING CAP PRESENTER (ta_query_cap) + HONEST DENY ----------------------------------- 203 // Closes the measured root cause of the shell-fallback cascade (debt seq1235): a client that drops the 204 // X-Nishi-Cap header denies EVERY call for a whole session, and the old deny text was indistinguishable 205 // from a missing tool. T14-T18 prove the parser; T19-T21 prove it is WIRED and the deny is honest. 206 let qo: *i64 = sys_mmap(16) as *i64 207 208 // T14: ?cap=<token> is extracted verbatim, and the presenter is COMPILED IN (liveness marker) 209 let q14: *u8 = "POST /mcp?cap=abc~123~7.def HTTP/1.1\r\nHost: x\r\n\r\n{}" as *u8 210 tot = tot + 1 211 var t14: i64 = 0 212 if ta_query_cap_available() == 1 { if ta_query_cap(q14, ta_slen(q14), qo) == 1 { if tg_slice_eq(q14, qo, "abc~123~7.def" as *u8) == 1 { t14 = 1 } } } 213 if t14 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 214 gw("T14 query cap: ?cap=<token> extracted verbatim from the request line\n" as *u8) 215 216 // T15: no query string at all -> absent (0), never a garbage slice 217 let q15: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\n\r\n{}" as *u8 218 tot = tot + 1 219 var t15: i64 = 0 220 if ta_query_cap(q15, ta_slen(q15), qo) == 0 { t15 = 1 } 221 if t15 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 222 gw("T15 query cap: no query string -> absent (fail-closed)\n" as *u8) 223 224 // T16: a query with other params but no cap -> absent 225 let q16: *u8 = "POST /mcp?other=1&x=2 HTTP/1.1\r\nHost: x\r\n\r\n{}" as *u8 226 tot = tot + 1 227 var t16: i64 = 0 228 if ta_query_cap(q16, ta_slen(q16), qo) == 0 { t16 = 1 } 229 if t16 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 230 gw("T16 query cap: query without a cap param -> absent\n" as *u8) 231 232 // T17 NEG-CONTROL (the seq1293 substring-shadowing class): the key must match EXACTLY cap. A lookalike 233 // param must NEVER authorize -- otherwise recap= or capx= would silently present a capability. 234 let q17: *u8 = "POST /mcp?capx=zzz&recap=yyy&scap=www HTTP/1.1\r\nHost: x\r\n\r\n{}" as *u8 235 tot = tot + 1 236 var t17: i64 = 0 237 if ta_query_cap(q17, ta_slen(q17), qo) == 0 { t17 = 1 } 238 if t17 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 239 gw("T17 query cap NEG: capx/recap/scap lookalikes do NOT authorize (exact key only)\n" as *u8) 240 241 // T18: cap as a NON-FIRST pair is found, and its value stops at & (not swallowing the rest of the query) 242 let q18: *u8 = "POST /mcp?a=1&cap=TOK99&z=9 HTTP/1.1\r\nHost: x\r\n\r\n{}" as *u8 243 tot = tot + 1 244 var t18: i64 = 0 245 if ta_query_cap(q18, ta_slen(q18), qo) == 1 { if tg_slice_eq(q18, qo, "TOK99" as *u8) == 1 { t18 = 1 } } 246 if t18 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 247 gw("T18 query cap: found as a non-first pair, value terminates at &\n" as *u8) 248 249 // T19: tools/call with NO cap -> the deny SAYS SO, says the tool exists, and says not to fall back to shell 250 let d19: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":11,\"method\":\"tools/call\",\"params\":{\"name\":\"nx_http_probe\"}}" as *u8 251 let n19: i64 = ta_handle_pfx(TP, d19, ta_slen(d19), out) 252 tot = tot + 1 253 var t19: i64 = 0 254 if tg_has(out, n19, "-32001" as *u8) == 1 { if tg_has(out, n19, "NO capability was presented" as *u8) == 1 { if tg_has(out, n19, "\"presented\":0" as *u8) == 1 { if tg_has(out, n19, "do NOT fall back to shell" as *u8) == 1 { t19 = 1 } } } } 255 if t19 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 256 gw("T19 honest deny: no cap -> NO-capability-presented + presented:0 + do-not-shell (not no-such-tool)\n" as *u8) 257 258 // T20: a PRESENTED-but-invalid cap gets the OPPOSITE message -- the two cases have opposite remedies 259 let d20: *u8 = "POST /mcp HTTP/1.1\r\nHost: x\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":12,\"method\":\"tools/call\",\"params\":{\"name\":\"nx_http_probe\",\"_cap\":\"bogus~1~1.zzz\"}}" as *u8 260 let n20: i64 = ta_handle_pfx(TP, d20, ta_slen(d20), out) 261 tot = tot + 1 262 var t20: i64 = 0 263 if tg_has(out, n20, "\"presented\":1" as *u8) == 1 { if tg_has(out, n20, "does not grant this tool" as *u8) == 1 { if tg_has(out, n20, "NO capability was presented" as *u8) == 0 { t20 = 1 } } } 264 if t20 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 265 gw("T20 honest deny: invalid cap -> presented:1 + does-not-grant (distinct remedy)\n" as *u8) 266 267 // T21 NON-VACUITY: the SAME bogus cap delivered ONLY via ?cap= must also report presented:1. This is the 268 // test that FAILS if ta_query_cap exists but is never called from ta_mcp_call -- it proves the WIRE. 269 let d21: *u8 = "POST /mcp?cap=bogus~1~1.zzz HTTP/1.1\r\nHost: x\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":13,\"method\":\"tools/call\",\"params\":{\"name\":\"nx_http_probe\"}}" as *u8 270 let n21: i64 = ta_handle_pfx(TP, d21, ta_slen(d21), out) 271 tot = tot + 1 272 var t21: i64 = 0 273 if tg_has(out, n21, "\"presented\":1" as *u8) == 1 { if tg_has(out, n21, "NO capability was presented" as *u8) == 0 { t21 = 1 } } 274 if t21 == 1 { pass = pass + 1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 275 gw("T21 NON-VACUITY: a cap presented ONLY via ?cap= reaches ta_mcp_call (presented:1) -- the wire is live\n" as *u8) 276 277 gw("\n=== nx_tools_api_gate " as *u8); gn(pass); gw("/" as *u8); gn(tot); gw(" ===\n" as *u8) 278 if pass == tot { gw("TOOLS-API GREEN -- MCP-compatible (initialize+tools/list) + superset (gate-status), sovereign\n" as *u8); sys_exit(0); return 0 } 279 gw("TOOLS-API RED\n" as *u8); sys_exit(1); return 1 280}