# Troubleshoot Archcore

> Diagnose missing MCP tools, wrong project context, installation failures, and document or hook errors.

Archcore troubleshooting starts with the symptom: a missing tool, incorrect project context, or a failed document operation. Run `archcore status` and `archcore doctor` in the affected repository, then follow the matching section.

## Agent cannot see documents

[Section titled “Agent cannot see documents”](#agent-cannot-see-documents)

Your agent says it can’t find any documents, or it doesn’t seem to know about Archcore at all. Work through the checks below in order, most common first.

### MCP not configured

[Section titled “MCP not configured”](#mcp-not-configured)

The agent needs an MCP server configuration to connect to Archcore. Without it, the agent has no way to discover or read your project context.

**Check:** Look for the MCP config file for your agent:

| Agent          | Config file                           |
| -------------- | ------------------------------------- |
| Claude Code    | `.mcp.json`                           |
| Cursor         | `.cursor/mcp.json`                    |
| GitHub Copilot | `.mcp.json` (shared with Claude Code) |
| Gemini CLI     | `.gemini/settings.json`               |
| OpenCode       | `opencode.json`                       |
| Codex CLI      | `.codex/config.toml`                  |
| Roo Code       | `.roo/mcp.json`                       |
| Cline          | VS Code globalStorage (manual setup)  |

**Fix:** Run the setup command:

```bash
archcore mcp install
```

Or re-run full initialization, which also installs hooks:

```bash
archcore init
```

Both commands auto-detect your agents and write the correct config files. See [Agent integrations](/guides/connect-your-agent/) for the full agent registry.

### Config points to wrong command

[Section titled “Config points to wrong command”](#config-points-to-wrong-command)

The MCP config JSON tells the agent what command to run. If the `command` or `args` fields are wrong, the server won’t start and the agent won’t see any documents.

**Check:** Open your agent’s MCP config file and verify it matches this structure:

```json
{
  "mcpServers": {
    "archcore": {
      "command": "archcore",
      "args": ["mcp"]
    }
  }
}
```

Cursor is the exception: in `.cursor/mcp.json` the CLI writes `"args": ["mcp", "--project", "${workspaceFolder}"]` on purpose, because Cursor does not guarantee the working directory it launches MCP servers with. Do not replace it with the bare `["mcp"]` template.

**Fix:** Regenerate the config:

```bash
archcore mcp install
```

See [Agent integrations](/guides/connect-your-agent/) for config file locations per agent.

### Archcore not in PATH

[Section titled “Archcore not in PATH”](#archcore-not-in-path)

The MCP server runs as a subprocess: your agent executes `archcore mcp`. If the `archcore` binary isn’t in your shell PATH, the agent can’t launch it and reports “command not found.”

**Check:**

```bash
which archcore
```

If this returns nothing, the binary isn’t in your PATH.

**Fix:** Add the directory containing `archcore` to your PATH. The exact location depends on how you installed it:

* **macOS / Linux (install.sh):** typically `~/.local/bin/archcore` or `/usr/local/bin/archcore`. Add to your shell profile (`~/.bashrc`, `~/.zshrc`, or equivalent).
* **Windows (install.ps1):** typically `%LOCALAPPDATA%\Programs\archcore\archcore.exe`. The installer adds this directory to your user `PATH` automatically. If it’s missing, open a new PowerShell window or re-run the installer.

Then verify:

```bash
archcore --version
```

If you haven’t installed Archcore yet, follow [Install](/start/install/).

### Wrong working directory

[Section titled “Wrong working directory”](#wrong-working-directory)

The MCP server looks for `.archcore/` relative to the current project root. If you opened your editor in a parent directory, a subdirectory, or a different project entirely, the server won’t find your documents.

**Check:**

```bash
ls .archcore/
```

If this shows “No such file or directory,” you’re not in the right project root.

**Fix:** Open your editor or terminal in the directory that contains `.archcore/`. For multi-root workspaces, make the project with `.archcore/` the active workspace root.

If the agent launches `archcore mcp` from a fixed directory you can’t change (e.g., a desktop app or a profile-scoped runner), pin the project root in the MCP config instead:

* **Flag:** `archcore mcp --project /absolute/path/to/repo`
* **Environment:** set `ARCHCORE_PROJECT_ROOT=/absolute/path/to/repo` in the agent’s environment.

See [Pointing the server at a project root](/guides/connect-your-agent/#pointing-the-server-at-a-project-root) for the full config example.

When the root is not pinned with `--project` or `ARCHCORE_PROJECT_ROOT`, the server follows the working directory the client reports (see [Following the session’s working directory](/guides/connect-your-agent/#following-the-sessions-working-directory)). When the server refuses a reported directory, it keeps the current root and writes one line to stderr per distinct reason: the directory holds no `.archcore/`, it sits inside a plugin install cache, or a global source declared there is misconfigured. A declared global that is only missing from disk does not block the switch. The tool call itself still succeeds.

If you haven’t initialized the project yet:

```bash
archcore init
```

### Hooks not installed

[Section titled “Hooks not installed”](#hooks-not-installed)

Without session hooks, the agent doesn’t receive project context when a conversation starts. The agent can still use MCP tools if configured, but it won’t proactively check for documents.

**Check:** For Claude Code, look for the hook in `.claude/settings.json`:

```json
{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "archcore hooks claude-code session-start"
          }
        ]
      }
    ]
  }
}
```

**Fix:**

```bash
archcore hooks install
```

This installs hooks for all detected agents. See [Hooks](/guides/connect-your-agent/#lifecycle-hooks) for agent-specific details.

If hooks are installed but still not firing:

1. Re-run `archcore hooks install` and read the notes it prints. A host that cannot run the written config says so, with the reason and the fix.
2. Verify the config file holds archcore entries.
3. Ensure `archcore` is on your `PATH`.
4. On Codex CLI, enable the hooks feature (`[features]` with `hooks = true` in `~/.codex/config.toml`; `codex_hooks = true` before Codex 0.129.0) and trust the project’s `.codex/` layer.
5. Check the agent’s logs for hook execution errors.

### Config was reset after an install

[Section titled “Config was reset after an install”](#config-was-reset-after-an-install)

**What you see:** After `archcore init`, `archcore hooks install`, or `archcore mcp install`, an agent config file lost its previous content, and the install warned that the file was backed up.

**Why it happens:** The file held invalid JSON, so Archcore backed it up to `{path}.bak` and started from a fresh config. When the backup write itself fails, the install aborts instead: the original is never overwritten without a confirmed backup.

**Fix:** Restore the backup, correct the JSON, and re-run the installer:

```bash
cp .cursor/hooks.json.bak .cursor/hooks.json
archcore hooks install --agent cursor
```

`.codex/config.toml` is TOML and sits outside the `.bak` policy; Codex hook wiring lives in a separate `.codex/hooks.json`. See [corrupt config handling](/guides/connect-your-agent/#corrupt-config-handling) for the full policy per file.

### Agent doesn’t support MCP

[Section titled “Agent doesn’t support MCP”](#agent-doesnt-support-mcp)

Some agents or agent modes don’t support the Model Context Protocol. If your agent isn’t in the [agent integrations](/guides/connect-your-agent/) list, it can’t connect to the Archcore MCP server.

**Supported agents:** Claude Code, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Codex CLI, and Roo Code. Archcore writes the MCP config for each of these.

Cline is also supported, but its MCP config lives in VS Code `globalStorage` rather than a project file, so `archcore mcp install` cannot write it. Add the Archcore server through Cline’s own MCP settings interface.

If your agent isn’t listed, you can still use Archcore documents manually. They are standard Markdown files in `.archcore/` that any tool can read.

### Documents exist but agent says none found

[Section titled “Documents exist but agent says none found”](#documents-exist-but-agent-says-none-found)

The agent connects to MCP successfully but reports zero documents. The server is reading a directory that holds no documents. The MCP scan indexes every `.md` file under `.archcore/` except hidden directories, symlinks, and the meta files `settings.json` and `.sync-state.json`; a malformed document is still listed, with an empty title and status. Validation errors do not hide documents from the MCP tools.

**Common causes:**

* The server resolved the wrong project root. See [Wrong working directory](#wrong-working-directory).
* The project is not initialized: there is no `.archcore/` directory.
* The files sit outside `.archcore/`.

**Check:**

```bash
ls .archcore/
archcore status
```

`archcore status` reports any issues with file naming, frontmatter, or document structure. Those issues do not explain a zero count, but they do need fixing.

**Fix:** Point the server at the directory that contains `.archcore/`, or run `archcore init` and move the documents under `.archcore/`. Then correct the issues reported by `archcore status`. See [Validation errors](#validation-errors) below for detailed guidance on each error type.

## MCP server not starting

[Section titled “MCP server not starting”](#mcp-server-not-starting)

The MCP server runs as a subprocess that your coding agent launches automatically. When it fails to start, the agent either reports an MCP error or silently loses access to your repo context.

### Permission denied

[Section titled “Permission denied”](#permission-denied)

On macOS and Linux, the binary needs execute permissions. The install script sets this automatically, but manual downloads or file transfers can strip it.

**Check:**

```bash
ls -l $(which archcore)
```

Look for `x` in the permissions (e.g., `-rwxr-xr-x`).

**Fix:**

```bash
chmod +x $(which archcore)
```

### Multiple archcore versions

[Section titled “Multiple archcore versions”](#multiple-archcore-versions)

If you have multiple installations (e.g., a global install and a project-local one), the agent might pick up the wrong version.

**Check:**

```bash
which archcore
archcore --version
```

On some systems, you can also check for duplicates:

```bash
which -a archcore
```

**Fix:** Remove the extra installation, or ensure your PATH resolves to the correct one first. After fixing, regenerate the config:

```bash
archcore mcp install
```

### Missing or invalid global source

[Section titled “Missing or invalid global source”](#missing-or-invalid-global-source)

If your `settings.json` declares a [global source](/cli/configuration/#global-sources) whose directory isn’t on disk, the server still starts (CLI v0.10.7 and later) and serves the local documents. The missing source mounts no documents, so an empty search result says nothing about it.

**What you see** on the server’s stderr, and as a warning in `archcore status` and the SessionStart `GLOBALS` block:

```text
global source "company-standards" not found at "../company-standards/.archcore" — starting without it
```

**Fix:** Clone or vendor the source so the `path` resolves, or remove the entry from `globals` if you no longer need it. For a source that ships with the repo, [vendor it in-tree](/cli/configuration/#vendoring-a-global-in-tree) under `.archcore/global/`. A source that exists but is unreadable, not a directory, a duplicate path, or the project’s own `.archcore/` still aborts startup with `— fix .archcore/settings.json before starting the MCP server`.

The message `invalid .archcore/settings.json: …` means the file itself is malformed. The server aborts rather than start with globals silently dropped. Run `archcore doctor` to see the exact parse or validation error.

When the source is declared with a `../` path and the CLI runs inside a linked git worktree, a CLI older than v0.8.2 reports it as missing, because the worktree does not share the main checkout’s parent directory. CLI v0.8.2 and later resolve the path from the main checkout. See [How `path` resolves](/cli/configuration/#how-path-resolves).

On non-server surfaces a missing global never blocks you: the session-start hook degrades to a local-only context summary with a warning naming the source, and `archcore status` reports it as a visible failure while still running its local checks.

### Server refuses to start inside a plugin cache

[Section titled “Server refuses to start inside a plugin cache”](#server-refuses-to-start-inside-a-plugin-cache)

**What you see:**

```text
refusing project root "…": path is inside an AI-host plugin install cache, not a user project
```

**Why it happens:** The host launched `archcore mcp` from a plugin install cache (for example `~/.copilot/installed-plugins/…`), and the server resolved that directory as the implicit project root. Serving a cache would read the plugin’s bundled documents as if they were yours and write your documents into a directory the next plugin update deletes, so the server refuses loudly.

**Fix:** Pass the real project root explicitly. `--project` is trusted as given:

```bash
archcore mcp --project /absolute/path/to/repo
```

Or register a project-level server with `archcore init --agent <agent> --project <path>`.

### ”Cannot update a read-only global source document”

[Section titled “”Cannot update a read-only global source document””](#cannot-update-a-read-only-global-source-document)

**What you see:** A write tool (`create_document`, `update_document`, `remove_document`) or `add_relation` is rejected because the target is a global document.

This is working as intended: globals are read-only and are never relation endpoints. Make the change upstream in the source repository, and link **local → local** documents instead of linking to a global. See [Read-only everywhere](/cli/configuration/#read-only-everywhere).

## Context appears twice

[Section titled “Context appears twice”](#context-appears-twice)

**What you see:** The session recap or a hook advisory shows up twice in one session.

**Why it happens:** An older Archcore plugin still ships its own hooks, so both its entries and the CLI’s fire.

**Fix:** Update the plugin. Until then the duplication costs extra output, never a wrong verdict.

## Install and update failures

[Section titled “Install and update failures”](#install-and-update-failures)

Errors from the install scripts and `archcore update`:

| Message                                                | Cause and fix                                                                                                                                                                                                                                                      |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Could not reach https://github.com/…/releases/latest` | A network, proxy, or DNS problem. No API rate limit is involved, so `GITHUB_TOKEN` does not help. Pin a version instead: `ARCHCORE_VERSION=v1.0.0`.                                                                                                                |
| `Could not check for updates`                          | A network problem, or `github.com` answered with something other than a redirect: a captive portal, a proxy interstitial, or an outage. Retry later. No API rate limit applies; the check reads the `github.com` web redirect, which needs no token.               |
| `unexpected redirect resolving latest release`         | The redirect landed somewhere that is not a `/releases/tag/` page. Two causes occur in practice: a proxy or captive portal intercepting the request, or a repository with no published release, which GitHub answers with a redirect to the bare `/releases` page. |
| `no Location header` / `parsing redirect location`     | A redirect arrived without a usable `Location`. This indicates an intercepting proxy rather than GitHub.                                                                                                                                                           |
| `Checksum verification failed` / `Checksum mismatch`   | The download was corrupted. Run the install or `archcore update` again.                                                                                                                                                                                            |
| `Unsupported operating system/architecture`            | Prebuilt binaries cover `darwin`, `linux`, and `windows` on `amd64` and `arm64` only.                                                                                                                                                                              |
| `this installer requires bash`                         | The script was piped into `sh` or another POSIX shell. Pipe into `bash` instead.                                                                                                                                                                                   |
| `Update failed` with a permission error                | The binary sits in a directory without write access. Reinstall it to a writable location, or run `archcore update` with `sudo`.                                                                                                                                    |

See [Install the CLI](/start/install/) for the install options and prerequisites.

### A development build updates on every run

[Section titled “A development build updates on every run”](#a-development-build-updates-on-every-run)

While `archcore --version` reports `dev`, `archcore update` downloads the latest release on every run: a development build compares as always behind. The unattended path refuses a `dev` build instead.

### The background update never runs

[Section titled “The background update never runs”](#the-background-update-never-runs)

`archcore mcp` starts one unattended attempt 60 seconds after it begins serving, and the attempt stops at the first condition that does not hold. Walk the conditions in order under [Unattended update](/start/install/#unattended-update). A binary built with `go build` carries no official-build marker, so it stops at condition 1, which is the intended behavior for a local build.

## Validation errors

[Section titled “Validation errors”](#validation-errors)

`archcore status` checks every document in `.archcore/` for correct naming, structure, and frontmatter.

### Invalid filename

[Section titled “Invalid filename”](#invalid-filename)

**What you see:** The file doesn’t match the `slug.type.md` pattern.

**Why it happens:** Slugs must be lowercase alphanumeric with hyphens only. The filename must follow the exact format `slug.type.md`, with no extra dots, spaces, or underscores.

**Examples of invalid names:**

| Filename                  | Problem                |
| ------------------------- | ---------------------- |
| `My Decision.adr.md`      | Spaces and uppercase   |
| `jwt_strategy.adr.md`     | Underscores            |
| `UsePostgres.adr.md`      | Uppercase letters      |
| `api.v2.migration.adr.md` | Extra dots in the slug |

**Fix:** Rename the file to use a valid slug:

```bash
mv ".archcore/My Decision.adr.md" ".archcore/my-decision.adr.md"
mv ".archcore/jwt_strategy.adr.md" ".archcore/jwt-strategy.adr.md"
```

Slugs must match `^[a-z0-9]+(-[a-z0-9]+)*$`. See [Document format](/reference/document-format/) for the full spec.

### Unknown document type

[Section titled “Unknown document type”](#unknown-document-type)

**What you see:** The type portion of the filename isn’t recognized.

**Why it happens:** The type (the middle part of `slug.type.md`) must be one of the 23 valid types.

**Valid types:**

```text
adr, rfc, rule, guide, spec, doc, evidence, prd, idea, plan, rnd, research,
task-type, cpat, mrd, brd, urd, brs, strs, syrs, srs
```

`research` is a vision type and `evidence` is a knowledge type.

**Common mistakes:**

| Filename                | Problem                   | Fix                                               |
| ----------------------- | ------------------------- | ------------------------------------------------- |
| `auth.decision.md`      | `decision` is not a type  | Rename to `auth.adr.md`                           |
| `setup.tutorial.md`     | `tutorial` is not a type  | Rename to `setup.guide.md`                        |
| `api-spec.reference.md` | `reference` is not a type | Rename to `api-spec.spec.md` or `api-spec.doc.md` |

**Fix:** Rename the file using one of the 23 valid types. See [Document types](/concepts/document-types/) for guidance on choosing.

### Missing frontmatter

[Section titled “Missing frontmatter”](#missing-frontmatter)

**What you see:** The document is missing YAML frontmatter, or the frontmatter is missing required fields.

**Why it happens:** Every Archcore document requires YAML frontmatter with both `title` and `status` fields.

**Fix:** Add the required frontmatter at the top of the file:

```markdown
---
title: Use PostgreSQL as Primary Database
status: draft
---


Your document content here...
```

Both fields are required:

| Field    | Type   | Required values                    |
| -------- | ------ | ---------------------------------- |
| `title`  | string | Any non-empty string               |
| `status` | string | `draft`, `accepted`, or `rejected` |

### Invalid status

[Section titled “Invalid status”](#invalid-status)

**What you see:** The `status` field contains an unrecognized value.

**Why it happens:** Status must be exactly one of three values. Archcore rejects `active`, `approved`, and `archived`.

| Status     | Meaning                                      |
| ---------- | -------------------------------------------- |
| `draft`    | Work in progress (default for new documents) |
| `accepted` | Finalized or approved                        |
| `rejected` | Superseded, abandoned, or declined           |

**Fix:** Update the frontmatter to use a valid status.

### Orphaned relations

[Section titled “Orphaned relations”](#orphaned-relations)

**What you see:** A relation points to a document that no longer exists on disk.

**Why it happens:** You deleted or renamed a document, but the relation referencing it still exists in `.sync-state.json`.

**Fix:**

```bash
archcore doctor --fix
```

This automatically removes orphaned relations from the manifest before running checks.

### Invalid tags

[Section titled “Invalid tags”](#invalid-tags)

**What you see:** A tag doesn’t match the required format.

**Why it happens:** Tags must be lowercase and match `^[a-z][a-z0-9_:|-]*$`.

| Tag         | Problem                  |
| ----------- | ------------------------ |
| `Frontend`  | Uppercase letters        |
| `my tag`    | Spaces                   |
| `123-start` | Must start with a letter |

**Fix:** Correct the tag value. When Archcore rejects a tag, it prints a “did you mean?” hint.

### Invalid YAML

[Section titled “Invalid YAML”](#invalid-yaml)

**What you see:** The frontmatter can’t be parsed as valid YAML.

**Why it happens:** Syntax error between the `---` delimiters. Common causes:

* Missing closing `---`
* Tabs instead of spaces
* Unquoted special characters (colons, brackets) in values

**Fix:** Correct the YAML syntax. If unsure, start with a minimal frontmatter block:

```yaml
---
title: Your Title Here
status: draft
---
```

### Using `--fix`

[Section titled “Using --fix”](#using---fix)

`archcore doctor --fix` automates what it can:

* Removes orphaned relations from `.sync-state.json` and saves the cleaned manifest before running checks
* Converges host wiring by re-running the hook and MCP installers per agent; `--agent <id>` narrows the pass to the named agents

The installers touch only the fields Archcore owns: a stale hook command or a drifted MCP entry is rewritten, and your own fields survive. See [`archcore doctor`](/cli/commands/#archcore-doctor) for what `--fix` writes.

It does **not** auto-fix invalid filenames, missing frontmatter, unknown document types, or YAML syntax. Correct those manually.

For a full project health check:

```bash
archcore doctor
```

See [Commands](/cli/commands/) for details.

## `/archcore:*` commands don’t appear

[Section titled “/archcore:\* commands don’t appear”](#archcore-commands-dont-appear)

**Symptom:** Typing `/archcore:` doesn’t autocomplete, or the list is missing `init`, `plan`, `document`, or `review`.

**Checks, in order:**

1. **Plugin is installed.**

   ```bash
   # Claude Code
   claude plugin list
   # Cursor: check plugin settings
   ```

   You should see `archcore@archcore-plugins`.

2. **Host was restarted.** Plugins load at startup. After installing or updating, restart the host.

3. **Session-start hook ran.** Look at the session opening messages for a short “Archcore context loaded” line. If it is missing, the hook didn’t fire.

4. **Run `archcore doctor` from your shell.** The CLI validates `.archcore/` integrity. For plugin-side install issues (missing skills, hook scripts, manifest problems), reinstall via the marketplace. See [Install the plugin](/start/install/).

## MCP server not found (Cursor)

[Section titled “MCP server not found (Cursor)”](#mcp-server-not-found-cursor)

Cursor does not auto-register plugin-provided MCP. Copy `docs/cursor.mcp.example.json` from the plugin into `~/.cursor/mcp.json` (user-scoped) or `.cursor/mcp.json` (project-scoped):

```json
{
  "mcpServers": {
    "archcore": {
      "type": "stdio",
      "command": "archcore",
      "args": ["mcp", "--project", "${workspaceFolder}"]
    }
  }
}
```

**Keep the `--project ${workspaceFolder}` argument.** Without it, a single registration reads one project’s `.archcore/` across every Cursor window. Then verify that the CLI itself resolves:

```bash
archcore --version
```

If that fails, install via <https://docs.archcore.ai/start/install/> and relaunch Cursor.

## Cursor: MCP attached to the wrong project

[Section titled “Cursor: MCP attached to the wrong project”](#cursor-mcp-attached-to-the-wrong-project)

**Symptom:** MCP tools answer from a different project’s `.archcore/` than the one currently open in Cursor.

Your Cursor MCP registration is missing the `--project ${workspaceFolder}` argument (or has a literal path baked in). Without it, Cursor reuses the first registration across every window and the MCP server reads whichever `.archcore/` that initial registration was scoped to. Re-copy the `docs/cursor.mcp.example.json` template and restart Cursor.

## Automatic context injection didn’t fire

[Section titled “Automatic context injection didn’t fire”](#automatic-context-injection-didnt-fire)

**Symptom:** You expected the agent to see relevant rules / ADRs before editing `src/...`, but it didn’t, and no context summary was printed.

The pre-write hook runs the injection, through `archcore hooks <host> pre-tool-use`. It stays silent when:

* The edit target lives under `.archcore/`. That path is the write guard’s business.
* The path is outside your configured source roots. Defaults: `src`, `lib`, `app`, `pkg`, `cmd`, `internal`, `apps`, `packages`, `modules`, `components`. Set `codeAlignment.sourceRoots` in `.archcore/settings.json` to replace that list (a JSON array of directory names).
* No `.archcore/` documents reference that path.
* The env var `ARCHCORE_DISABLE_INJECTION=1` is set.
* The host is GitHub Copilot, whose pre-write event carries only a permission decision.
* The installed CLI is older than v0.7.0. The launcher exits silently rather than risk a usage error reading as a deny.

To verify it’s enabled, unset the env var and ensure the edited file is under one of the configured roots. To turn it off temporarily:

```bash
export ARCHCORE_DISABLE_INJECTION=1
```

The hook never blocks an edit: if it errors, it exits silently. Absence of output does not mean the hook is broken. It usually means the hook found nothing relevant to inject.

## Codex CLI-specific: hooks not firing

[Section titled “Codex CLI-specific: hooks not firing”](#codex-cli-specific-hooks-not-firing)

**Symptom:** On Codex CLI, the validation, cascade, precision, and pre-edit context-injection hooks don’t run.

Codex hooks are gated by Codex’s `hooks` feature. Enable it with `codex --enable hooks`, or add a `[features]` table to `~/.codex/config.toml`:

```toml
[features]
hooks = true
```

Before Codex 0.129.0 the key is spelled `codex_hooks = true`. After you enable the feature, restart the Codex session so it picks up the new hook configuration. If hooks still don’t fire, verify your Codex version is `0.117.0` or later (`codex --version`).

## Codex CLI-specific: `apply_patch` writes not blocked

[Section titled “Codex CLI-specific: apply\_patch writes not blocked”](#codex-cli-specific-apply_patch-writes-not-blocked)

**Symptom:** On Codex CLI, you used Codex’s `apply_patch` tool to edit a `.archcore/*.md` file directly and the hook didn’t block it.

The Codex hooks file (`hooks/codex.hooks.json`) uses the matcher `Write|Edit|apply_patch` precisely to cover all three Codex write surfaces. If the matcher doesn’t appear to be catching `apply_patch`, the most likely cause is that Codex’s `hooks` feature is not enabled (see above). Without the feature, no hook fires, including the `PreToolUse` write guard.

## Codex CLI-specific: MCP server not found

[Section titled “Codex CLI-specific: MCP server not found”](#codex-cli-specific-mcp-server-not-found)

**Symptom:** On Codex CLI, MCP tool calls fail with “server not found” or similar.

The plugin ships `.codex.mcp.json`, referenced from the manifest’s `mcpServers` field. The `command` is `archcore` from `PATH`. Codex inherits the shell’s `PATH` when it spawns the MCP server, so the CLI must be installed globally.

Checks, in order:

1. **Manifest references `.codex.mcp.json`.** Open `.codex-plugin/plugin.json` and verify `"mcpServers": "./.codex.mcp.json"` is present.
2. **`.codex.mcp.json` exists at plugin root.** It should ship with the marketplace install. If missing, reinstall: `codex plugin uninstall archcore`, then `codex plugin marketplace add archcore-ai/archcore --sparse .agents/plugins --sparse plugins/archcore` and re-install Archcore from `/plugins`.
3. **`archcore` is on `PATH` in the shell that launched Codex.** Run `archcore --version` from that shell; if it fails, install via <https://docs.archcore.ai/start/install/> and re-launch Codex.

## Copilot-specific: no Archcore MCP tools in the session

[Section titled “Copilot-specific: no Archcore MCP tools in the session”](#copilot-specific-no-archcore-mcp-tools-in-the-session)

**Symptom:** On GitHub Copilot CLI, the plugin loaded and the commands appear, but every Archcore operation reports that the document tools are unavailable. A session-start line says the project is not wired.

On Copilot the plugin ships no MCP server, so the project-level entry is the only source of document tools. Wire the project once:

```bash
archcore init --agent copilot --project "$PWD"
```

Restart the session afterwards so Copilot connects the server. Copilot discovers `.mcp.json` from the working directory up to the git root, and also reads `${COPILOT_HOME:-~/.copilot}/mcp-config.json`, so a repository-root file wires a subdirectory session too.

The advisory is rate-limited to once per 24 hours per project. Suppress it with `ARCHCORE_HIDE_WIRING_NUDGE=1`.

## Copilot-specific: no context before a source edit

[Section titled “Copilot-specific: no context before a source edit”](#copilot-specific-no-context-before-a-source-edit)

**Symptom:** On GitHub Copilot CLI, the write guard blocks direct `.archcore/` edits, but no rules or ADRs appear before a source-file edit.

Copilot’s `preToolUse` event carries only a permission decision, so it cannot receive advisory context ([github/copilot-cli#2585](https://github.com/github/copilot-cli/issues/2585)). The write guard runs; the code-alignment injection does not. This is a host limitation, not a misconfiguration.

## Copilot-specific: hooks appear to run twice

[Section titled “Copilot-specific: hooks appear to run twice”](#copilot-specific-hooks-appear-to-run-twice)

**Symptom:** Session-start context or post-write findings are printed twice.

Copilot also reads `.claude/settings.json`. A repository wired for both Copilot and Claude Code runs both configurations. The cost is duplicated output, never a wrong verdict.

## Cursor-specific: `afterMCPExecution` not firing

[Section titled “Cursor-specific: afterMCPExecution not firing”](#cursor-specific-aftermcpexecution-not-firing)

**Symptom:** On Cursor, validation and cascade checks don’t run after MCP calls.

Cursor only fires `afterMCPExecution` for successful MCP calls. If the MCP call itself failed (invalid frontmatter, for example), the hook won’t fire, and you’ll see the MCP error directly.

## Next steps

[Section titled “Next steps”](#next-steps)

* [Install Archcore](/start/install/) to repeat the setup sequence.
* [Connect your agent](/guides/connect-your-agent/) to inspect MCP, hooks, and instruction hints.
