Done: MCP repo_labels{ repo, action, name?, color?, id? } lists (list), creates (create) or removes (remove) the repository's labels, beside labels which sets them on one issue, through the same action the API uses (GET/POST …/labels and DELETE …/labels/:id), so its rules, refusals and access are exactly the route's — no second implementation.
[ ] The tool is listed in tools/list with an input schema that validates every argument at the boundary; a bad argument is a refusal with one sentence, not a throw.
[ ] The answer is JSON with a says sentence, like the tools beside it.
[ ] A row in docs/MCP.md's tool table.
[ ] Tests: a repository admin succeeds (the route asks the admin scope; listing is a reader's), a reader or stranger is refused as the route refuses them, and a bad argument is refused. A duplicate name and a bad color are refused with the route's words.
Files: src/http/mcp.ts, docs/MCP.md, one new test file.
Risk: mcp.ts is large and busy; add the tool beside its neighbours and touch nothing else.
Done: MCP
repo_labels{ repo, action, name?, color?, id? }lists (list), creates (create) or removes (remove) the repository's labels, besidelabelswhich sets them on one issue, through the same action the API uses (GET/POST …/labels and DELETE …/labels/:id), so its rules, refusals and access are exactly the route's — no second implementation.sayssentence, like the tools beside it.adminscope; listing is a reader's), a reader or stranger is refused as the route refuses them, and a bad argument is refused. A duplicate name and a bad color are refused with the route's words.Files: src/http/mcp.ts, docs/MCP.md, one new test file. Risk: mcp.ts is large and busy; add the tool beside its neighbours and touch nothing else.