Skip to content

Commit a75fa5d

Browse files
committed
BACK-558 - Resolve MCP project root from client workspace roots
The MCP server froze its project root at startup and only consulted MCP roots in fallback mode, so a shared/user-scope server (or one launched in the main checkout while working in a git worktree) wrote tasks to the wrong backlog directory. Unify startup and fallback resolution into one request-scoped resolver: a --cwd/BACKLOG_CWD pin wins; otherwise client workspace roots are authoritative and re-resolved on roots/list_changed; a launch-directory project is kept only when nested inside an advertised root; clients without the roots capability keep process.cwd() behavior. Closes #558
1 parent d6fcf24 commit a75fa5d

5 files changed

Lines changed: 450 additions & 203 deletions

File tree

README.md

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
![Backlog demo GIF using: backlog board](./.github/backlog-v1.40.gif)
99

10-
1110
---
1211

1312
> **Backlog.md** turns any folder with a Git repo into a **self‑contained project board**
@@ -16,27 +15,26 @@
1615
1716
## Features
1817

19-
* 📝 **Markdown-native tasks** -- manage every issue as a plain `.md` file
20-
21-
* 🤖 **AI-Ready** -- Works with Claude Code, Gemini CLI, Codex, Kiro & any other MCP or CLI compatible AI assistants
18+
- 📝 **Markdown-native tasks** -- manage every issue as a plain `.md` file
2219

23-
* 📊 **Instant terminal Kanban** -- `backlog board` paints a live board in your shell
20+
- 🤖 **AI-Ready** -- Works with Claude Code, Gemini CLI, Codex, Kiro & any other MCP or CLI compatible AI assistants
2421

25-
* 🌐 **Modern web interface** -- `backlog browser` launches a sleek web UI for visual task management
22+
- 📊 **Instant terminal Kanban** -- `backlog board` paints a live board in your shell
2623

27-
* 🔍 **Powerful search** -- fuzzy search across tasks, docs & decisions with `backlog search`
24+
- 🌐 **Modern web interface** -- `backlog browser` launches a sleek web UI for visual task management
2825

29-
* 📋 **Rich query commands** -- view, list, filter, or archive tasks with ease
30-
***Definition of Done defaults** -- add a reusable checklist to every new task
26+
- 🔍 **Powerful search** -- fuzzy search across tasks, docs & decisions with `backlog search`
3127

32-
* 📤 **Board export** -- `backlog board export` creates shareable markdown reports
28+
- 📋 **Rich query commands** -- view, list, filter, or archive tasks with ease
29+
-**Definition of Done defaults** -- add a reusable checklist to every new task
3330

34-
* 🔒 **100 % private & offline** -- backlog lives entirely inside your repo and you can manage everything locally
31+
- 📤 **Board export** -- `backlog board export` creates shareable markdown reports
3532

36-
* 💻 **Cross-platform** -- runs on macOS, Linux, and Windows
33+
- 🔒 **100 % private & offline** -- backlog lives entirely inside your repo and you can manage everything locally
3734

38-
* 🆓 **MIT-licensed & open-source** -- free for personal or commercial use
35+
- 💻 **Cross-platform** -- runs on macOS, Linux, and Windows
3936

37+
- 🆓 **MIT-licensed & open-source** -- free for personal or commercial use
4038

4139
---
4240

@@ -56,6 +54,7 @@ backlog init "Personal Planning" --no-git
5654
```
5755

5856
The init wizard will ask how you want to connect AI tools:
57+
5958
- **MCP connector** (recommended) — auto-configures Claude Code, Codex, Gemini CLI, Kiro or Cursor and adds workflow instructions for your agents.
6059
- **CLI commands** — creates instruction files (CLAUDE.md, AGENTS.md, etc.) so agents use Backlog via CLI.
6160
- **Skip** — no AI setup; use Backlog.md purely as a task manager.
@@ -72,6 +71,7 @@ After running `backlog init` and choosing the MCP or CLI integration, work in th
7271
**Step 1 — Describe your idea.** Tell the agent what you want to build and ask it to split the work into small tasks with clear descriptions and acceptance criteria.
7372

7473
**🤖 Ask your AI Agent:**
74+
7575
> I want to add a search feature to the web view that searches tasks, docs, and decisions. Please decompose this into small Backlog.md tasks.
7676
7777
> [!NOTE]
@@ -82,6 +82,7 @@ After running `backlog init` and choosing the MCP or CLI integration, work in th
8282
**Step 3 — Plan before coding.** Ask the agent to research and write an implementation plan in the task. Do this right before implementation so the plan reflects the current state of the codebase.
8383

8484
**🤖 Ask your AI Agent:**
85+
8586
> Work on BACK-10 only. Research the codebase and write an implementation plan in the task. Wait for my approval before coding.
8687
8788
> [!NOTE]
@@ -137,6 +138,7 @@ backlog browser --no-open
137138
```
138139

139140
**Features:**
141+
140142
- Interactive Kanban board with drag-and-drop
141143
- Task creation and editing with rich forms
142144
- Interactive acceptance criteria editor with checklists
@@ -161,43 +163,56 @@ You can run `backlog init` (even if you already initialized Backlog.md) to set u
161163
<details>
162164
<summary><strong>Claude Code</strong></summary>
163165

164-
```bash
165-
claude mcp add backlog --scope user -- backlog mcp start
166-
```
166+
```bash
167+
claude mcp add backlog --scope user -- backlog mcp start
168+
```
167169

168170
</details>
169171

170172
<details>
171173
<summary><strong>Codex</strong></summary>
172174

173-
```bash
174-
codex mcp add backlog -- backlog mcp start
175-
```
175+
```bash
176+
codex mcp add backlog -- backlog mcp start
177+
```
176178

177179
</details>
178180

179181
<details>
180182
<summary><strong>Gemini CLI</strong></summary>
181183

182-
```bash
183-
gemini mcp add backlog -s user backlog mcp start
184-
```
184+
```bash
185+
gemini mcp add backlog -s user backlog mcp start
186+
```
185187

186188
</details>
187189

188190
<details>
189191
<summary><strong>Kiro</strong></summary>
190192

191-
```bash
192-
kiro-cli mcp add --scope global --name backlog --command backlog --args mcp,start
193-
```
193+
```bash
194+
kiro-cli mcp add --scope global --name backlog --command backlog --args mcp,start
195+
```
194196

195197
</details>
196198

197-
Use the shared `backlog` server name everywherethe MCP server auto-detects whether the current directory is initialized and falls back to `backlog://init-required` when needed.
199+
Use the shared `backlog` server name everywhere. The MCP server follows your editor's active workspace: it reads the client's MCP roots to locate the project, re-resolves when you switch workspace or git worktree, and falls back to `backlog://init-required` when the workspace has no backlog project yet. A single user-scope server therefore works across all your projects.
198200

199201
### Manual config
200202

203+
```json
204+
{
205+
"mcpServers": {
206+
"backlog": {
207+
"command": "backlog",
208+
"args": ["mcp", "start"]
209+
}
210+
}
211+
}
212+
```
213+
214+
Pinning to one project: set `BACKLOG_CWD` (or pass `--cwd`) to fix the server on a single backlog and turn off workspace following. This is useful when you want every session to target the same backlog (for example one global backlog), or when your client does not advertise MCP roots and cannot set the process working directory.
215+
201216
```json
202217
{
203218
"mcpServers": {
@@ -212,15 +227,13 @@ Use the shared `backlog` server name everywhere – the MCP server auto-detects
212227
}
213228
```
214229

215-
If your IDE can't set the process working directory for MCP servers, set `BACKLOG_CWD` as shown above.
216-
If your IDE supports custom args but not env vars, you can also use `["mcp", "start", "--cwd", "/absolute/path/to/your/project"]`.
230+
If your client supports custom args but not env vars, use `["mcp", "start", "--cwd", "/absolute/path/to/your/project"]` instead.
217231

218232
> [!IMPORTANT]
219233
> When adding the MCP server manually, you should add some extra instructions in your CLAUDE.md/AGENTS.md files to inform the agent about Backlog.md.
220234
> This step is not required when using `backlog init` as it adds these instructions automatically.
221235
> Backlog.md's instructions for agents are available at [`/src/guidelines/mcp/agent-nudge.md`](/src/guidelines/mcp/agent-nudge.md).
222236
223-
224237
Once connected, agents can read the Backlog.md workflow instructions via the resource `backlog://docs/task-workflow`.
225238
Use `/mcp` command in your AI tool (Claude Code, Codex, Kiro) to verify if the connection is working.
226239

@@ -249,6 +262,7 @@ Backlog.md merges the following layers (highest → lowest):
249262
### Interactive wizard (`backlog config`)
250263

251264
Run `backlog config` with no arguments to launch the full interactive wizard. This is the same experience triggered from `backlog init` when you opt into advanced settings, and it walks through the complete configuration surface:
265+
252266
- Cross-branch accuracy: `checkActiveBranches`, `remoteOperations`, and `activeBranchDays`.
253267
- Git workflow: `autoCommit` and `bypassGitHooks`.
254268
- ID formatting: enable or size `zeroPaddedIds`.
@@ -257,6 +271,7 @@ Run `backlog config` with no arguments to launch the full interactive wizard. Th
257271
- Web UI defaults: choose `defaultPort` and whether `autoOpenBrowser` should run.
258272

259273
Skipping the wizard (answering "No" during init) applies the safe defaults that ship with Backlog.md:
274+
260275
- `checkActiveBranches=true`, `remoteOperations=true`, `activeBranchDays=30`.
261276
- `autoCommit=false`, `bypassGitHooks=false`.
262277
- `zeroPaddedIds` disabled.

src/commands/mcp.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ function registerStartCommand(mcpCmd: Command): void {
3838
try {
3939
const runtimeCwd = await resolveRuntimeCwd({ cwd: options.cwd });
4040
const projectRoot = (await findBacklogRoot(runtimeCwd.cwd)) ?? runtimeCwd.cwd;
41-
const server = await createMcpServer(projectRoot, { debug: options.debug });
41+
// An explicit --cwd/BACKLOG_CWD pins the root; an inferred process.cwd()
42+
// lets the server follow the client's workspace roots instead.
43+
const pinned = runtimeCwd.source !== "process";
44+
const server = await createMcpServer(projectRoot, { debug: options.debug, pinned });
4245

4346
await server.connect();
4447
await server.start();

0 commit comments

Comments
 (0)