mcp-server-wikijs 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_server_wikijs-0.1.0/.env.example +9 -0
- mcp_server_wikijs-0.1.0/.github/workflows/ci.yml +62 -0
- mcp_server_wikijs-0.1.0/.github/workflows/publish.yml +55 -0
- mcp_server_wikijs-0.1.0/.gitignore +16 -0
- mcp_server_wikijs-0.1.0/CHANGELOG.md +28 -0
- mcp_server_wikijs-0.1.0/CONTRIBUTING.md +57 -0
- mcp_server_wikijs-0.1.0/LICENSE +21 -0
- mcp_server_wikijs-0.1.0/PKG-INFO +164 -0
- mcp_server_wikijs-0.1.0/README.md +138 -0
- mcp_server_wikijs-0.1.0/pyproject.toml +67 -0
- mcp_server_wikijs-0.1.0/src/wikijs_mcp/__init__.py +7 -0
- mcp_server_wikijs-0.1.0/src/wikijs_mcp/__main__.py +8 -0
- mcp_server_wikijs-0.1.0/src/wikijs_mcp/client.py +257 -0
- mcp_server_wikijs-0.1.0/src/wikijs_mcp/server.py +151 -0
- mcp_server_wikijs-0.1.0/tests/conftest.py +51 -0
- mcp_server_wikijs-0.1.0/tests/test_client.py +254 -0
- mcp_server_wikijs-0.1.0/tests/test_server.py +99 -0
- mcp_server_wikijs-0.1.0/tests/test_settings.py +54 -0
- mcp_server_wikijs-0.1.0/uv.lock +829 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copy to .env for standalone / local runs (gitignored). When the server is launched by an
|
|
2
|
+
# MCP client, prefer passing these in the client config's `env` block instead.
|
|
3
|
+
|
|
4
|
+
# Base URL of your Wiki.js instance (the GraphQL endpoint is <URL>/graphql). Required.
|
|
5
|
+
WIKIJS_URL=https://wiki.example.com
|
|
6
|
+
|
|
7
|
+
# A Wiki.js API key: Administration → API Access → enable API → New API Key (full access).
|
|
8
|
+
# Required. WIKIJS_API_TOKEN and WIKI_JS_MCP_API_TOKEN are also accepted as aliases.
|
|
9
|
+
WIKIJS_TOKEN=
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
name: test (py${{ matrix.python-version }})
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
strategy:
|
|
21
|
+
fail-fast: false
|
|
22
|
+
matrix:
|
|
23
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Install uv
|
|
28
|
+
uses: astral-sh/setup-uv@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: ${{ matrix.python-version }}
|
|
31
|
+
enable-cache: true
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: uv sync --all-extras --dev
|
|
35
|
+
|
|
36
|
+
- name: Lint (ruff)
|
|
37
|
+
run: uv run ruff check .
|
|
38
|
+
|
|
39
|
+
- name: Run tests
|
|
40
|
+
run: uv run pytest -q
|
|
41
|
+
|
|
42
|
+
build:
|
|
43
|
+
name: build (sdist + wheel)
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
needs: test
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
|
|
49
|
+
- name: Install uv
|
|
50
|
+
uses: astral-sh/setup-uv@v5
|
|
51
|
+
|
|
52
|
+
- name: Build distributions
|
|
53
|
+
run: uv build
|
|
54
|
+
|
|
55
|
+
- name: Check distributions
|
|
56
|
+
run: uvx twine check dist/*
|
|
57
|
+
|
|
58
|
+
- name: Upload build artifacts
|
|
59
|
+
uses: actions/upload-artifact@v4
|
|
60
|
+
with:
|
|
61
|
+
name: dist
|
|
62
|
+
path: dist/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI when a version tag (v*) is pushed, using PyPI Trusted Publishing
|
|
4
|
+
# (OIDC) — no API token stored in the repo. Configure the trusted publisher once at
|
|
5
|
+
# https://pypi.org/manage/project/mcp-server-wikijs/settings/publishing/ with:
|
|
6
|
+
# owner: margus | repo: wikijs-mcp | workflow: publish.yml | environment: pypi
|
|
7
|
+
# (For the very first release, create a "pending publisher" at
|
|
8
|
+
# https://pypi.org/manage/account/publishing/ with the same values.)
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
tags: ["v*"]
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
name: build
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Install uv
|
|
26
|
+
uses: astral-sh/setup-uv@v5
|
|
27
|
+
|
|
28
|
+
- name: Build distributions
|
|
29
|
+
run: uv build
|
|
30
|
+
|
|
31
|
+
- name: Check distributions
|
|
32
|
+
run: uvx twine check dist/*
|
|
33
|
+
|
|
34
|
+
- uses: actions/upload-artifact@v4
|
|
35
|
+
with:
|
|
36
|
+
name: dist
|
|
37
|
+
path: dist/
|
|
38
|
+
|
|
39
|
+
publish:
|
|
40
|
+
name: publish to PyPI
|
|
41
|
+
needs: build
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
environment:
|
|
44
|
+
name: pypi
|
|
45
|
+
url: https://pypi.org/project/mcp-server-wikijs/
|
|
46
|
+
permissions:
|
|
47
|
+
id-token: write # required for Trusted Publishing
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/download-artifact@v4
|
|
50
|
+
with:
|
|
51
|
+
name: dist
|
|
52
|
+
path: dist/
|
|
53
|
+
|
|
54
|
+
- name: Publish
|
|
55
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] — 2026-06-25
|
|
10
|
+
|
|
11
|
+
Initial public release. Published on PyPI as `mcp-server-wikijs`.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- MCP server exposing Wiki.js admin operations over stdio.
|
|
15
|
+
- Page tools: `list_pages`, `get_page`, `create_page`, `update_page` (field-merge),
|
|
16
|
+
`delete_page`.
|
|
17
|
+
- Navigation tools: `get_navigation`, `set_navigation_mode`.
|
|
18
|
+
- Group tools: `list_groups`, `get_group` (permissions + page rules).
|
|
19
|
+
- `trigger_git_sync` for the Git storage target.
|
|
20
|
+
- `execute_graphql` generic escape hatch for any other query/mutation.
|
|
21
|
+
- Configuration via `WIKIJS_URL` + `WIKIJS_TOKEN` (with `WIKIJS_API_TOKEN` and
|
|
22
|
+
`WIKI_JS_MCP_API_TOKEN` aliases), or a local `.env`.
|
|
23
|
+
- Test suite (38 tests) running against a mocked HTTP transport — no live wiki needed.
|
|
24
|
+
- GitHub Actions: CI (ruff + pytest on Python 3.11–3.13, build check) and tag-triggered
|
|
25
|
+
PyPI publish via Trusted Publishing.
|
|
26
|
+
|
|
27
|
+
[Unreleased]: https://github.com/margus/wikijs-mcp/compare/v0.1.0...HEAD
|
|
28
|
+
[0.1.0]: https://github.com/margus/wikijs-mcp/releases/tag/v0.1.0
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in improving **wikijs-mcp**.
|
|
4
|
+
|
|
5
|
+
## Development setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/margus/wikijs-mcp
|
|
9
|
+
cd wikijs-mcp
|
|
10
|
+
uv sync # installs runtime + dev dependencies into .venv
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Running checks
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv run pytest -q # tests (no live Wiki.js needed — httpx is mocked)
|
|
17
|
+
uv run ruff check . # lint
|
|
18
|
+
uv run ruff format . # format
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
CI runs the same `ruff` + `pytest` on Python 3.11–3.13, so green locally ≈ green on CI.
|
|
22
|
+
|
|
23
|
+
## Architecture
|
|
24
|
+
|
|
25
|
+
- **`src/wikijs_mcp/client.py`** — `WikiJSClient`, all the Wiki.js GraphQL logic as plain
|
|
26
|
+
async methods. This is where behaviour lives and where most tests point. It takes an
|
|
27
|
+
optional `httpx` transport so tests can inject `httpx.MockTransport`.
|
|
28
|
+
- **`src/wikijs_mcp/server.py`** — the MCP layer: a `FastMCP` instance plus thin `@mcp.tool()`
|
|
29
|
+
wrappers that delegate to a lazily-constructed `WikiJSClient`.
|
|
30
|
+
|
|
31
|
+
When adding a capability, prefer: add a method to `WikiJSClient`, test it against a mock
|
|
32
|
+
transport, then expose a one-line tool wrapper in `server.py`.
|
|
33
|
+
|
|
34
|
+
## Adding a tool
|
|
35
|
+
|
|
36
|
+
1. Add an `async def` method to `WikiJSClient` that builds the GraphQL query and unwraps the
|
|
37
|
+
response.
|
|
38
|
+
2. Add tests in `tests/test_client.py` covering variable construction and response handling.
|
|
39
|
+
3. Add a `@mcp.tool()` wrapper in `server.py` with a clear one-line docstring (it becomes the
|
|
40
|
+
tool description the model sees).
|
|
41
|
+
4. Add the tool name to `EXPECTED_TOOLS` in `tests/test_server.py` and to the table in
|
|
42
|
+
`README.md`.
|
|
43
|
+
|
|
44
|
+
## Pull requests
|
|
45
|
+
|
|
46
|
+
- Keep changes focused; one logical change per PR.
|
|
47
|
+
- Update the README/CHANGELOG when behaviour or the tool surface changes.
|
|
48
|
+
- Make sure `pytest` and `ruff check` pass.
|
|
49
|
+
|
|
50
|
+
## Releasing (maintainers)
|
|
51
|
+
|
|
52
|
+
1. Bump `version` in `pyproject.toml` and `__version__` in `src/wikijs_mcp/__init__.py`.
|
|
53
|
+
2. Update `CHANGELOG.md`.
|
|
54
|
+
3. Tag and push: `git tag vX.Y.Z && git push --tags`.
|
|
55
|
+
4. The **Publish** workflow builds and uploads to PyPI (as `mcp-server-wikijs`) via Trusted
|
|
56
|
+
Publishing. For the first release, set up a pending publisher on PyPI first — see the
|
|
57
|
+
header comment in `.github/workflows/publish.yml`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Margus
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-server-wikijs
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for managing a Wiki.js instance via its GraphQL admin API
|
|
5
|
+
Project-URL: Homepage, https://github.com/margus/wikijs-mcp
|
|
6
|
+
Project-URL: Repository, https://github.com/margus/wikijs-mcp
|
|
7
|
+
Project-URL: Issues, https://github.com/margus/wikijs-mcp/issues
|
|
8
|
+
Author-email: Margus <margus@imargus.net>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: claude,graphql,mcp,model-context-protocol,wiki.js,wikijs
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Documentation
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: httpx>=0.27
|
|
23
|
+
Requires-Dist: mcp>=1.2.0
|
|
24
|
+
Requires-Dist: python-dotenv>=1.0
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# wikijs-mcp
|
|
28
|
+
|
|
29
|
+
[](https://github.com/margus/wikijs-mcp/actions/workflows/ci.yml)
|
|
30
|
+
[](https://pypi.org/project/mcp-server-wikijs/)
|
|
31
|
+
[](https://pypi.org/project/mcp-server-wikijs/)
|
|
32
|
+
[](LICENSE)
|
|
33
|
+
|
|
34
|
+
An [MCP](https://modelcontextprotocol.io) server that lets Claude (or any MCP client)
|
|
35
|
+
manage a **[Wiki.js](https://js.wiki/)** instance through its **GraphQL admin API** —
|
|
36
|
+
read and write pages, manage navigation and groups, and trigger Git storage syncs.
|
|
37
|
+
|
|
38
|
+
> Published on PyPI as **`mcp-server-wikijs`**; the source repo is
|
|
39
|
+
> [`margus/wikijs-mcp`](https://github.com/margus/wikijs-mcp). The admin focus (navigation,
|
|
40
|
+
> groups, Git sync, raw GraphQL) sets it apart from content-authoring Wiki.js MCP servers.
|
|
41
|
+
|
|
42
|
+
> **How it works:** MCP does *not* run inside Wiki.js. This is a small stdio server your
|
|
43
|
+
> MCP client launches locally; it talks to `https://<your-wiki>/graphql`. If your Wiki.js
|
|
44
|
+
> is on a private network, the machine running this needs network reach to it.
|
|
45
|
+
|
|
46
|
+
## Tools
|
|
47
|
+
|
|
48
|
+
| Tool | What it does |
|
|
49
|
+
|------|--------------|
|
|
50
|
+
| `execute_graphql(query, variables?)` | Run any Wiki.js GraphQL query/mutation (escape hatch) |
|
|
51
|
+
| `list_pages(locale?, limit?)` | List pages (id, locale, path, title) |
|
|
52
|
+
| `get_page(path?, locale?, id?)` | Get a page's content + metadata |
|
|
53
|
+
| `create_page(path, title, content, …)` | Create a page |
|
|
54
|
+
| `update_page(id, content?, title?, …)` | Update a page — only passed fields change |
|
|
55
|
+
| `delete_page(id)` | Delete a page |
|
|
56
|
+
| `get_navigation()` | Current nav mode + tree |
|
|
57
|
+
| `set_navigation_mode(mode)` | `NONE` / `TREE` / `MIXED` / `STATIC` |
|
|
58
|
+
| `list_groups()` / `get_group(id)` | Groups + their permissions/page rules |
|
|
59
|
+
| `trigger_git_sync()` | Re-sync the Git storage target (re-import content repo) |
|
|
60
|
+
|
|
61
|
+
## Prerequisites
|
|
62
|
+
|
|
63
|
+
1. A running **Wiki.js 2.x** instance.
|
|
64
|
+
2. An **API key**: *Administration → API Access →* enable the API *→ New API Key*
|
|
65
|
+
(full access; the 2.x API isn't finely scoped). Copy the token.
|
|
66
|
+
|
|
67
|
+
## Quick start
|
|
68
|
+
|
|
69
|
+
Run it on demand with [`uvx`](https://docs.astral.sh/uv/) (no install) — set the two
|
|
70
|
+
environment variables and go:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
export WIKIJS_URL="https://wiki.example.com"
|
|
74
|
+
export WIKIJS_TOKEN="your-api-key"
|
|
75
|
+
uvx mcp-server-wikijs
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Or install it:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install mcp-server-wikijs # or: uv tool install mcp-server-wikijs
|
|
82
|
+
mcp-server-wikijs
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The server speaks MCP over **stdio**, so running it directly just waits for a client —
|
|
86
|
+
that's expected. Wire it into a client below.
|
|
87
|
+
|
|
88
|
+
## Configuration
|
|
89
|
+
|
|
90
|
+
| Variable | Required | Description |
|
|
91
|
+
|----------|----------|-------------|
|
|
92
|
+
| `WIKIJS_URL` | ✅ | Base URL of your Wiki.js instance (e.g. `https://wiki.example.com`). The GraphQL endpoint is `<URL>/graphql`. |
|
|
93
|
+
| `WIKIJS_TOKEN` | ✅ | Wiki.js API key. Aliases also accepted: `WIKIJS_API_TOKEN`, `WIKI_JS_MCP_API_TOKEN`. |
|
|
94
|
+
|
|
95
|
+
For standalone runs you can instead drop a `.env` next to where you launch it
|
|
96
|
+
(`cp .env.example .env`); it's loaded automatically.
|
|
97
|
+
|
|
98
|
+
## Register with an MCP client
|
|
99
|
+
|
|
100
|
+
### Claude Code
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
claude mcp add wikijs --env WIKIJS_URL=https://wiki.example.com --env WIKIJS_TOKEN=your-api-key -- uvx mcp-server-wikijs
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
…or add it to `.mcp.json` / your settings:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"mcpServers": {
|
|
111
|
+
"wikijs": {
|
|
112
|
+
"command": "uvx",
|
|
113
|
+
"args": ["mcp-server-wikijs"],
|
|
114
|
+
"env": {
|
|
115
|
+
"WIKIJS_URL": "https://wiki.example.com",
|
|
116
|
+
"WIKIJS_TOKEN": "your-api-key"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
> **Tip:** keep secrets out of committed files — reference an env var that's already in
|
|
124
|
+
> your shell, e.g. `"WIKIJS_TOKEN": "${WIKIJS_TOKEN}"`, and start the client from a shell
|
|
125
|
+
> where it's set.
|
|
126
|
+
|
|
127
|
+
### Claude Desktop
|
|
128
|
+
|
|
129
|
+
Add the same block to `claude_desktop_config.json`
|
|
130
|
+
(*Settings → Developer → Edit Config*), then restart Claude Desktop.
|
|
131
|
+
|
|
132
|
+
## Examples
|
|
133
|
+
|
|
134
|
+
Once registered, ask your assistant things like:
|
|
135
|
+
|
|
136
|
+
- *"List every page under `clients/` in the `en` locale."*
|
|
137
|
+
- *"Create a page at `guides/onboarding` titled 'Onboarding' with this content: …"*
|
|
138
|
+
- *"Update page 31 — append a 'Troubleshooting' section, leave everything else."*
|
|
139
|
+
- *"Trigger a Git sync so the wiki re-imports the content repo."*
|
|
140
|
+
|
|
141
|
+
## Security
|
|
142
|
+
|
|
143
|
+
The Wiki.js API key is **full-admin** — treat it as a privileged credential. Keep it in
|
|
144
|
+
your secrets manager / environment, never commit it, and revoke or rotate it anytime from
|
|
145
|
+
*Wiki.js → API Access*. Every write tool acts with that key's full authority, so review
|
|
146
|
+
mutations before approving them.
|
|
147
|
+
|
|
148
|
+
## Development
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
git clone https://github.com/margus/wikijs-mcp
|
|
152
|
+
cd wikijs-mcp
|
|
153
|
+
uv sync # install runtime + dev deps
|
|
154
|
+
uv run pytest # run the test suite (no live wiki needed — httpx is mocked)
|
|
155
|
+
uv run ruff check . # lint
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The Wiki.js logic lives in `src/wikijs_mcp/client.py` (`WikiJSClient`), unit-tested against
|
|
159
|
+
`httpx.MockTransport`. `src/wikijs_mcp/server.py` is a thin layer of MCP tool wrappers over
|
|
160
|
+
it. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# wikijs-mcp
|
|
2
|
+
|
|
3
|
+
[](https://github.com/margus/wikijs-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/mcp-server-wikijs/)
|
|
5
|
+
[](https://pypi.org/project/mcp-server-wikijs/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
An [MCP](https://modelcontextprotocol.io) server that lets Claude (or any MCP client)
|
|
9
|
+
manage a **[Wiki.js](https://js.wiki/)** instance through its **GraphQL admin API** —
|
|
10
|
+
read and write pages, manage navigation and groups, and trigger Git storage syncs.
|
|
11
|
+
|
|
12
|
+
> Published on PyPI as **`mcp-server-wikijs`**; the source repo is
|
|
13
|
+
> [`margus/wikijs-mcp`](https://github.com/margus/wikijs-mcp). The admin focus (navigation,
|
|
14
|
+
> groups, Git sync, raw GraphQL) sets it apart from content-authoring Wiki.js MCP servers.
|
|
15
|
+
|
|
16
|
+
> **How it works:** MCP does *not* run inside Wiki.js. This is a small stdio server your
|
|
17
|
+
> MCP client launches locally; it talks to `https://<your-wiki>/graphql`. If your Wiki.js
|
|
18
|
+
> is on a private network, the machine running this needs network reach to it.
|
|
19
|
+
|
|
20
|
+
## Tools
|
|
21
|
+
|
|
22
|
+
| Tool | What it does |
|
|
23
|
+
|------|--------------|
|
|
24
|
+
| `execute_graphql(query, variables?)` | Run any Wiki.js GraphQL query/mutation (escape hatch) |
|
|
25
|
+
| `list_pages(locale?, limit?)` | List pages (id, locale, path, title) |
|
|
26
|
+
| `get_page(path?, locale?, id?)` | Get a page's content + metadata |
|
|
27
|
+
| `create_page(path, title, content, …)` | Create a page |
|
|
28
|
+
| `update_page(id, content?, title?, …)` | Update a page — only passed fields change |
|
|
29
|
+
| `delete_page(id)` | Delete a page |
|
|
30
|
+
| `get_navigation()` | Current nav mode + tree |
|
|
31
|
+
| `set_navigation_mode(mode)` | `NONE` / `TREE` / `MIXED` / `STATIC` |
|
|
32
|
+
| `list_groups()` / `get_group(id)` | Groups + their permissions/page rules |
|
|
33
|
+
| `trigger_git_sync()` | Re-sync the Git storage target (re-import content repo) |
|
|
34
|
+
|
|
35
|
+
## Prerequisites
|
|
36
|
+
|
|
37
|
+
1. A running **Wiki.js 2.x** instance.
|
|
38
|
+
2. An **API key**: *Administration → API Access →* enable the API *→ New API Key*
|
|
39
|
+
(full access; the 2.x API isn't finely scoped). Copy the token.
|
|
40
|
+
|
|
41
|
+
## Quick start
|
|
42
|
+
|
|
43
|
+
Run it on demand with [`uvx`](https://docs.astral.sh/uv/) (no install) — set the two
|
|
44
|
+
environment variables and go:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
export WIKIJS_URL="https://wiki.example.com"
|
|
48
|
+
export WIKIJS_TOKEN="your-api-key"
|
|
49
|
+
uvx mcp-server-wikijs
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or install it:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install mcp-server-wikijs # or: uv tool install mcp-server-wikijs
|
|
56
|
+
mcp-server-wikijs
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The server speaks MCP over **stdio**, so running it directly just waits for a client —
|
|
60
|
+
that's expected. Wire it into a client below.
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
| Variable | Required | Description |
|
|
65
|
+
|----------|----------|-------------|
|
|
66
|
+
| `WIKIJS_URL` | ✅ | Base URL of your Wiki.js instance (e.g. `https://wiki.example.com`). The GraphQL endpoint is `<URL>/graphql`. |
|
|
67
|
+
| `WIKIJS_TOKEN` | ✅ | Wiki.js API key. Aliases also accepted: `WIKIJS_API_TOKEN`, `WIKI_JS_MCP_API_TOKEN`. |
|
|
68
|
+
|
|
69
|
+
For standalone runs you can instead drop a `.env` next to where you launch it
|
|
70
|
+
(`cp .env.example .env`); it's loaded automatically.
|
|
71
|
+
|
|
72
|
+
## Register with an MCP client
|
|
73
|
+
|
|
74
|
+
### Claude Code
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
claude mcp add wikijs --env WIKIJS_URL=https://wiki.example.com --env WIKIJS_TOKEN=your-api-key -- uvx mcp-server-wikijs
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
…or add it to `.mcp.json` / your settings:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"mcpServers": {
|
|
85
|
+
"wikijs": {
|
|
86
|
+
"command": "uvx",
|
|
87
|
+
"args": ["mcp-server-wikijs"],
|
|
88
|
+
"env": {
|
|
89
|
+
"WIKIJS_URL": "https://wiki.example.com",
|
|
90
|
+
"WIKIJS_TOKEN": "your-api-key"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
> **Tip:** keep secrets out of committed files — reference an env var that's already in
|
|
98
|
+
> your shell, e.g. `"WIKIJS_TOKEN": "${WIKIJS_TOKEN}"`, and start the client from a shell
|
|
99
|
+
> where it's set.
|
|
100
|
+
|
|
101
|
+
### Claude Desktop
|
|
102
|
+
|
|
103
|
+
Add the same block to `claude_desktop_config.json`
|
|
104
|
+
(*Settings → Developer → Edit Config*), then restart Claude Desktop.
|
|
105
|
+
|
|
106
|
+
## Examples
|
|
107
|
+
|
|
108
|
+
Once registered, ask your assistant things like:
|
|
109
|
+
|
|
110
|
+
- *"List every page under `clients/` in the `en` locale."*
|
|
111
|
+
- *"Create a page at `guides/onboarding` titled 'Onboarding' with this content: …"*
|
|
112
|
+
- *"Update page 31 — append a 'Troubleshooting' section, leave everything else."*
|
|
113
|
+
- *"Trigger a Git sync so the wiki re-imports the content repo."*
|
|
114
|
+
|
|
115
|
+
## Security
|
|
116
|
+
|
|
117
|
+
The Wiki.js API key is **full-admin** — treat it as a privileged credential. Keep it in
|
|
118
|
+
your secrets manager / environment, never commit it, and revoke or rotate it anytime from
|
|
119
|
+
*Wiki.js → API Access*. Every write tool acts with that key's full authority, so review
|
|
120
|
+
mutations before approving them.
|
|
121
|
+
|
|
122
|
+
## Development
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
git clone https://github.com/margus/wikijs-mcp
|
|
126
|
+
cd wikijs-mcp
|
|
127
|
+
uv sync # install runtime + dev deps
|
|
128
|
+
uv run pytest # run the test suite (no live wiki needed — httpx is mocked)
|
|
129
|
+
uv run ruff check . # lint
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The Wiki.js logic lives in `src/wikijs_mcp/client.py` (`WikiJSClient`), unit-tested against
|
|
133
|
+
`httpx.MockTransport`. `src/wikijs_mcp/server.py` is a thin layer of MCP tool wrappers over
|
|
134
|
+
it. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
135
|
+
|
|
136
|
+
## License
|
|
137
|
+
|
|
138
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "mcp-server-wikijs"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "MCP server for managing a Wiki.js instance via its GraphQL admin API"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Margus", email = "margus@imargus.net" }]
|
|
14
|
+
keywords = [
|
|
15
|
+
"mcp",
|
|
16
|
+
"model-context-protocol",
|
|
17
|
+
"wiki.js",
|
|
18
|
+
"wikijs",
|
|
19
|
+
"graphql",
|
|
20
|
+
"claude",
|
|
21
|
+
]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 4 - Beta",
|
|
24
|
+
"Intended Audience :: Developers",
|
|
25
|
+
"License :: OSI Approved :: MIT License",
|
|
26
|
+
"Programming Language :: Python :: 3",
|
|
27
|
+
"Programming Language :: Python :: 3.11",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Topic :: Software Development :: Libraries",
|
|
31
|
+
"Topic :: Documentation",
|
|
32
|
+
]
|
|
33
|
+
dependencies = [
|
|
34
|
+
"mcp>=1.2.0",
|
|
35
|
+
"httpx>=0.27",
|
|
36
|
+
"python-dotenv>=1.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/margus/wikijs-mcp"
|
|
41
|
+
Repository = "https://github.com/margus/wikijs-mcp"
|
|
42
|
+
Issues = "https://github.com/margus/wikijs-mcp/issues"
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
mcp-server-wikijs = "wikijs_mcp.server:main"
|
|
46
|
+
|
|
47
|
+
[dependency-groups]
|
|
48
|
+
dev = [
|
|
49
|
+
"pytest>=8.0",
|
|
50
|
+
"pytest-asyncio>=0.23",
|
|
51
|
+
"ruff>=0.6",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[tool.hatch.build.targets.wheel]
|
|
55
|
+
packages = ["src/wikijs_mcp"]
|
|
56
|
+
|
|
57
|
+
[tool.pytest.ini_options]
|
|
58
|
+
asyncio_mode = "auto"
|
|
59
|
+
testpaths = ["tests"]
|
|
60
|
+
pythonpath = ["src", "tests"]
|
|
61
|
+
|
|
62
|
+
[tool.ruff]
|
|
63
|
+
line-length = 100
|
|
64
|
+
target-version = "py311"
|
|
65
|
+
|
|
66
|
+
[tool.ruff.lint]
|
|
67
|
+
select = ["E", "F", "I", "UP", "B", "W"]
|