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

MCP `close`: close or reopen an issue with the same rules as PATCH …/issues/{number} #4179

Merged opened this

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

Merged

The MCP `close` tool is rebuilt on current main and pushed. `test/mcp.test.ts` passes (37 tests). I could not run the type check: `bun x tsc --noEmit` stops with "Cannot find type definition file for 'bun'". I did not run the tests that cover `src/http/api.ts`, which the change also touches.

shipped production is serving it deploy 4915f35

opened this

The MCP close tool is rebuilt on current main and pushed. test/mcp.test.ts passes (37 tests). I could not run the type check: bun x tsc --noEmit stops with "Cannot find type definition file for 'bun'". I did not run the tests that cover src/http/api.ts, which the change also touches.

The branch already held the close work from my earlier commit, so this push is mostly a merge of today's main into it, with no conflicts.

What changed

  • Tool: close in src/http/mcp.ts takes repo and number. It also takes state (closed by default, or open) and the optional reason and into.
  • Same action as PATCH: it calls the same state-setting function as PATCH …/issues/{number}, so every refusal matches the API. That covers an agent dropping a person's ask, done without a note, and the forbidden case. A bad state, reason or into is refused with invalid_state or invalid_reason.
  • API route: I moved the shared check out of the route into a helper in src/http/api.ts so the tool and the route use one path. The route's behaviour is unchanged.
  • Answer: the tool returns the issue's new state and closeReason.

Tests (test/mcp.test.ts)

  • An agent closing its own issue as dropped succeeds.
  • done without a note is refused with the same error as the API.
  • A person's ask is refused when an agent tries to drop it.
  • Reopening works for someone who writes the repository, and an agent reopening is refused where the API refuses it.
  • Closing again answers done.
  • Bad state, reason and into are refused.

Left out: nothing beyond the issue's scope, and no new dependencies.

To try it: call the close tool with {repo, number, reason: "dropped"}, then with {repo, number, state: "open"} to reopen.

Closes #3361

commented

The MCP close tool is rebuilt on current main and pushed. test/mcp.test.ts passes (37 tests). I could not run the type check: bun x tsc --noEmit stops with "Cannot find type definition file for 'bun'". I did not run the tests that cover src/http/api.ts, which the change also touches.

The branch already held the close work from my earlier commit, so this push is mostly a merge of today's main into it, with no conflicts.

What changed

  • Tool: close in src/http/mcp.ts takes repo and number. It also takes state (closed by default, or open) and the optional reason and into.
  • Same action as PATCH: it calls the same state-setting function as PATCH …/issues/{number}, so every refusal matches the API. That covers an agent dropping a person's ask, done without a note, and the forbidden case. A bad state, reason or into is refused with invalid_state or invalid_reason.
  • API route: I moved the shared check out of the route into a helper in src/http/api.ts so the tool and the route use one path. The route's behaviour is unchanged.
  • Answer: the tool returns the issue's new state and closeReason.

Tests (test/mcp.test.ts)

  • An agent closing its own issue as dropped succeeds.
  • done without a note is refused with the same error as the API.
  • A person's ask is refused when an agent tries to drop it.
  • Reopening works for someone who writes the repository, and an agent reopening is refused where the API refuses it.
  • Closing again answers done.
  • Bad state, reason and into are refused.

Left out: nothing beyond the issue's scope, and no new dependencies.

To try it: call the close tool with {repo, number, reason: "dropped"}, then with {repo, number, state: "open"} to reopen.

commented

The MCP tool listing is back under its 40 KB ceiling, and the fix is committed and pushed. The test files that mention tools/list or MCP now pass (952 tests, 0 failures). I did not run the full check, so the other failed shards from the forge's log are unconfirmed. They stopped at exit 143 without naming a test and were skipped after the first red exit.

Cause: adding the close tool pushed tools/list to 40,844 bytes, past the 40,000 limit. test/mcp-size.test.ts and test/mcp-pulls.test.ts both check it, and test/mcp-pulls.test.ts was the failing test.

What I cut

  • close description: shortened from 439 bytes to about 130.
  • issue, pulls and tell descriptions: trimmed.
  • repo argument: removed the "owner/name" caption that all 37 tools repeated on it. This is where most of the room came from, but a harness no longer sees the owner/name format in the schema. If you want the format hint kept, say so, and I'll put the descriptions back and cut elsewhere.

No tool's behaviour changed. The close tests in test/mcp.test.ts still pass.

commented

I merged current main into the branch and pushed it; the check on #4179 has not re-run yet.

The conflict in src/http/mcp.ts was in three tool descriptions: issue, pulls and tell. Main had shortened the same three for the same 40 KB size limit, so I took main's wording for all three. The tests with mcp in their name pass (87 tests, 0 failures), including the tools/list size tests. I didn't run the full test suite.

My other changes are unchanged: the close tool and its shorter description, and no owner/name caption on repo.

Approved

Does what #3361 asks. close goes through setIssueStateThrough, the same action as PATCH …/issues/:number. So who may close or reopen is decided once: an agent may not drop a person's ask, done needs a commit note, an agent reopens nothing, the plan's structural issues stay a person's, and mirrors write through. The close is announced on app.bus, so web viewers see it live. writes: true stops a read-only token, and issueArg's mayView hides a sealed report. closingFrom moves into actions/issues.ts unchanged, and the route and the tool now share one boundary check. The tests cover each behaviour the issue lists: own-dropped succeeds, done with no note gets forbidden exactly as the API does, a person's ask is refused, an agent's reopen is refused, a person reopens, and bad words are refused. I couldn't run the head's tests: the branch is on a fork my token can't fetch, and the preview's MCP needs a token. I'm relying on the green check for those. Two non-blocking notes are inline. The one worth a follow-up is the owner/name hint dropped from repo on every tool.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs