1package tinyclient23import (4 _ "embed"5 "encoding/json"6 "fmt"7 "net/http"8)910//go:embed webmcp.js11var webMCPJavaScript string1213func (a *App) webMCP(writer http.ResponseWriter, request *http.Request) {14 writer.Header().Set("content-type", "application/javascript; charset=utf-8")15 writer.Header().Set("cache-control", "no-store")16 _, _ = writer.Write([]byte(webMCPJavaScript))17}1819func (a *App) webMCPQuery(writer http.ResponseWriter, request *http.Request) {20 writer.Header().Set("cache-control", "no-store, private")21 method := request.URL.Query().Get("method")22 var params []json.RawMessage23 if raw := request.URL.Query().Get("params"); raw != "" {24 if err := json.Unmarshal([]byte(raw), ¶ms); err != nil {25 writeJSON(writer, http.StatusBadRequest, map[string]string{"error": "invalid WebMCP query"})26 return27 }28 }29 allowed := map[string]bool{"browserepos": true, "browserepo": true, "browsefiles": true, "browsefile": true, "browsestatus": true, "browseissues": true, "browsepulls": true, "browseissue": true, "browsepull": true, "browsewiki": true, "browsewikipage": true, "browsewikimerge": true, "browserooms": true, "browseroom": true, "browsethread": true, "browseagent": true, "browsegrant": true, "browseprofile": true, "browseapprovals": true, "browseapproval": true, "browsejobs": true, "browsejob": true}30 if !allowed[method] {31 writeJSON(writer, http.StatusBadRequest, map[string]string{"error": "unsupported WebMCP query"})32 return33 }34 actor, err := a.resolveActor(request)35 if err != nil {36 writeJSON(writer, http.StatusUnauthorized, map[string]string{"error": "authentication required"})37 return38 }39 result, err := a.backend.Query(request.Context(), method, params, actor)40 if err != nil {41 writeJSON(writer, http.StatusForbidden, map[string]string{"error": fmt.Sprint(err)})42 return43 }44 writeJSON(writer, http.StatusOK, result)45}4647var _ http.Handler = (*App)(nil)