@@ -267,6 +267,59 @@ pub export fn discord_mcp_reset() void {
267267}
268268
269269// ---------------------------------------------------------------------------
270+ // ═══════════════════════════════════════════════════════════════════════
271+ // Standard ABI (ADR-0005 four symbols + ADR-0006 invoke)
272+ // ═══════════════════════════════════════════════════════════════════════
273+
274+ const shim = @import ("cartridge_shim" );
275+
276+ const CARTRIDGE_NAME_PTR : [* :0 ]const u8 = "discord-mcp" ;
277+ const CARTRIDGE_VERSION_PTR : [* :0 ]const u8 = "0.1.0" ;
278+
279+ export fn boj_cartridge_init () callconv (.c ) c_int {
280+ return 0 ;
281+ }
282+
283+ export fn boj_cartridge_deinit () callconv (.c ) void {}
284+
285+ export fn boj_cartridge_name () callconv (.c ) [* :0 ]const u8 {
286+ return CARTRIDGE_NAME_PTR ;
287+ }
288+
289+ export fn boj_cartridge_version () callconv (.c ) [* :0 ]const u8 {
290+ return CARTRIDGE_VERSION_PTR ;
291+ }
292+
293+ /// Dispatch the cartridge.json MCP tools. Grade D Alpha stubs.
294+ export fn boj_cartridge_invoke (
295+ tool_name : [* c ]const u8 ,
296+ json_args : [* c ]const u8 ,
297+ out_buf : [* c ]u8 ,
298+ in_out_len : [* c ]usize ,
299+ ) callconv (.c ) i32 {
300+ _ = json_args ;
301+ if (shim .invokeArgsNull (tool_name , out_buf , in_out_len )) return shim .RC_BAD_ARGS ;
302+
303+ const body : []const u8 = if (shim .toolIs (tool_name , "discord_authenticate" ))
304+ "{\" result\" :{\" status\" :\" stub\" }}"
305+ else if (shim .toolIs (tool_name , "discord_send_message" ))
306+ "{\" result\" :{\" status\" :\" stub\" }}"
307+ else if (shim .toolIs (tool_name , "discord_list_guilds" ))
308+ "{\" result\" :{\" items\" :[],\" count\" :0,\" status\" :\" stub\" }}"
309+ else if (shim .toolIs (tool_name , "discord_list_channels" ))
310+ "{\" result\" :{\" items\" :[],\" count\" :0,\" status\" :\" stub\" }}"
311+ else if (shim .toolIs (tool_name , "discord_read_messages" ))
312+ "{\" result\" :{\" status\" :\" stub\" }}"
313+ else if (shim .toolIs (tool_name , "discord_add_reaction" ))
314+ "{\" result\" :{\" status\" :\" stub\" }}"
315+ else if (shim .toolIs (tool_name , "discord_deauthenticate" ))
316+ "{\" result\" :{\" status\" :\" stub\" }}"
317+ else
318+ return shim .RC_UNKNOWN_TOOL ;
319+
320+ return shim .writeResult (out_buf , in_out_len , body );
321+ }
322+
270323// Tests
271324// ---------------------------------------------------------------------------
272325
@@ -372,3 +425,50 @@ test "slot exhaustion" {
372425 const new_slot = discord_mcp_session_open ();
373426 try std .testing .expect (new_slot >= 0 );
374427}
428+
429+ // ═══════════════════════════════════════════════════════════════════════
430+ // ADR-0006 invoke dispatch tests
431+ // ═══════════════════════════════════════════════════════════════════════
432+
433+ test "boj_cartridge_name returns discord-mcp" {
434+ const n = std .mem .span (boj_cartridge_name ());
435+ try std .testing .expectEqualStrings ("discord-mcp" , n );
436+ }
437+
438+ test "boj_cartridge_init returns 0" {
439+ try std .testing .expectEqual (@as (c_int , 0 ), boj_cartridge_init ());
440+ }
441+
442+ test "invoke: each declared tool succeeds" {
443+ var buf : [256 ]u8 = undefined ;
444+ const tools = [_ ][]const u8 {
445+ "discord_authenticate" ,
446+ "discord_send_message" ,
447+ "discord_list_guilds" ,
448+ "discord_list_channels" ,
449+ "discord_read_messages" ,
450+ "discord_add_reaction" ,
451+ "discord_deauthenticate" ,
452+ };
453+ for (tools ) | t | {
454+ var len : usize = buf .len ;
455+ const rc = boj_cartridge_invoke (t .ptr , "{}" , & buf , & len );
456+ try std .testing .expectEqual (@as (i32 , 0 ), rc );
457+ try std .testing .expect (std .mem .indexOf (u8 , buf [0.. len ], "result" ) != null );
458+ }
459+ }
460+
461+ test "invoke: unknown tool returns -1" {
462+ var buf : [64 ]u8 = undefined ;
463+ var len : usize = buf .len ;
464+ const rc = boj_cartridge_invoke ("nope" , "{}" , & buf , & len );
465+ try std .testing .expectEqual (@as (i32 , -1 ), rc );
466+ }
467+
468+ test "invoke: buffer too small returns -3" {
469+ var buf : [4 ]u8 = undefined ;
470+ var len : usize = buf .len ;
471+ const rc = boj_cartridge_invoke ("discord_authenticate" , "{}" , & buf , & len );
472+ try std .testing .expectEqual (@as (i32 , -3 ), rc );
473+ try std .testing .expect (len > 4 );
474+ }
0 commit comments