Files
sm-quizzes-plugin/mcp_quizzes.go
Jakub Zych e615cc88db feat: list and show quizzes over MCP for their owner
- quizzes_list_quizzes and quizzes_show_quiz bound to GET /api/v1/quizzes
  and /api/v1/quizzes/{slug} behind user.api_token, the per-user
  golem15.quizzes.manage throttle, a scope and the access_quizzes permission
- the permission is grantable through pact.HasFrontendPermissions
- owner JSON shapes with solutions in manage_json.go, never used by a
  student route
2026-11-09 14:25:07 +01:00

54 lines
2.4 KiB
Go

package quizzes
import (
"net/http"
"git.golem15.com/golem15/summercms/modules/pact"
)
// The sentences every quiz tool description ends with (D-13).
const (
needsRead = " Needs scope read and the golem15.quizzes.access_quizzes permission."
needsWrite = " Needs scope write and the golem15.quizzes.access_quizzes permission."
)
// quizPermissions filters the listing: only users whose groups grant the
// quizzes permission see the quiz tools.
var quizPermissions = []string{permQuizzes}
// yes is the true the tool annotations point at.
var yes = true
// listQuizzesInput is the input of quizzes_list_quizzes.
type listQuizzesInput struct {
Context string `json:"context,omitempty" query:"context" jsonschema:"only quizzes whose context label equals this value exactly; leave out for every quiz"`
}
// showQuizInput is the input of quizzes_show_quiz.
type showQuizInput struct {
Slug string `json:"slug" path:"slug" jsonschema:"the quiz slug (lowercase letters, digits and hyphens), as listed by quizzes_list_quizzes"`
}
func quizTools() []pact.MCPTool {
return []pact.MCPTool{
{
Name: "list_quizzes",
Title: "List quizzes",
Description: "Lists every quiz, published or not, ordered by context (quizzes without one last) and title: id, slug, title, description, context, mode (learning or test), navigation (free or one_way), max_attempts, time_limit_seconds, passing_score, shuffle_questions, round_size, is_published, question_count, attempts_count (completed attempts of all students), created_at and updated_at. context filters by the exact context label." + needsRead,
Method: http.MethodGet,
Path: ManagePrefix,
Input: listQuizzesInput{},
Permissions: quizPermissions,
},
{
Name: "show_quiz",
Title: "Show a quiz with its solutions",
Description: "Returns one quiz with the fields of quizzes_list_quizzes and its questions in order: id, text, type (single, multiple or self_check), category, answer_text, explanation, points, sort_order and answers [{id, text, is_correct, explanation, sort_order}]. This is the owner view: it includes the solutions (is_correct, explanations and answer_text), which students only see after answering or finishing." + needsRead,
Method: http.MethodGet,
Path: ManagePrefix + "/{slug}",
Input: showQuizInput{},
Permissions: quizPermissions,
},
}
}