leafwiki-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@leafwiki-mcp search for pages tagged 'python'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
leafwiki-mcp
An MCP server that lets compatible clients discover, read, organize, revise, favorite, create, edit, and delete content in a LeafWiki instance.
Status
The project is at version 0.1.0 and is under early development. It runs as a synchronous MCP server over stdio. Installation from PyPI is not currently documented or supported; run it from GitHub directly or from a source checkout.
Related MCP server: mediawiki-mcp-server
Prerequisites
Python 3.12 or newer
Installation
Choose the method that matches how you plan to use the server. All methods run the same
leafwiki-mcp command over stdio.
Run directly from GitHub (recommended)
Use uvx to run the server directly from the GitHub repository without cloning it or installing
it permanently:
uvx --from git+https://github.com/ipapadop/leafwiki-mcp.git leafwiki-mcpuvx creates an isolated environment and caches downloaded dependencies for later runs.
Install as a persistent tool
Install the server from GitHub when you want the leafwiki-mcp command to remain available on
your PATH:
uv tool install git+https://github.com/ipapadop/leafwiki-mcp.git
leafwiki-mcpIf uv reports that its tool directory is not on PATH, run uv tool update-shell and restart
your shell.
Run from a source checkout
Clone over HTTPS:
git clone https://github.com/ipapadop/leafwiki-mcp.git
cd leafwiki-mcp
uv syncOr clone over SSH:
git clone git@github.com:ipapadop/leafwiki-mcp.git
cd leafwiki-mcp
uv syncConfiguration
The server accepts command-line options or equivalent environment variables:
Option | Environment variable | Default |
|
|
|
|
| empty |
|
| empty |
|
|
|
Credentials are unnecessary when authentication is disabled. Accounts requiring TOTP are not supported; use a dedicated editor account without TOTP.
The password in the MCP client example below is stored directly in that client's configuration.
Protect the configuration as you would any other credential. For an authentication-disabled
LeafWiki instance, omit LEAFWIKI_USERNAME and LEAFWIKI_PASSWORD entirely.
Set LEAFWIKI_READ_ONLY=true or pass --read-only to register only discovery and retrieval
tools. The environment variable accepts true/false, 1/0, yes/no, and on/off
case-insensitively. Either command-line option overrides the environment value, so
--no-read-only explicitly enables read-write mode. Read-only mode provides defense in depth
against accidental changes; it does not replace LeafWiki's server-side authorization or
appropriately scoped credentials.
Running
If you installed leafwiki-mcp as a persistent tool, start it with:
leafwiki-mcpFrom a source checkout, start it with:
uv run leafwiki-mcpIn normal use, an MCP client starts the server for you. Use the configuration that matches your installation method.
Directly from GitHub (recommended)
{
"mcpServers": {
"leafwiki": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/ipapadop/leafwiki-mcp.git",
"leafwiki-mcp"
],
"env": {
"LEAFWIKI_URL": "https://wiki.example.com",
"LEAFWIKI_USERNAME": "mcp-editor",
"LEAFWIKI_PASSWORD": "replace-me"
}
}
}
}Persistent tool installation
{
"mcpServers": {
"leafwiki": {
"command": "leafwiki-mcp",
"env": {
"LEAFWIKI_URL": "https://wiki.example.com",
"LEAFWIKI_USERNAME": "mcp-editor",
"LEAFWIKI_PASSWORD": "replace-me"
}
}
}
}Source checkout
Replace /absolute/path/to/leafwiki-mcp with the location of your clone:
{
"mcpServers": {
"leafwiki": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/leafwiki-mcp",
"run",
"leafwiki-mcp"
],
"env": {
"LEAFWIKI_URL": "https://wiki.example.com",
"LEAFWIKI_USERNAME": "mcp-editor",
"LEAFWIKI_PASSWORD": "replace-me"
}
}
}
}The server always exposes these discovery and retrieval tools over stdio:
search_pages: search page text and tags with paginationget_page: retrieve Markdown content and metadata by ID or pathbrowse_tree: browse the page hierarchy with an optional depth limitget_page_links: retrieve backlinks, outgoing links, and broken linkslist_tags: discover tags and their usage countsfind_pages_by_property: find pages by structured property metadatalist_page_revisions: list revision history when revisions are enabledget_page_revision: retrieve a historical page snapshot when revisions are enabledcompare_page_revisions: compare two historical snapshotsget_indexing_status: inspect full-text indexing statelist_property_keys,find_page_by_title,lookup_path, andsuggest_slug: discover page metadata and pathslist_favorites: list personal bookmarks
In the default read-write mode, the server also exposes these mutation tools:
move_page,copy_page,ensure_path,convert_page, andpin_page: organize pagesadd_favoriteandremove_favorite: change personal bookmarksappend_to_page,update_page_tags, andupdate_page_properties: make focused page updatessort_pages: set the ordering of children under a pageadd_page,edit_page, anddelete_page: mutate pages using optimistic concurrency
Tools that select a page accept an ID or slash-separated path and prefer a non-empty ID when both are supplied. Revision tools require revisions to be enabled in LeafWiki. Favorites require an authenticated user when authentication is enabled.
Page edits and deletions use LeafWiki versions for optimistic concurrency. A conflict is returned as an error so callers can re-read the page and retry deliberately. Deletion is non-recursive by default; recursive deletion must be requested explicitly. Creating a page with content, tags, or properties performs a create followed by a versioned update, so creation may succeed even if the follow-up update fails.
Troubleshooting
Cannot connect: confirm
LEAFWIKI_URLincludeshttp://orhttps://, points to a running LeafWiki instance, and is reachable from the MCP client process. The server starts even when LeafWiki is unreachable on the network, reports the problem on stderr, and connects when a tool is first called, so a host that is briefly down does not require restarting the MCP client. A LeafWiki instance that answers with an error status still stops startup.Intermittent failures during a long session: the server logs in again and repeats the request when LeafWiki rejects an expired session. It also retries a request once when a pooled connection is dropped, except for state-changing requests that LeafWiki may already have processed; those are reported so they can be retried deliberately.
Authentication required: set both
LEAFWIKI_USERNAMEandLEAFWIKI_PASSWORD, or omit them when LeafWiki reports that authentication is disabled.TOTP required: TOTP accounts are unsupported. Use a dedicated editor account without TOTP.
Revision request fails: confirm revisions are enabled in the LeafWiki instance.
Update or deletion conflicts: re-read the page to obtain its current version, review the intervening change, and retry deliberately.
Development
The tests use mocked HTTP transports and clients. They do not require a live LeafWiki instance, network access, or real credentials.
uv sync
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv run pytestThe Quality GitHub Actions workflow runs Ruff lint, Ruff formatting verification, Pyright, and
Pytest for every pull request, every push to main, and manual dispatches. Run the same commands
locally before pushing.
Project links
License
This project is licensed under the MIT License.
Available Tools
29 toolsadd_favoriteC
Favorite a page for the authenticated user.
Args: id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: Serializable favorite confirmation.
Inputs: id, path. Returns: object
add_pageB
Create a page or section, optionally with content and metadata.
Args:
title: Display title for the new page.
slug: URL path segment for the new page.
parent_id: Parent identifier, or empty for the root.
kind: Page kind, either page or section.
content: Optional Markdown content.
tags: Optional tags.
properties: Optional structured properties.
Returns: JSON-compatible created page.
Inputs: slug (required), title (required), kind, tags, +3 more. Returns: object
append_to_pageB
Append Markdown content to a page.
Args: content: Markdown content to append. id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: JSON-compatible updated page.
Inputs: content (required), id, path. Returns: object
browse_treeC
Browse the page hierarchy, optionally limited to a depth.
Args: depth: Optional maximum tree depth.
Returns: LeafWiki page-tree object.
Inputs: depth. Returns: object
compare_page_revisionsB
Compare two historical page snapshots.
Args: base_revision_id: Revision used as the comparison base. target_revision_id: Revision compared with the base. id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: Revision comparison returned by LeafWiki.
Inputs: base_revision_id (required), target_revision_id (required), id, path. Returns: object
convert_pageB
Convert a page to a section or a section to a page.
Args:
target_kind: Destination kind, either page or section.
id: Page identifier, preferred when both selectors are supplied.
path: Slash-separated page path.
Returns: Serializable conversion confirmation.
Inputs: target_kind (required), id, path. Returns: object
copy_pageB
Copy a page and its assets.
Args: title: Title for the copied page. slug: Slug for the copied page. id: Source page identifier, preferred when both selectors are supplied. path: Slash-separated source page path. target_parent_id: Destination parent identifier, or empty for root.
Returns: JSON-compatible copied page.
Inputs: slug (required), title (required), id, path, +1 more. Returns: object
delete_pageB
Delete a page after fetching its current version.
Args:
id: Page identifier, preferred when both selectors are supplied.
path: Slash-separated page path.
recursive: Whether to delete descendants recursively. Defaults to False.
Returns: Serializable deletion confirmation.
Inputs: id, path, recursive. Returns: object
edit_pageB
Edit a page while preserving omitted fields.
Args: id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path. title: Optional replacement title; omitted values are preserved. slug: Optional replacement slug; omitted values are preserved. content: Optional replacement content; omitted values are preserved. tags: Optional replacement tags; omitted values are preserved. properties: Optional replacement properties; omitted values are preserved.
Returns: JSON-compatible updated page.
Inputs: id, path, slug, tags, +3 more. Returns: object
ensure_pathB
Ensure a nested page path exists.
Args:
path: Slash-separated path to ensure.
title: Title for the final node.
kind: Kind for the final node, either page or section.
Returns: JSON-compatible final page.
Inputs: path (required), title (required), kind. Returns: object
find_page_by_titleC
Find pages by title.
Args: title: Title to match.
Returns: Title-match result returned by LeafWiki.
Inputs: title (required). Returns: object
find_pages_by_propertyB
Find pages carrying a property key and optional value.
Args: key: Required property key. value: Optional property value to match.
Returns: Matching page summaries.
Inputs: key (required), value. Returns: result
get_indexing_statusB
Get full-text search indexing status.
Returns: Indexing status returned by LeafWiki.
Inputs: no named parameters. Returns: object
get_pageB
Get a page by ID or path, including content and metadata.
Args: id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: JSON-compatible page.
Inputs: id, path. Returns: object
get_page_linksB
Get backlinks, outgoing links, and broken links for a page.
Args: id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: Link information returned by LeafWiki.
Inputs: id, path. Returns: object
get_page_revisionA
Get a page revision; requires revisions to be enabled.
Args: revision_id: Revision identifier to retrieve. id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: Historical page snapshot.
Inputs: revision_id (required), id, path. Returns: object
list_favoritesB
List the authenticated user's favorite pages.
Returns: Favorite page summaries.
Inputs: no named parameters. Returns: result
list_page_revisionsA
List page revisions; requires revisions to be enabled.
Args: id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path. cursor: Optional pagination cursor. limit: Maximum number of revisions.
Returns: Revision metadata and pagination information.
Inputs: id, path, limit, cursor. Returns: object
list_property_keysC
List available property keys.
Args: query: Optional property-key filter. limit: Maximum number of keys.
Returns: Property-key objects returned by LeafWiki.
Inputs: limit, query. Returns: result
list_tagsB
List tags and usage counts, optionally filtering by name.
Args: query: Optional tag-name filter. selected: Tags LeafWiki should retain in the result set. limit: Maximum number of tags.
Returns: Tag objects returned by LeafWiki.
Inputs: limit, query, selected. Returns: result
lookup_pathB
Resolve a path into tree segments.
Args: path: Slash-separated page path to resolve.
Returns: Existing and missing path segments.
Inputs: path (required). Returns: object
move_pageB
Move a page under a new parent.
Args: id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path. parent_id: Destination parent identifier, or empty for root. position: Optional zero-based position under the parent.
Returns: Serializable move confirmation.
Inputs: id, path, position, parent_id. Returns: object
pin_pageB
Pin or unpin a page.
Args: pinned: Whether the page should be pinned. id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: JSON-compatible updated page.
Inputs: id, path, pinned. Returns: object
remove_favoriteA
Remove a page from the authenticated user's favorites.
Args: id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: Serializable removal confirmation.
Inputs: id, path. Returns: object
search_pagesA
Search pages by text and tags, returning excerpts and tag facets.
Args: query: Full-text search query. tags: Optional tags used to filter results. offset: Zero-based result offset. limit: Maximum number of results.
Returns: Search result object returned by LeafWiki.
Inputs: tags, limit, query, offset. Returns: object
sort_pagesB
Set the child ordering under a parent page.
Args: parent_id: Parent identifier, or empty for root. ordered_ids: Child identifiers in their desired order.
Returns: Serializable sort confirmation.
Inputs: parent_id (required), ordered_ids (required). Returns: object
suggest_slugB
Suggest an available slug for a title.
Args: title: Title from which to derive a slug. parent_id: Parent used to determine availability. current_id: Existing page to exclude from conflicts.
Returns: Slug suggestion returned by LeafWiki.
Inputs: title (required), parent_id, current_id. Returns: object
update_page_propertiesB
Replace a page's properties.
Args: properties: Complete replacement property mapping. id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: JSON-compatible updated page.
Inputs: properties (required), id, path. Returns: object
update_page_tagsA
Replace a page's tags.
Args: tags: Complete replacement tag list. id: Page identifier, preferred when both selectors are supplied. path: Slash-separated page path.
Returns: JSON-compatible updated page.
Inputs: tags (required), id, path. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 29 tools
Most tools have distinct purposes, but several boundaries are blurred: edit_page can replace tags, properties, and content, duplicating update_page_tags, update_page_properties, and append_to_page; move_page overlaps sort_pages, and add_page overlaps ensure_path. Descriptions help, but the set still presents multiple overlapping update and path-creation options.
All tool names use consistent snake_case with a verb-first pattern (get_, list_, find_, update_, add_, delete_, etc.). Synonym variation (get/find/search/browse/lookup) exists but does not break the predictable naming convention.
At 29 tools, the surface is heavy for a wiki MCP server, and several tools are redundant conveniences (e.g., update_page_tags, update_page_properties, append_to_page) that edit_page already covers. The count exceeds the 25+ threshold for 'too many' in the rubric.
The set covers the core wiki lifecycle well: page CRUD, move, copy, sort, revisions, tags, properties, favorites, search, tree browsing, and link inspection. Minor gaps exist (e.g., dedicated asset management, tag rename/delete, bulk operations), but no major dead ends.
Maintenance
Related MCP Connectors
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
An MCP server that used to create notes
An MCP server for deep research or task groups
MCP-native open-source Notion alternative: read & write pages, databases and kanban boards.
Related MCP Servers
- AlicenseBqualityBmaintenanceA secure MCP server for interacting with MediaWiki instances, allowing users to search, read, create, and manage wiki content like pages, categories, and files. It supports both public and private wikis with comprehensive authentication for full read and write operations.19AGPL 3.0
- AlicenseAqualityAmaintenanceMCP server for MediaWiki wikis. Search, read, edit, and manage wiki content from AI assistants. Includes formatting, link checking, revision history, and markdown conversion.4323MIT
- FlicenseNot gradedqualityDmaintenanceMCP server for managing a personal markdown wiki. Provides search, navigation, read, write, delete, and move tools with automatic index.md management.-
- AlicenseNot gradedqualityDmaintenanceMCP server for mind-wiki — access your personal knowledge wiki from any directory or MCP-compatible client.MIT