- jz.bm.mcp-links on the token twins and the management API: under MCP, url and *_url strings starting with a single / get the app base - material answers under MCP leave the body out unless include_body, marking it with body_omitted; write answers never echo it - jz.bm.manage keys a dispatched call by user - bm_materials and bm_material student tools Plain HTTP answers are unchanged.
86 lines
2.9 KiB
Go
86 lines
2.9 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/bouncer"
|
|
)
|
|
|
|
// The MCP view of the material answers (D-17, D-21): a material's body may
|
|
// hold transcript text, so an answer to an MCP tool call leaves it out
|
|
// unless the call asks for it with include_body, and a write answer never
|
|
// echoes it. Plain HTTP answers are unchanged.
|
|
|
|
// viaMCP reports whether r is an MCP tool call: a request pier dispatched
|
|
// in-process with the api_token marker. The marker lives on the context
|
|
// only, so an HTTP request can never carry it.
|
|
func viaMCP(r *http.Request) bool {
|
|
_, ok := bouncer.Dispatched(r.Context(), "api_token")
|
|
return ok
|
|
}
|
|
|
|
// includeBody reports whether r asks for the material body
|
|
// (include_body=true or 1).
|
|
func includeBody(r *http.Request) bool {
|
|
return flag(r, "include_body")
|
|
}
|
|
|
|
// bodyOmitted reports whether leaving body out hides content.
|
|
func bodyOmitted(body *string) bool {
|
|
return body != nil && *body != ""
|
|
}
|
|
|
|
// mcpMaterialDetailJSON is a published material under MCP without its body:
|
|
// the list fields and the files, with body_omitted when a non-empty body was
|
|
// left out. Body shadows the embedded one and stays nil.
|
|
type mcpMaterialDetailJSON struct {
|
|
materialDetailJSON
|
|
Body *string `json:"body,omitempty"`
|
|
BodyOmitted bool `json:"body_omitted,omitempty"`
|
|
}
|
|
|
|
// mcpManagedMaterialJSON is a managed material under MCP without its body.
|
|
type mcpManagedMaterialJSON struct {
|
|
managedMaterialJSON
|
|
Body *string `json:"body,omitempty"`
|
|
BodyOmitted bool `json:"body_omitted,omitempty"`
|
|
}
|
|
|
|
// mcpManagedMaterialDetailJSON is a managed material with its files under
|
|
// MCP without its body.
|
|
type mcpManagedMaterialDetailJSON struct {
|
|
mcpManagedMaterialJSON
|
|
Files []fileJSON `json:"files"`
|
|
}
|
|
|
|
// materialView is the answer of GET /materials/{id} (student): unchanged
|
|
// over plain HTTP; under MCP (mcp) without the body unless withBody.
|
|
func materialView(d materialDetailJSON, mcp, withBody bool) any {
|
|
if !mcp || withBody {
|
|
return d
|
|
}
|
|
return mcpMaterialDetailJSON{materialDetailJSON: d, BodyOmitted: bodyOmitted(d.Body)}
|
|
}
|
|
|
|
// managedMaterialView is a managed material: unchanged over plain HTTP;
|
|
// under MCP (mcp) without the body unless withBody (a write answer passes
|
|
// false, so it never echoes the body).
|
|
func managedMaterialView(m managedMaterialJSON, mcp, withBody bool) any {
|
|
if !mcp || withBody {
|
|
return m
|
|
}
|
|
return mcpManagedMaterialJSON{managedMaterialJSON: m, BodyOmitted: bodyOmitted(m.Body)}
|
|
}
|
|
|
|
// managedMaterialDetailView is a managed material with its files, under the
|
|
// same rule as managedMaterialView.
|
|
func managedMaterialDetailView(d managedMaterialDetailJSON, mcp, withBody bool) any {
|
|
if !mcp || withBody {
|
|
return d
|
|
}
|
|
return mcpManagedMaterialDetailJSON{
|
|
mcpManagedMaterialJSON: mcpManagedMaterialJSON{managedMaterialJSON: d.managedMaterialJSON, BodyOmitted: bodyOmitted(d.Body)},
|
|
Files: d.Files,
|
|
}
|
|
}
|