fix: remove the obsidian MCP server and the unreadable .mcp.json files

718c79a deleted every per-plugin .claude-plugin/plugin.json, which
reclassified each package from a marketplace plugin to a plain apm
package. That silently broke MCP propagation: apm_cli/deps/plugin_parser.py
maps a plugin-root .mcp.json into .apm/.mcp.json, and that code path runs
only for marketplace plugins. With no manifest, apm never reads the file.

Reproduced on ref-pinned consumer clones: at the parent commit a consumer
receives the obsidian server, at HEAD it receives none, and on upgrade apm
prints "Removed stale MCP server 'obsidian' from .mcp.json". This repo
consumes its own plugins through apm (ADR-0018), so the tracked root
.mcp.json would have been rewritten to an empty server map on the next
lock re-resolve -- silent tool loss plus unexplained working-tree drift.

The server is removed entirely rather than relocated to .apm/. It was
already a standing question (SIMPLIFICATION-AUDIT finding 37, deferred on
2026-09-13 pending confirmation, now confirmed), and plugins/bin/apm.yml
declares dependencies.mcp: [] -- apm's supported mechanism was never used.
All seven .mcp.json files go; the root one is apm-generated output and is
now gitignored alongside the other install artifacts.

ADR-0011's deferred ".mcp.json wiring gap" is moot twice over -- the
install route it blocked no longer exists and neither does the file --
and ADR-0018 records why it lost its only worked example of MCP
propagation. apm.lock.yaml still carries the server; it clears on the
first apm update after this reaches the default branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
This commit is contained in:
2026-09-14 18:09:17 +00:00
parent 061bb3d5b4
commit c96ca9ca0d
12 changed files with 40 additions and 43 deletions

View File

@@ -67,6 +67,14 @@ than being wired into the plugin manifest. This means the gitea plugin is not ye
standalone via `claude plugin install gitea@holocron` without manual MCP setup. A follow-up Gitea
issue tracks closing this gap.
**Correction (2026-09-14):** this gap is now closed by removal rather than by wiring. ADR-0024
made apm the only supported install path, so `claude plugin install gitea@holocron` is no longer
a route this repo supports, and the per-plugin manifests it needed are gone. Because apm reads a
plugin-root `.mcp.json` only on the marketplace-plugin code path, that file became unreadable;
every `plugins/*/.mcp.json` was deleted, including this one. A plugin that needs an MCP server
declares it in `dependencies.mcp` in its `apm.yml` — the supported mechanism, which this repo has
never used. The follow-up issue this paragraph anticipates is moot.
**Research backfill.** The existing research docs
(`plugins/gitea/docs/research/docs/gitea/`) are 100% code-derived from gitea-mcp source with zero
external/best-practice content (the original docs.gitea.com fetch timed out and was never

View File

@@ -5,6 +5,16 @@ authored `.apm/` tree discoverable by hosts that install natively. Both are abou
marketplace. This ADR is about consuming it: how the plugins get onto the machine this repo is
worked on.
**Correction (2026-09-14): the flat content mirror named above no longer exists.** ADR-0017 is
superseded by ADR-0024, and commit `718c79a` deleted the mirror
(`plugins/<name>/{skills,agents,hooks}/`) along with its generator, its test suite and its pre-push
gate; native `claude plugin install` is no longer a supported path, so there are no longer "hosts
that install natively" for it to serve. Nothing this ADR decides depends on the mirror — it appears
here only as the other half of "producing the marketplace", and once more under "Install output is
gitignored" below, where the two copies of plugin content ADR-0017 governed are now one, `.apm/`
itself, and committing the deployed skills would make a second rather than a third. Read both
mentions as historical.
**Status: executed (2026-08-14).** All six packages are installed into `/root/ai-development` by
`apm install`; the six native project-scope installs (`claude plugin uninstall <name>@holocron
--scope project`) are gone and `.claude/settings.json`'s `enabledPlugins` block is empty.
@@ -121,6 +131,19 @@ unprompted. The `gitea` and `context7` servers were never plugin-provided — th
apm's "contributed no entries to claude settings; skipped" warning on `kyberforge` and `lint` is
accurate and harmless.
**Correction (2026-09-14): the MCP propagation above stopped operating, and the files it read are
deleted.** It ran on one code path only — `apm_cli/deps/plugin_parser.py` maps a plugin-root
`.mcp.json` onto `.apm/.mcp.json` for packages apm treats as *marketplace plugins*. Commit
`718c79a` (ADR-0024) deleted every `plugins/*/.claude-plugin/plugin.json` and
`plugins/*/.github/plugin/plugin.json`, so each package is now a plain apm package and that path no
longer runs. The supported declaration was never in use either: `plugins/bin/apm.yml` has
`dependencies.mcp: []`. That left the six plugin-root `.mcp.json` files dead config — five of them
empty stubs, only `plugins/bin`'s carrying the `obsidian` server — and all six are now deleted along
with the server itself, which is not wanted. The repo-root `.mcp.json` was apm's own generated
output that happened to be tracked; it is deleted and gitignored, on the same reasoning as
`.claude/skills/`. The rest of this paragraph is unaffected: `gitea` and `context7` were never
plugin-provided, and the hooks claim never depended on any of this.
**A `.apm/` edit now needs a round trip.** The dependency resolves from the remote, so an edit is
invisible to the running session until it is pushed and the install is refreshed. Under the native
install with `autoUpdate` the shape was the same; it was more noticeable here at first because the

View File

@@ -48,7 +48,7 @@ One compiler produces the generated content in the tree:
apm is the only supported install path. A flat `skills/`, `agents/`, `hooks/` mirror used to be compiled to each plugin root so Claude Code's installer could convention-scan it, alongside a per-plugin `.claude-plugin/plugin.json` and `.github/plugin/plugin.json`; both are gone, together with native `claude plugin install` support. apm reads `plugins/<name>/apm.yml` and deploys from `.apm/` directly, and never probed those manifests.
`.apm/` is the sole hand-edited authoring source for plugin content. Hand-authored material that is not an `.apm/` primitive — `README.md`, `docs/`, `bin/`, `sources.md`, `.mcp.json`, and per-plugin extras such as `plugins/gitea/references/` and `plugins/bin/evals/` — lives at the plugin **root**. A hand-edit to the generated `.claude-plugin/marketplace.json` is reported as drift by the `apm-pack-check-clean` pre-push hook.
`.apm/` is the sole hand-edited authoring source for plugin content. Hand-authored material that is not an `.apm/` primitive — `README.md`, `docs/`, `bin/`, `sources.md`, and per-plugin extras such as `plugins/gitea/references/` and `plugins/bin/evals/` — lives at the plugin **root**. A hand-edit to the generated `.claude-plugin/marketplace.json` is reported as drift by the `apm-pack-check-clean` pre-push hook.
Plugin-root documentation belongs in `docs/`. That convention is older than the mirror's removal: a hand-written `README.md` placed inside a mirrored directory used to be destroyed by the next sync with no drift report, which cost the repo one document — `plugins/kyberforge/hooks/README.md`, since restored to `plugins/kyberforge/docs/hooks.md`.