@@ -275,6 +275,63 @@ pub export fn postgresql_mcp_reset() void {
275275}
276276
277277// ---------------------------------------------------------------------------
278+ // ═══════════════════════════════════════════════════════════════════════
279+ // Standard ABI (ADR-0005 four symbols + ADR-0006 invoke)
280+ // ═══════════════════════════════════════════════════════════════════════
281+
282+ const shim = @import ("cartridge_shim" );
283+
284+ const CARTRIDGE_NAME_PTR : [* :0 ]const u8 = "postgresql-mcp" ;
285+ const CARTRIDGE_VERSION_PTR : [* :0 ]const u8 = "0.1.0" ;
286+
287+ export fn boj_cartridge_init () callconv (.c ) c_int {
288+ return 0 ;
289+ }
290+
291+ export fn boj_cartridge_deinit () callconv (.c ) void {}
292+
293+ export fn boj_cartridge_name () callconv (.c ) [* :0 ]const u8 {
294+ return CARTRIDGE_NAME_PTR ;
295+ }
296+
297+ export fn boj_cartridge_version () callconv (.c ) [* :0 ]const u8 {
298+ return CARTRIDGE_VERSION_PTR ;
299+ }
300+
301+ /// Dispatch the cartridge.json MCP tools. Grade D Alpha stubs.
302+ export fn boj_cartridge_invoke (
303+ tool_name : [* c ]const u8 ,
304+ json_args : [* c ]const u8 ,
305+ out_buf : [* c ]u8 ,
306+ in_out_len : [* c ]usize ,
307+ ) callconv (.c ) i32 {
308+ _ = json_args ;
309+ if (shim .invokeArgsNull (tool_name , out_buf , in_out_len )) return shim .RC_BAD_ARGS ;
310+
311+ const body : []const u8 = if (shim .toolIs (tool_name , "pg_connect" ))
312+ "{\" result\" :{\" status\" :\" stub\" }}"
313+ else if (shim .toolIs (tool_name , "pg_query" ))
314+ "{\" result\" :{\" matches\" :[],\" status\" :\" stub\" }}"
315+ else if (shim .toolIs (tool_name , "pg_execute" ))
316+ "{\" result\" :{\" status\" :\" stub\" }}"
317+ else if (shim .toolIs (tool_name , "pg_begin" ))
318+ "{\" result\" :{\" status\" :\" stub\" }}"
319+ else if (shim .toolIs (tool_name , "pg_commit" ))
320+ "{\" result\" :{\" status\" :\" stub\" }}"
321+ else if (shim .toolIs (tool_name , "pg_rollback" ))
322+ "{\" result\" :{\" status\" :\" stub\" }}"
323+ else if (shim .toolIs (tool_name , "pg_list_tables" ))
324+ "{\" result\" :{\" items\" :[],\" count\" :0,\" status\" :\" stub\" }}"
325+ else if (shim .toolIs (tool_name , "pg_describe" ))
326+ "{\" result\" :{\" status\" :\" stub\" }}"
327+ else if (shim .toolIs (tool_name , "pg_disconnect" ))
328+ "{\" result\" :{\" status\" :\" stub\" }}"
329+ else
330+ return shim .RC_UNKNOWN_TOOL ;
331+
332+ return shim .writeResult (out_buf , in_out_len , body );
333+ }
334+
278335// Tests
279336// ---------------------------------------------------------------------------
280337
@@ -364,3 +421,52 @@ test "pool exhaustion" {
364421 const new_slot = postgresql_mcp_connect ("postgres://x:y@h:5432/d" , 23 );
365422 try std .testing .expect (new_slot >= 0 );
366423}
424+
425+ // ═══════════════════════════════════════════════════════════════════════
426+ // ADR-0006 invoke dispatch tests
427+ // ═══════════════════════════════════════════════════════════════════════
428+
429+ test "boj_cartridge_name returns postgresql-mcp" {
430+ const n = std .mem .span (boj_cartridge_name ());
431+ try std .testing .expectEqualStrings ("postgresql-mcp" , n );
432+ }
433+
434+ test "boj_cartridge_init returns 0" {
435+ try std .testing .expectEqual (@as (c_int , 0 ), boj_cartridge_init ());
436+ }
437+
438+ test "invoke: each declared tool succeeds" {
439+ var buf : [256 ]u8 = undefined ;
440+ const tools = [_ ][]const u8 {
441+ "pg_connect" ,
442+ "pg_query" ,
443+ "pg_execute" ,
444+ "pg_begin" ,
445+ "pg_commit" ,
446+ "pg_rollback" ,
447+ "pg_list_tables" ,
448+ "pg_describe" ,
449+ "pg_disconnect" ,
450+ };
451+ for (tools ) | t | {
452+ var len : usize = buf .len ;
453+ const rc = boj_cartridge_invoke (t .ptr , "{}" , & buf , & len );
454+ try std .testing .expectEqual (@as (i32 , 0 ), rc );
455+ try std .testing .expect (std .mem .indexOf (u8 , buf [0.. len ], "result" ) != null );
456+ }
457+ }
458+
459+ test "invoke: unknown tool returns -1" {
460+ var buf : [64 ]u8 = undefined ;
461+ var len : usize = buf .len ;
462+ const rc = boj_cartridge_invoke ("nope" , "{}" , & buf , & len );
463+ try std .testing .expectEqual (@as (i32 , -1 ), rc );
464+ }
465+
466+ test "invoke: buffer too small returns -3" {
467+ var buf : [4 ]u8 = undefined ;
468+ var len : usize = buf .len ;
469+ const rc = boj_cartridge_invoke ("pg_connect" , "{}" , & buf , & len );
470+ try std .testing .expectEqual (@as (i32 , -3 ), rc );
471+ try std .testing .expect (len > 4 );
472+ }
0 commit comments