Skip to main content
Glama
README.md
# MediaWiki MCP Server

A Model Context Protocol (MCP) server for MediaWiki instances with multi-wiki support. Uses the modern REST API (MediaWiki 1.42+) and Action API for full read/write access across multiple named wikis.

Field notes: [MediaWiki MCP: reads worked after login expired](https://hackyourworld.com/mediawiki-mcp-login-expired-docker-port/) covers the expired bot-password session and loopback-only container listener failures behind the current authentication and deployment checks.

## Features

- **Multi-Wiki Support**: Register named wikis, fan-out searches across all of them
- **REST API**: Uses the modern `/rest.php/v1/` endpoints for page CRUD, search, and revisions
- **Bot Password Auth**: Logs in via `Special:BotPasswords` with per-wiki credentials
- **Page Operations**: Read, create, update, delete, and undelete pages
- **Search**: Full-text and prefix search across all registered wikis
- **File Operations**: Get file metadata, upload files from data or URL
- **Category Browsing**: List categories and their members with pagination
- **History & Revisions**: Access revision history, view individual revisions
- **Recent Changes**: Track wiki activity across all wikis
- **Link Analysis**: Explore outgoing links and backlinks
- **Pagination**: All list endpoints support continuation tokens
- **Retry Logic**: Exponential backoff on 429/5xx errors

## Installation

### Prerequisites

- Node.js 18 or higher
- MediaWiki 1.42 or higher

### Local Installation

```bash
git clone https://github.com/ttpears/mediawiki-mcp.git
cd mediawiki-mcp
npm install
npm run build
```

### Claude Code Installation

Register the published npm package directly with `claude mcp add`. Repeat `--env` for each variable, put all flags **before** the server name, and use `--` to mark the start of the spawned command. `--scope` picks where the entry lives: `local` (default, current project), `user` (every project), or `project` (`.mcp.json` for team check-in).

Single-wiki:

```bash
claude mcp add mediawiki \
  --scope user \
  --env MEDIAWIKI_BASE_URL=https://wiki.example.com \
  --env MEDIAWIKI_USERNAME=Admin@mcp \
  --env MEDIAWIKI_PASSWORD=your-bot-password \
  -- npx -y mediawiki-mcp
```

Multi-wiki — register wikis as `Name:URL` pairs in `MEDIAWIKI_WIKIS`, then provide `MEDIAWIKI_USERNAME_<NAME>` and `MEDIAWIKI_PASSWORD_<NAME>` per wiki (uppercase). `MEDIAWIKI_DEFAULT_WIKI` picks the wiki used when a tool call doesn't specify one:

```bash
claude mcp add mediawiki \
  --scope user \
  --env MEDIAWIKI_WIKIS=Main:https://wiki.example.com,Dev:https://dev.wiki.example.com \
  --env MEDIAWIKI_DEFAULT_WIKI=Main \
  --env MEDIAWIKI_USERNAME_MAIN=Admin@mcp \
  --env MEDIAWIKI_PASSWORD_MAIN=your-bot-password \
  --env MEDIAWIKI_USERNAME_DEV=Admin@mcp \
  --env MEDIAWIKI_PASSWORD_DEV=your-bot-password \
  -- npx -y mediawiki-mcp
```

### Claude Desktop (MCPB bundle)

Each release attaches a one-click `mediawiki-mcp-<version>.mcpb` bundle. Download it
from the [latest release](https://github.com/ttpears/mediawiki-mcp/releases/latest)
and open it with Claude Desktop (Settings → Extensions → install from file, or
double-click). Claude Desktop prompts for the configuration:

- **Wiki API Base URL** — e.g. `https://wiki.example.com` (single-wiki setup).
- **Bot Username** / **Bot Password** — optional; from `Special:BotPasswords`. Leave
  blank for anonymous read-only access. Credentials are stored in your OS keychain.
- **Wikis** / **Default Wiki Name** — optional advanced fields for multi-wiki use.
  Note: per-wiki credentials can't be entered through the bundle UI, so authenticated
  multi-wiki still needs the Docker/env setup below.

To build the bundle locally: `npm run build:mcpb`.

### Docker Installation

```bash
cp .env.example .env
# Edit .env with your wiki URLs and credentials
docker compose up -d
```

## Authentication

This server uses MediaWiki **bot passwords** for API authentication. Bot passwords are scoped credentials that limit what the bot can do, separate from your real account password.

### Creating a Bot Password

1. Log in to your MediaWiki wiki as a user with the permissions you want the bot to have
2. Navigate to **Special:BotPasswords** (e.g., `https://wiki.example.com/wiki/Special:BotPasswords`)
3. Enter a bot name (e.g., `mcp`) and click **Create**
4. Select the grants (permissions) the bot needs:
   - **High-volume (bot) access** — required for API usage
   - **Edit existing pages** — for `update-page`
   - **Edit protected pages** — if the bot needs to edit protected pages
   - **Create, edit, and move pages** — for `create-page`, `update-page`
   - **Delete pages and revisions** — for `delete-page` / `undelete-page`
   - **Upload, replace, and move files** — for `upload-file` / `upload-file-from-url`
   - **Patrol changes to pages** — if using activity monitoring
   - **Rollback changes to pages** — if using rollback features
5. Click **Create** to generate the password

MediaWiki will display credentials in this format:

```
Username: Admin@mcp
Password: your-bot-password-here
```

You need **both** values. The username (`Admin@mcp`) goes in `MEDIAWIKI_USERNAME_*` and the password goes in `MEDIAWIKI_PASSWORD_*`. The server uses these to log in via the Action API (`action=login`) and maintains a cookie-based session for all subsequent requests.

### Repeat for Each Wiki

If you have multiple wikis, create a bot password on each one. You'll have a username/password pair per wiki.

## Configuration

### Multi-Wiki Setup

Create a `.env` file (see `.env.example`):

```bash
# Register multiple wikis (Name:URL pairs, comma-separated)
MEDIAWIKI_WIKIS=Main:https://wiki.example.com,Dev:https://dev.wiki.example.com

# Default wiki when none is specified
MEDIAWIKI_DEFAULT_WIKI=Main

# Per-wiki bot password credentials (uppercase wiki name)
MEDIAWIKI_USERNAME_MAIN=Admin@mcp
MEDIAWIKI_PASSWORD_MAIN=your-bot-password-here
MEDIAWIKI_USERNAME_DEV=Admin@mcp
MEDIAWIKI_PASSWORD_DEV=your-bot-password-here
```

### Single-Wiki Setup

```bash
MEDIAWIKI_BASE_URL=https://wiki.example.com
MEDIAWIKI_USERNAME=Admin@mcp
MEDIAWIKI_PASSWORD=your-bot-password-here
```

### HTTP Transport

```bash
MEDIAWIKI_MCP_PORT=8009
MEDIAWIKI_MCP_HOST=0.0.0.0
```

## Usage

### Stdio Mode (Local)

```bash
npm start
```

### HTTP Mode (Remote / Docker)

```bash
npm run start:http
```

Endpoint: `http://localhost:8009/mcp`

### LibreChat Integration

#### 1. Add wiki credentials to the LibreChat `.env`

Add the `MEDIAWIKI_*` variables to your LibreChat host's `.env` file:

```bash
# MediaWiki MCP
MEDIAWIKI_WIKIS=Main:https://wiki.example.com,Dev:https://dev.wiki.example.com
MEDIAWIKI_DEFAULT_WIKI=Main
MEDIAWIKI_USERNAME_MAIN=Admin@mcp
MEDIAWIKI_PASSWORD_MAIN=your-bot-password-here
MEDIAWIKI_USERNAME_DEV=Admin@mcp
MEDIAWIKI_PASSWORD_DEV=your-bot-password-here
```

#### 2. Add to `docker-compose.override.yml`

```yaml
services:
  mediawiki-mcp:
    build: ./mediawiki-mcp
    container_name: mediawiki-mcp
    env_file:
      - .env
    environment:
      - MEDIAWIKI_MCP_HOST=0.0.0.0
    restart: unless-stopped
    networks:
      - default
```

This builds the container from source and starts it alongside LibreChat. No need to install Node.js on the host — Docker handles the build.

#### 3. Configure in `librechat.yaml`

```yaml
mcpServers:
  mediawiki:
    type: streamable-http
    url: http://mediawiki-mcp:8009/mcp
```

> If you have `allowedDomains` configured in LibreChat, add `mediawiki-mcp` to the list.

### Use as a Claude.ai Connector (OAuth)

The HTTP transport can run as a public remote connector for claude.ai,
authenticated with **Microsoft Entra (OIDC)** — no MediaWiki extensions required.
The server is an OAuth 2.1 broker: it presents authorization-server metadata and
Dynamic Client Registration to Claude, runs the Entra sign-in flow, and issues its
own audience-bound access tokens. **Entra decides who can connect**; wiki reads and
edits run on the existing **per-wiki bot accounts** (`MEDIAWIKI_USERNAME_<WIKI>` /
`MEDIAWIKI_PASSWORD_<WIKI>`), attributed to the Entra user in edit summaries. Only
broker session state lives in **Redis** (namespaced by host); no wiki credentials
or Entra tokens are stored. The stdio and LibreChat header paths are unaffected.

The connector serves the whole farm in `MEDIAWIKI_WIKIS` (cross-wiki fan-out). Any
tenant member can **read**; **write** tools (create/update/delete/upload) are gated
by an Entra **app role** (`OAUTH_WRITE_ROLE`, default `Writer`) — members without
it get read-only.

**1. Register / reuse an Entra app**

- Reuse an existing Entra app (e.g. the bookstack connector's) or register a new one.
- Add the redirect URI `https://<your-public-url>/callback`.
- Define an app role for write access (e.g. `Writer`) and assign it to the users
  who should be able to edit. (Reading needs no role.)

**2. Configure the connector environment**

```bash
MEDIAWIKI_MCP_AUTH=oauth
MEDIAWIKI_MCP_PUBLIC_URL=https://wiki-mcp.example.com    # public HTTPS base URL
# the farm to serve, and per-wiki bot credentials for the actual API calls:
MEDIAWIKI_WIKIS=itops:https://itops.wiki.example.com,tech:https://tech.wiki.example.com
MEDIAWIKI_DEFAULT_WIKI=itops
MEDIAWIKI_USERNAME_ITOPS=Bot@mcp
MEDIAWIKI_PASSWORD_ITOPS=<bot password>
MEDIAWIKI_USERNAME_TECH=Bot@mcp
MEDIAWIKI_PASSWORD_TECH=<bot password>
# Entra app (OIDC):
OAUTH_TENANT_ID=<entra tenant id>
OAUTH_CLIENT_ID=<entra app client id>
OAUTH_CLIENT_SECRET=<entra app client secret>
OAUTH_WRITE_ROLE=Writer                                  # app role granting write
# broker infra:
REDIS_URL=redis://:<password>@redis:6379                 # shared broker state
MEDIAWIKI_MCP_JWT_SECRET=<random secret>
MEDIAWIKI_MCP_HOST=0.0.0.0
MEDIAWIKI_MCP_TRUST_PROXY=1                               # behind a reverse proxy
# MEDIAWIKI_MCP_ALLOWED_HOSTS=wiki-mcp.example.com        # optional Host allowlist
```

Terminate TLS at your reverse proxy and forward to the server; it must be reachable
at `MEDIAWIKI_MCP_PUBLIC_URL`. Run the published image `ghcr.io/ttpears/mediawiki-mcp`
(the `npm run start:http` entrypoint) or locally with `npm run start:http`.

**3. Add the connector in claude.ai**

Add a custom connector pointing at `https://<your-public-url>/mcp`. Claude discovers
the auth server via `/.well-known/oauth-protected-resource/mcp`, registers itself
via DCR, and signs the user in through Entra. One sign-in covers the whole farm.

## Tools

All tools that accept a `wiki` parameter will use the default wiki when omitted. Search and listing tools fan out across all registered wikis when `wiki` is not specified.

### Wiki Management

| Tool | Description |
|------|-------------|
| `add-wiki` | Register a new named wiki (name, url, username, password) |
| `remove-wiki` | Remove a registered wiki |
| `list-wikis` | Show all registered wikis |

### Search (Fan-Out)

| Tool | Description |
|------|-------------|
| `search-pages` | Full-text search across wikis |
| `search-pages-by-prefix` | Title prefix search across wikis |

**Parameters:** `query`, `wiki?`, `limit?`

### Page Operations (Single Wiki)

| Tool | Description |
|------|-------------|
| `get-page` | Get page content (wikitext or HTML) and metadata |
| `create-page` | Create a new page |
| `update-page` | Edit an existing page (requires `latest_timestamp` from get-page) |
| `delete-page` | Delete a page |
| `undelete-page` | Restore a deleted page |

### History (Single Wiki)

| Tool | Description |
|------|-------------|
| `get-page-history` | Paginated revision list for a page |
| `get-revision` | Get details of a specific revision by ID |

### Categories

| Tool | Description |
|------|-------------|
| `list-categories` | List categories with member counts (fan-out) |
| `get-category-members` | List pages in a category (single wiki, paginated) |

### Files (Single Wiki)

| Tool | Description |
|------|-------------|
| `get-file` | Get file metadata, dimensions, and URLs |
| `upload-file` | Upload from base64-encoded data |
| `upload-file-from-url` | Upload from a remote URL |

### Activity (Fan-Out)

| Tool | Description |
|------|-------------|
| `get-recent-changes` | Recent edits, creations, and deletions across wikis |

### Links (Single Wiki)

| Tool | Description |
|------|-------------|
| `get-page-links` | Get outgoing links or backlinks for a page |

## Development

```bash
npm run dev        # Watch mode
npm run type-check # Type checking
npm run build      # Build
npm test           # Run tests (85 tests)
npm run test:watch # Watch mode tests
```

## Architecture

```
src/
├── index.ts                # Entry point (stdio)
├── stdio.ts                # Stdio transport
├── http-transport.ts       # Streamable HTTP transport
├── wiki-registry.ts        # Named wiki storage and env parsing
├── wiki-orchestrator.ts    # Fan-out routing and client management
├── types.ts                # TypeScript types
├── clients/
│   ├── rest-client.ts      # REST API (/rest.php/v1/)
│   └── action-client.ts    # Action API (/api.php) + bot password login
└── tools/
    ├── index.ts            # Tool registration barrel
    ├── wiki-tools.ts       # Wiki management
    ├── search-tools.ts     # Search (fan-out)
    ├── page-tools.ts       # Page CRUD
    ├── history-tools.ts    # Revision history
    ├── category-tools.ts   # Categories
    ├── link-tools.ts       # Links and backlinks
    ├── file-tools.ts       # File operations
    └── activity-tools.ts   # Recent changes
```

```
Transport Layer (stdio.ts, http-transport.ts)
         ↓
   WikiOrchestrator (fan-out / routing)
     ↓              ↓
RestClient      ActionClient
(/rest.php/v1)  (/api.php)
     ↑              ↑
     └── shared session cookies (bot password login)
```

## License

MIT

## Contributing

Contributions welcome! Please open issues or pull requests.

TDQS

A3.8/5.0

Scored across 21 tools

Disambiguation3/5

The three search/locate tools (find-page, search-page, search-page-by-prefix) have overlapping purposes and could be confused. While descriptions attempt to differentiate them, an agent may struggle to choose the right one. Other tools are clearly distinct.

Naming Consistency5/5

All tool names follow a consistent verb-noun pattern with hyphens (e.g., list-wikis, get-page, upload-file). Verbs are predictable and there are no mixed naming conventions.

Tool Count4/5

With 21 tools, this is on the heavier side, but the broad scope of MediaWiki management (wiki instances, pages, history, categories, files, recent changes) justifies the count. Each tool covers a distinct aspect of the domain.

Completeness4/5

Core workflows are well covered: page CRUD, history, file upload, category browsing, and search. Minor gaps exist (e.g., no page move/rename, no revision diff tool), but agents can work around them for most tasks.

Maintenance

ActivityActive
ResponsivenessResponsive