Public: anyone can read this; the crew can change it.

MCP `repo_labels` renames or recolours a label with `action: "update"`, as the labels page does #7502

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

MCP `repo_labels` now takes `action: "update"`, so an agent can rename or recolour a label without using the labels page. It needs `id`, plus a new `name`, a new `color` (six hex digits), or both. It calls the same `updateLabel` action as the labels page and returns the updated label as `{ says, label }`.

shipped production is serving it deploy 11fb0ff

opened this

MCP repo_labels now takes action: "update", so an agent can rename or recolour a label without using the labels page. It needs id, plus a new name, a new color (six hex digits), or both. It calls the same updateLabel action as the labels page and returns the updated label as { says, label }.

  • Partial updates: if name or color is left out, the label keeps its current value. Leaving out both is refused as invalid. The page always sends both fields.
  • Refusals: taken, not_found and invalid use the page's own sentences. Those sentences now live in src/actions/label_words.ts, next to the existing shape sentence. Both the page (src/web/pages/labels.ts) and the tool read them from there, so the wording can't drift apart.
  • Who may update: the same people as create. A read-only or rw token is refused, and so is anyone who isn't an admin of the repository.
  • Docs: the tool's doc and short description name the new action, and bun scripts/mcp-tools.ts regenerated the table in docs/MCP.md.

Worth a look: someone who isn't an admin of the repository gets not_found: That label no longer exists., because the admin check underneath answers not_found. That matches the page, but it's less clear than remove's "no such label, or you are not this repository's admin".

I left create's existing "A label with that name already exists." unchanged, because test/mcp-repo-labels.test.ts checks for that exact text.

To try it: bun test test/mcp-labels-update.test.ts. The test creates a label, then renames and recolours it (both together and each alone) and checks the list each time. It also checks a taken name, a bad colour, a blank name and a missing label, each in the page's words, and that read-only, rw and stranger tokens can't change anything.

Passing: those tests, plus test/mcp-repo-labels.test.ts, test/mcp-labels.test.ts, test/label-words.test.ts, test/mcp-size.test.ts (within the ceilings) and test/mcp-tools.test.ts. The tests that open the labels page also pass (settings, web-ui, settings-repo-timing, studio-shipping), as do bun x tsc --noEmit and bun scripts/design-lint.ts. The full suite was not run here.

🤖 Generated with Claude Code

Closes #7497

commented

MCP repo_labels now takes action: "update", so an agent can rename or recolour a label without using the labels page. It needs id, plus a new name, a new color (six hex digits), or both. It calls the same updateLabel action as the labels page and returns the updated label as { says, label }.

  • Partial updates: if name or color is left out, the label keeps its current value. Leaving out both is refused as invalid. The page always sends both fields.
  • Refusals: taken, not_found and invalid use the page's own sentences. Those sentences now live in src/actions/label_words.ts, next to the existing shape sentence. Both the page (src/web/pages/labels.ts) and the tool read them from there, so the wording can't drift apart.
  • Who may update: the same people as create. A read-only or rw token is refused, and so is anyone who isn't an admin of the repository.
  • Docs: the tool's doc and short description name the new action, and bun scripts/mcp-tools.ts regenerated the table in docs/MCP.md.

Worth a look: someone who isn't an admin of the repository gets not_found: That label no longer exists., because the admin check underneath answers not_found. That matches the page, but it's less clear than remove's "no such label, or you are not this repository's admin".

I left create's existing "A label with that name already exists." unchanged, because test/mcp-repo-labels.test.ts checks for that exact text.

To try it: bun test test/mcp-labels-update.test.ts. The test creates a label, then renames and recolours it (both together and each alone) and checks the list each time. It also checks a taken name, a bad colour, a blank name and a missing label, each in the page's words, and that read-only, rw and stranger tokens can't change anything.

Passing: those tests, plus test/mcp-repo-labels.test.ts, test/mcp-labels.test.ts, test/label-words.test.ts, test/mcp-size.test.ts (within the ceilings) and test/mcp-tools.test.ts. The tests that open the labels page also pass (settings, web-ui, settings-repo-timing, studio-shipping), as do bun x tsc --noEmit and bun scripts/design-lint.ts. The full suite was not run here.

🤖 Generated with Claude Code

Approved

Approved. action: "update" goes through the same updateLabel action as the labels page. That action checks the repository admin with requireRepoAdmin, validates the name with trim and empty and the colour with six hex digits in core/issues.updateLabel, uses parameterised SQL, and appends label.updated to the bus, so web viewers see the change live. Before that, the tool refuses a read-only token through readsWhen and an rw token through scopeAllows(…, "admin"), the same gate create and remove use. Partial updates are resolved against the stored row, and the refusals use the page's sentences. The test file covers rename and recolour (together and each alone), a taken name, a bad colour, a blank name, a missing id, a missing field, and ro, rw and stranger tokens. Every one of those cases would fail without this change. The change to src/web/pages/labels.ts only moves strings: no markup changes, so nothing applies from DESIGN.md. The terminal has no labels door at all, so there is no terminal parity to break. Preview: / answers 200, and /mcp without a token gives its usual unauthorized refusal.

Two low-severity notes, neither blocking (see the line comments): a stranger is told the label "no longer exists", and create still says taken in its own words. Follow-up outside this issue: the JSON API still has no PATCH …/labels/:id, so the API door can't rename a label yet.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs