feat(mcp): mint-token CLI + get_card / delete_comment tools + executeToolAs(actor)

Net-new capacidades recuperadas del WIP stash que el merge notif no traia:

- mint-token CLI subcommand: 'kanban mint-token --user <id> --name <pc>' genera token bearer
  para configurar Claude Code u otros clientes MCP HTTP sin tocar la UI.
- executeToolAs(db, name, input, actor): variante actor-aware de executeTool. El dispatcher
  HTTP /mcp pasa el user_id resuelto del bearer token; tools per-user (add_comment,
  delete_comment) lo usan como autor sin que el llamante pueda forjarlo.
- get_card tool: lookup por id o seq_num. Devuelve Card completa.
- delete_comment tool: borra card_message; solo el autor original (validado en DB).

executeTool() sigue siendo el wrapper legacy sin actor para chat WS.
This commit is contained in:
egutierrez
2026-05-28 09:36:48 +02:00
parent 084defe014
commit 65771ebb12
5 changed files with 162 additions and 15 deletions
+26
View File
@@ -279,6 +279,32 @@ func mcpToolDefs() []infra.MCPToolDef {
"required": []string{"card_id"},
}),
},
{
Name: "delete_comment",
Description: "Borra un comentario propio. Solo el autor original puede borrar (validado en server). " +
"Requiere autenticacion via MCP HTTP — el actor se infiere del bearer token. " +
"Output: {ok:true}.",
InputSchema: rawSchema(map[string]any{
"type": "object",
"properties": map[string]any{
"id": map[string]any{"type": "string", "description": "ID del card_message a borrar (no de la card)."},
},
"required": []string{"id"},
}),
},
{
Name: "get_card",
Description: "Devuelve una tarjeta activa (no archivada) por id o por seq_num. Read-only. " +
"Pasa exactamente UNO de los dos: id (hash interno) o seq_num (entero visible, ej. la '115' de 'card 00115'). " +
"Output: Card completa con time_in_column_ms, total_locked_ms, tags, stickers, deadline.",
InputSchema: rawSchema(map[string]any{
"type": "object",
"properties": map[string]any{
"id": map[string]any{"type": "string", "description": "ID hash de la tarjeta (16 hex)."},
"seq_num": map[string]any{"type": "integer", "description": "Numero secuencial visible al usuario."},
},
}),
},
}
}