Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ A PR that adds, removes, or renames an env var read by the server — or that ch
- **`CHANGELOG.md`** — an entry under `## [Unreleased]` if the change is user-visible.
- **`Dockerfile`** — only if the var needs a default baked into the docker image.

## Distribution

See [docs/distribution.md](docs/distribution.md) for the install channels, the Claude Code and Codex plugin layout, the manifest fields `scripts/sync-manifests.cjs` owns, and how to test an install before publishing. Consult before adding an install channel or editing a plugin manifest.

## Testing

Tool tests build a `ToolContext` via `fakeContext()` from `tests/helpers/fakeContext.ts` and dispatch through `dispatch( descriptor, ctx )`. Provide an `mwn` factory (typically `createMockMwn()` from `tests/helpers/mock-mwn.ts`) and override only the slices the test exercises. See [docs/testing.md](docs/testing.md) for the full pattern, MCP Inspector CLI examples, and the bot-password setup required to exercise authenticated tools against a local wiki.
Expand Down
97 changes: 97 additions & 0 deletions docs/distribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Distribution

For contributors adding an install channel, editing a plugin manifest, or testing an install before publishing. Release mechanics live in [releasing.md](releasing.md).

## Channels

| Artifact | Defined in |
| --- | --- |
| npm package | `package.json` |
| MCP registry entry | `server.json` |
| `.mcpb` bundle | `mcpb/manifest.json` |
| Docker image | `Dockerfile` |
| Gemini CLI extension | `gemini-extension.json` |
| Claude Code plugin | `.claude-plugin/marketplace.json` and the plugin directory |
| Codex plugin | `.agents/plugins/marketplace.json` and the plugin directory |

Every extension and plugin manifest is a wrapper that launches the published npm package with `npx`. The `.mcpb` bundle and the Docker image each ship their own build instead.

Commit a manifest for a client only when that client installs plugins from a repository. For any other client, add a copy-paste `npx` snippet to the README install section and commit no file.

## Plugin layout

Claude Code and Codex share one plugin directory and one server declaration:

```
.claude-plugin/marketplace.json Claude Code catalog
.agents/plugins/marketplace.json Codex catalog
plugins/mediawiki-mcp-server/
.claude-plugin/plugin.json Claude Code manifest
.codex-plugin/plugin.json Codex manifest
.mcp.json the shared server declaration
```

Four constraints fix this shape:

- [Claude Code](https://code.claude.com/docs/en/plugin-marketplaces) reads its catalog only from `.claude-plugin/marketplace.json` at the repository root.
- [Codex](https://developers.openai.com/codex/plugins) rejects a plugin whose source path is the repository root, so the plugin is a subdirectory.
- Claude Code discovers `.mcp.json` at the plugin root, so its `plugin.json` omits `mcpServers`. Codex has no such discovery and points at the same file with `"mcpServers": "./.mcp.json"`.
- The catalogs take different `source` shapes: a bare string for Claude Code, an object for Codex.

Keep `.mcp.json` inside the plugin directory. Claude Code loads a repository-root `.mcp.json` as a project server, which would start this server for anyone working in this repository.

## Fields the sync script owns

`scripts/sync-manifests.cjs` runs on `npm version` and re-reads each file to confirm the write. Each manifest takes a different subset:

| Manifest | Fields written |
| --- | --- |
| `server.json` | `version`, `description` |
| `mcpb/manifest.json` | `version`, `keywords`, `author`, `homepage`, `license` |
| `gemini-extension.json` | `version`, `description` |
| `.claude-plugin/marketplace.json` | `plugins[0].description` |
| `.agents/plugins/marketplace.json` | `plugins[0].description` |
| `plugins/mediawiki-mcp-server/.claude-plugin/plugin.json` | `version`, `description`, `keywords`, `author`, `homepage`, `license` |
| `plugins/mediawiki-mcp-server/.codex-plugin/plugin.json` | `version`, `description`, `keywords`, `author`, `homepage`, `license` |

`package.json` supplies `version`, `keywords`, `author`, `homepage`, and `license`; the shared `description` is a constant in the script. The script does not write `package.json`, and `mcpb/manifest.json` keeps its own shorter description.

Do not hand-edit a field in that table, because the next release overwrites it. Change the value at its source, then run:

```bash
npm run sync-manifests
```

Everything else in these files is hand-maintained, including each catalog's top-level `description` and `interface`. In `server.json` the script sets only the top-level pair; the `packages[]` entries are written during the release workflow by `scripts/update-server-json-npm.cjs` and `scripts/update-server-json-mcpb.cjs`.

Adding a manifest to the sync takes three edits:

- a path constant in `scripts/constants.cjs`
- a `targets` entry in `scripts/sync-manifests.cjs`
- the file added to the `git add` list in the `version` script in `package.json`, so the bump lands in the release commit

## Testing an install

Both CLIs accept a local directory as a marketplace source, so an install can be exercised before publishing. From the repository root:

```bash
claude plugin marketplace add ./
claude plugin install mediawiki-mcp-server@professional-wiki
claude plugin details mediawiki-mcp-server@professional-wiki

codex plugin marketplace add ./
codex plugin add mediawiki-mcp-server@professional-wiki
codex mcp list
```

`plugin details` and `mcp list` each report the `mediawiki` server. Remove the test install afterwards:

```bash
claude plugin uninstall mediawiki-mcp-server@professional-wiki
claude plugin marketplace remove professional-wiki

codex plugin remove mediawiki-mcp-server@professional-wiki
codex plugin marketplace remove professional-wiki
```

`claude plugin validate .` checks the Claude Code manifests without installing.
1 change: 1 addition & 0 deletions docs/documentation-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Every page sits in one genre. Write to that genre's reader and register.
| `docs/deployment.md` | Self-hosters running the HTTP transport or the hosted OAuth proxy | Tasks and env-var tables; system model only where needed to act |
| `docs/operations.md` | Sysadmins keeping a deployment healthy | Log, probe, and metric contracts, with remedies |
| `docs/testing.md`, `docs/releasing.md` | Contributors and maintainers executing a procedure | Runbooks and checklists; no design history |
| `docs/distribution.md` | Contributors adding an install channel or editing a manifest | The channel map, manifest contracts, and the install-test runbook; no design history |
| `docs/tool-conventions.md` | Anyone adding or changing a tool | Rules and decision guides |
| `src/auth/README.md` | Maintainers orienting in the auth code | A map of roles and files; no line-level detail that goes stale |

Expand Down
2 changes: 1 addition & 1 deletion docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ npm version 0.2.0
This command automatically:

- Updates `package.json` and `package-lock.json`
- Syncs the version and shared metadata across the distribution manifests (`server.json`, `mcpb/manifest.json`, `gemini-extension.json`, and the Claude Code and Codex plugin files) via `scripts/sync-manifests.cjs`
- Syncs the version and shared metadata across the distribution manifests via `scripts/sync-manifests.cjs` (see [distribution.md](distribution.md#fields-the-sync-script-owns) for the per-manifest field list)
- Promotes `## [Unreleased]` in `CHANGELOG.md` to `## [<version>] - <today>` and refreshes the link references
- Creates a git commit
- Creates a git tag (e.g. `v0.2.0`)
Expand Down
24 changes: 23 additions & 1 deletion docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,29 @@ Pass an optional `wiki` argument (a wiki key such as `en.wikipedia.org`, or the
To point an MCP client at a locally-built copy of the server:

1. [Install](../README.md#installation) the server on the client.
2. Replace the `command` and `args` values with the ones from [`mcp.json`](../mcp.json) (or [`mcp.docker.json`](../mcp.docker.json) for Docker).
2. Replace the `command` and `args` values with:

```json
"command": "node",
"args": ["/path/to/MediaWiki-MCP-Server/dist/index.js"]
```

Or, to run the server in Docker:

```json
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "/path/to/MediaWiki-MCP-Server/:/home/node/app",
"-w", "/home/node/app",
"-u", "node",
"node:22",
"npm", "run", "start", "--silent"
]
```

The Docker variant mounts the repository at `/home/node/app`, so point `CONFIG` at a path inside the container.

3. Run the `dev` command so sources recompile on save:

```sh
Expand Down
26 changes: 0 additions & 26 deletions mcp.docker.json

This file was deleted.

13 changes: 0 additions & 13 deletions mcp.json

This file was deleted.

Loading