@@ -210,6 +210,59 @@ pub export fn supabase_mcp_reset() void {
210210}
211211
212212// ---------------------------------------------------------------------------
213+ // ═══════════════════════════════════════════════════════════════════════
214+ // Standard ABI (ADR-0005 four symbols + ADR-0006 invoke)
215+ // ═══════════════════════════════════════════════════════════════════════
216+
217+ const shim = @import ("cartridge_shim" );
218+
219+ const CARTRIDGE_NAME_PTR : [* :0 ]const u8 = "supabase-mcp" ;
220+ const CARTRIDGE_VERSION_PTR : [* :0 ]const u8 = "0.1.0" ;
221+
222+ export fn boj_cartridge_init () callconv (.c ) c_int {
223+ return 0 ;
224+ }
225+
226+ export fn boj_cartridge_deinit () callconv (.c ) void {}
227+
228+ export fn boj_cartridge_name () callconv (.c ) [* :0 ]const u8 {
229+ return CARTRIDGE_NAME_PTR ;
230+ }
231+
232+ export fn boj_cartridge_version () callconv (.c ) [* :0 ]const u8 {
233+ return CARTRIDGE_VERSION_PTR ;
234+ }
235+
236+ /// Dispatch the cartridge.json MCP tools. Grade D Alpha stubs.
237+ export fn boj_cartridge_invoke (
238+ tool_name : [* c ]const u8 ,
239+ json_args : [* c ]const u8 ,
240+ out_buf : [* c ]u8 ,
241+ in_out_len : [* c ]usize ,
242+ ) callconv (.c ) i32 {
243+ _ = json_args ;
244+ if (shim .invokeArgsNull (tool_name , out_buf , in_out_len )) return shim .RC_BAD_ARGS ;
245+
246+ const body : []const u8 = if (shim .toolIs (tool_name , "supabase_connect" ))
247+ "{\" result\" :{\" status\" :\" stub\" }}"
248+ else if (shim .toolIs (tool_name , "supabase_query" ))
249+ "{\" result\" :{\" matches\" :[],\" status\" :\" stub\" }}"
250+ else if (shim .toolIs (tool_name , "supabase_insert" ))
251+ "{\" result\" :{\" status\" :\" stub\" }}"
252+ else if (shim .toolIs (tool_name , "supabase_update" ))
253+ "{\" result\" :{\" status\" :\" stub\" }}"
254+ else if (shim .toolIs (tool_name , "supabase_delete" ))
255+ "{\" result\" :{\" status\" :\" stub\" }}"
256+ else if (shim .toolIs (tool_name , "supabase_storage_list" ))
257+ "{\" result\" :{\" items\" :[],\" count\" :0,\" status\" :\" stub\" }}"
258+ else if (shim .toolIs (tool_name , "supabase_disconnect" ))
259+ "{\" result\" :{\" status\" :\" stub\" }}"
260+ else
261+ return shim .RC_UNKNOWN_TOOL ;
262+
263+ return shim .writeResult (out_buf , in_out_len , body );
264+ }
265+
213266// Tests
214267// ---------------------------------------------------------------------------
215268
@@ -292,3 +345,50 @@ test "action requires connection" {
292345 try std .testing .expectEqual (@as (c_int , 0 ), supabase_mcp_action_requires_connection (0 )); // list_projects
293346 try std .testing .expectEqual (@as (c_int , 0 ), supabase_mcp_action_requires_connection (99 )); // out of range
294347}
348+
349+ // ═══════════════════════════════════════════════════════════════════════
350+ // ADR-0006 invoke dispatch tests
351+ // ═══════════════════════════════════════════════════════════════════════
352+
353+ test "boj_cartridge_name returns supabase-mcp" {
354+ const n = std .mem .span (boj_cartridge_name ());
355+ try std .testing .expectEqualStrings ("supabase-mcp" , n );
356+ }
357+
358+ test "boj_cartridge_init returns 0" {
359+ try std .testing .expectEqual (@as (c_int , 0 ), boj_cartridge_init ());
360+ }
361+
362+ test "invoke: each declared tool succeeds" {
363+ var buf : [256 ]u8 = undefined ;
364+ const tools = [_ ][]const u8 {
365+ "supabase_connect" ,
366+ "supabase_query" ,
367+ "supabase_insert" ,
368+ "supabase_update" ,
369+ "supabase_delete" ,
370+ "supabase_storage_list" ,
371+ "supabase_disconnect" ,
372+ };
373+ for (tools ) | t | {
374+ var len : usize = buf .len ;
375+ const rc = boj_cartridge_invoke (t .ptr , "{}" , & buf , & len );
376+ try std .testing .expectEqual (@as (i32 , 0 ), rc );
377+ try std .testing .expect (std .mem .indexOf (u8 , buf [0.. len ], "result" ) != null );
378+ }
379+ }
380+
381+ test "invoke: unknown tool returns -1" {
382+ var buf : [64 ]u8 = undefined ;
383+ var len : usize = buf .len ;
384+ const rc = boj_cartridge_invoke ("nope" , "{}" , & buf , & len );
385+ try std .testing .expectEqual (@as (i32 , -1 ), rc );
386+ }
387+
388+ test "invoke: buffer too small returns -3" {
389+ var buf : [4 ]u8 = undefined ;
390+ var len : usize = buf .len ;
391+ const rc = boj_cartridge_invoke ("supabase_connect" , "{}" , & buf , & len );
392+ try std .testing .expectEqual (@as (i32 , -3 ), rc );
393+ try std .testing .expect (len > 4 );
394+ }
0 commit comments