Make MCP development task creation reliable - #173
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
d0104b9 to
acb4b3a
Compare
📝 WalkthroughWalkthroughThe MCP task workflow now supports exact parent keys, improved task search, and ChangesTask discovery and parenting
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant MCPClient
participant MCPServer
participant TasksServer
participant TaskDatabase
MCPClient->>MCPServer: Search for a parent or duplicate task
MCPServer->>TasksServer: Apply query, visibility, status, and client boundary
TasksServer->>TaskDatabase: Retrieve and rank task candidates
TaskDatabase-->>TasksServer: Return matching tasks
TasksServer-->>MCPServer: Return ordered results
MCPClient->>MCPServer: Create task with parentTaskKey
MCPServer->>TaskDatabase: Resolve accessible parentTaskKey
TaskDatabase-->>MCPServer: Return resolved parent task ID
MCPServer->>TaskDatabase: Persist child task with parent task ID
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d0104b94fd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
This PR improves reliability of Optimitron MCP task discovery and creation by making task search more tolerant of natural-language framing, adding an exact task-key fast path/boost, and allowing MCP createTask to resolve parents via either an opaque ID or an exact stable task key (with OAuth/client-access boundaries enforced).
Changes:
- Updated
searchTasksto OR-match distinctive terms (dropping request-framing words) while bounding candidate retrieval, and to prioritize exact stabletaskKeymatches. - Extended MCP
createTaskparent resolution to acceptparentTaskIdorparentTaskKey, with validation for ambiguous inputs and boundary enforcement. - Updated MCP instructions/docs and added regression tests covering the new search and parent-resolution behavior.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/web/src/lib/tasks.server.ts | Adjusts task search term handling, adds exact-key fast path/boost, and changes candidate retrieval strategy for relevance ranking. |
| packages/web/src/lib/mcp-server.ts | Allows createTask to resolve parent by stable key, enforces OAuth/client-access boundaries, and tightens parent validation rules. |
| packages/web/src/lib/mcp-instructions.ts | Updates first-run MCP client guidance to direct agents toward optimitron:dev and the new parent-key workflow. |
| packages/web/src/lib/tests/tasks.server.test.ts | Adds/updates regressions for OR-ranked term search and exact-key prioritization behavior. |
| packages/web/src/lib/tests/mcp-tool-catalog.test.ts | Ensures the MCP instruction string continues to mention how to target the canonical dev root. |
| packages/web/src/lib/tests/mcp-server.test.ts | Adds regressions for tool dispatch, parent-key resolution, ambiguous-parent rejection, and client-boundary enforcement. |
| docs/MCP_SERVER.md | Fixes/extends MCP guide examples and adds a documented Optimitron development task creation flow. |
Suppressed comments (1)
packages/web/src/lib/tests/mcp-tool-catalog.test.ts:60
- This test currently enshrines the ambiguous
parentTaskKey "optimitron:dev"phrasing from MCP_SERVER_INSTRUCTIONS. If the instructions are updated to the clearerparentTaskKey='optimitron:dev'form, this assertion should be updated to match so the catalog test continues validating the intended guidance.
: undefined,
).toEqual(["taskId", "completionEvidence"]);
expect(completeClaim?.description).toContain(
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
PR review packetStart here
No user-facing page or component changes were inferred from changed files or the visual review manifest. Changed files considered
Updated automatically when this PR's preview or visual review reruns. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/web/src/lib/mcp-server.ts (1)
14858-14894: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winWrite-conflict replay check does not recognize
parentTaskKeyrequests.At Line 14884, the idempotency check compares
existingTask.parentTaskId === optionalString(a.parentTaskId). When the originalcreateTaskcall suppliedparentTaskKeyinstead ofparentTaskId,a.parentTaskIdisundefined, butexistingTask.parentTaskIdholds the real resolved ID string. The comparison always fails forparentTaskKeyrequests, so a retried call after a unique-constraint race never matches the replay condition.The pre-creation duplicate check earlier in the same case block (around Line 10958) avoids this by comparing against the resolved
parentTaskIdlocal variable. That variable is scoped to thecreateTaskcase block and is not visible in this shared catch handler, which is why the catch block reads the raw request field instead.Resolve the request's parent reference the same way before comparing, so retries using
parentTaskKeyget the correct idempotent-replay result instead of a spuriousWRITE_CONFLICT.🔧 Proposed fix
+ const requestedParentTaskId = optionalString(a.parentTaskId); + const requestedParentTaskKey = optionalString(a.parentTaskKey); + const resolvedRequestedParentId = + requestedParentTaskId ?? + (requestedParentTaskKey + ? ( + await prisma.task.findFirst({ + where: { + deletedAt: null, + taskKey: requestedParentTaskKey, + }, + select: { id: true }, + }) + )?.id + : undefined); if ( existingTask?.taskKey === taskKey && existingTask.title === optionalString(a.title) && - existingTask.parentTaskId === optionalString(a.parentTaskId) + existingTask.parentTaskId === resolvedRequestedParentId ) {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/web/src/lib/mcp-server.ts` around lines 14858 - 14894, Update the write-conflict replay check in the shared handler around createTaskReplayResult to resolve the request’s parent reference through the same parentTaskKey/parentTaskId lookup used by the createTask flow before comparing it with existingTask.parentTaskId. Use the resolved parent ID for both request forms, while preserving the existing title and task-key comparisons and replay behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/web/src/lib/mcp-server.ts`:
- Around line 14858-14894: Update the write-conflict replay check in the shared
handler around createTaskReplayResult to resolve the request’s parent reference
through the same parentTaskKey/parentTaskId lookup used by the createTask flow
before comparing it with existingTask.parentTaskId. Use the resolved parent ID
for both request forms, while preserving the existing title and task-key
comparisons and replay behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 9a0a013b-a8bf-482e-a96d-f34faaecc5e3
📒 Files selected for processing (7)
docs/MCP_SERVER.mdpackages/web/src/lib/__tests__/mcp-server.test.tspackages/web/src/lib/__tests__/mcp-tool-catalog.test.tspackages/web/src/lib/__tests__/tasks.server.test.tspackages/web/src/lib/mcp-instructions.tspackages/web/src/lib/mcp-server.tspackages/web/src/lib/tasks.server.ts
Why
An AI agent asked to record an Optimitron improvement could not reliably find the canonical development parent.
searchTasksrequired every natural-language term to match, whilecreateTaskrequired the parent's opaque database ID. That combination encourages orphaned tasks, duplicate tasks, or no task at all instead of keeping development work in the EV-ranked Optimitron queue.What changed
createTaskresolve eitherparentTaskIdor an exactparentTaskKey, with the same account and OAuth-client access boundariesoptimitron:devsearch, deduplication, and creation flowcreateTaskexample and add a valid development-task exampleValidation
vitest: 276 focused tests passed after rebasing onto current maintsc --noEmit --project tsconfig.next.jsontsc --noEmit --project tsconfig.tests.jsongit diff --checkNo UI surfaces changed, so screenshot review is not applicable.
Summary by CodeRabbit
New Features
optimitron:devroot.Bug Fixes