gramps-remote-mcp
Click on "Install 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., "@gramps-remote-mcpsearch for John Smith"
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.
gramps-remote-mcp
A remote Model Context Protocol (MCP) server for Gramps, the open-source genealogy application. It lets an MCP client (Claude, or any MCP-capable assistant) read and edit a family tree hosted on a running Gramps Web instance through its REST API.
Unlike MCP servers that read a local Gramps database file, this one talks to Gramps Web over HTTP, so it works against a live, shared instance — and it focuses on guided, guarded write operations: new records are tagged as unconfirmed for later review, and field mutations and record creates are protected by before/after snapshots and record-count guards.
Tools
The server exposes 27 tools over the MCP stdio transport, plus 4 optional destructive
tools (gramps_delete_person, gramps_delete_family, gramps_delete_blog_post,
gramps_delete_all_objects) that are registered only when explicitly enabled — see
Destructive tools.
Read
Tool | Purpose |
| Fetch the current live record for a person by Gramps ID (e.g. |
| Search people (case-insensitive substring) across first name, surname, the combined |
| List people, optionally selecting fields ( |
| Return the tree's object counts (people, families, events, notes, media, …) — handy as a before/after guard. |
| Return the person and their descendants as a nested JSON tree, |
| Return the person and their ancestors as a nested JSON tree, |
| Return a person's family context: parent families (father/mother slots) and own families (partner + children). Each person carries its own |
Write
Tool | Purpose |
| Set a person's gender ( |
| Set the primary surname, optionally the name type (e.g. |
| Set a person's primary given (first) name. Non-destructive; returns before/after. |
| Set gender for many people in one call ( |
| Set the primary surname for many people in one call ( |
| Add a |
| Add an alternate name of a given type (e.g. |
| Swap a person's primary name with one of their alternate names ( |
| Create a new person, tagged as unconfirmed for later review. Returns the new Gramps ID. |
| Create a family linking one or two spouses. Returns the new family's Gramps ID. |
| Link an existing person as a child of an existing family. |
| Set the father or mother of an existing family ( |
| Remove a person from a family's children (inverse of |
| Remove the unconfirmed tag, marking a person as confirmed. |
Blog posts
A blog post is a Source object tagged Blog, with its body text stored in the source's
first note — not a dedicated blog record (see docs/blog-crud.md for
the full data model). The body's storage format is controlled by GRAMPS_BLOG_BODY_FORMAT:
plain text by default, or HTML (rendered and sanitized server-side) when set to html.
A post's body-note type is fixed when the post is created, so set GRAMPS_BLOG_BODY_FORMAT once
per deployment: flipping it on a tree that already has posts leaves those posts rendering in their
original format (a later HTML update to a text-mode post shows up escaped — visible but harmless).
Deleting a blog post (gramps_delete_blog_post) is destructive and only available when the
destructive-tools gate is on — see Destructive tools.
Tool | Purpose |
| Create a blog post (a Source tagged |
| List blog posts (Sources tagged |
| Fetch one blog post by its Source Gramps ID. Returns title, author, change (unix ts), the body as rendered HTML ( |
| Update a blog post's title, body, and/or author (only what you pass). |
Destructive tools
These destructive tools exist but are off by default and not even registered, so MCP clients never see them unless you opt in:
Tool | Purpose |
| Permanently delete a person (for duplicates / erroneous entries). Requires |
| Permanently delete a family — for cleaning up an orphaned/childless family left behind after re-homing its children. Requires |
| Permanently delete a blog post. Requires |
| Permanently delete every object in the tree — people, families, events, places, sources, citations, repositories, media, notes and tags. Requires |
To enable it, set GRAMPS_ENABLE_DESTRUCTIVE=1 in the server's environment; the account
also needs delete rights on the tree. Leave it unset for a read/edit-only deployment.
Wiping the tree. gramps_delete_all_objects is the one irreversible operation here, and
it takes two arguments rather than one: confirm=True plus expected_count, the tree's
current total object count (call gramps_get_object_counts and sum it). A mismatch aborts
before anything is deleted, which makes "count it, then destroy it" the only way to express
the call. There is no undo — run gramps_export_tree first; that backup file is the way back.
Together with gramps_import_file it makes a full reset three calls: export, wipe, import.
Backup / Restore
Two tools move whole-tree files through a mounted backup directory:
gramps_export_tree(filename=None, extension="gramps")— writes a.gramps(gzip XML) backup into the backup directory; returns{path, bytes, counts}. Read-only, always available.gramps_import_file(filename, extension="gramps")— imports a file from the backup directory into the tree (additive — Gramps import never merges, it stacks). Returns{before, after, added}. Requires the account to have OWNER role (GRAMPS_ROLE=4when runningops/setup-automation-user.sh).
Set GRAMPS_BACKUP_DIR to a directory inside the container and mount a host
directory there so files survive and are reachable from the host:
docker run --rm -i \
--env-file .env \
-v /home/you/gramps/export:/data \
-e GRAMPS_BACKUP_DIR=/data \
gramps-remote-mcpExport writes to that directory; for import, drop the file into the host
directory first, then call gramps_import_file("your-file.gramps"). Completion
of an import is confirmed by polling object counts (never the task endpoint), so
it works on both synchronous and Celery-backed Gramps Web deployments. An import
that adds no objects still counts as done: once the counts have held steady for
30 seconds it returns added: 0 rather than timing out.
Related MCP server: Overleaf MCP Server
Prerequisites
A running Gramps Web instance reachable over HTTP(S) with its REST API enabled.
A Gramps Web user account with the EDITOR role (role
3). Editor rights are required for the write tools (create person/family, set fields, add children, confirm).Python 3.12+ (or Docker) to run the server.
The server authenticates with username/password against POST /api/token/, then sends the
returned JWT as a bearer token on every request and transparently re-authenticates on a
401.
Tip: Create a dedicated, least-privilege automation user rather than reusing a personal login. The helper script
ops/setup-automation-user.shcreates a persistent EDITOR user and prints a generated password once.
Configuration
The server reads its connection settings from environment variables (see
.env.example):
Variable | Description |
| Base URL of the Gramps Web instance, e.g. |
| Username of the EDITOR-role account. |
| Password for that account. |
Copy .env.example to .env and fill in real values. .env is git-ignored — never
commit credentials.
Run with Docker
docker build -t gramps-remote-mcp .
docker run --rm -i --env-file .env gramps-remote-mcpThe image runs python server.py as its entrypoint and speaks MCP over stdio, so -i
(interactive stdin) is required.
Run locally
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
GRAMPS_BASE_URL=https://gramps.example.com \
GRAMPS_USERNAME=mcp-automation \
GRAMPS_PASSWORD=... \
.venv/bin/python server.pyConfigure an MCP client
Add the server to your MCP client configuration. Example (Claude Desktop / .mcp.json
style), using the Docker image:
{
"mcpServers": {
"gramps": {
"command": "docker",
"args": ["run", "--rm", "-i", "--env-file", "/absolute/path/to/.env", "gramps-remote-mcp"]
}
}
}Or run the Python script directly:
{
"mcpServers": {
"gramps": {
"command": "/absolute/path/to/.venv/bin/python",
"args": ["/absolute/path/to/server.py"],
"env": {
"GRAMPS_BASE_URL": "https://gramps.example.com",
"GRAMPS_USERNAME": "mcp-automation",
"GRAMPS_PASSWORD": "..."
}
}
}
}Design focus
Unconfirmed lifecycle.
gramps_add_persontags every new record as unconfirmed (a dedicated review tag);gramps_confirm_personremoves it. This gives you a review queue for records created by an assistant before they are accepted as final.Guarded writes. Field mutations capture a
before/aftersnapshot and verify that the total person (or family) count is unchanged — or increased by exactly one on a create — raising an error otherwise, so an unexpected side effect fails loudly instead of silently corrupting the tree. Structural family edits (add_child_to_family,remove_child_from_family,set_family_parent) instead PUT the whole family and rely on the Gramps Web API's referential integrity rather than a local count guard; the destructivedelete_personkeeps its own exact −1 person-count guard.Idempotency guards.
gramps_add_child_to_familyrefuses to add a child that is already linked; the unconfirmed tag is looked up and reused (with Unicode NFC normalization) rather than duplicated.Gender-based parent slots. When creating a family with
gramps_add_family, the spouse with gender Female is assigned as mother and the other as father; if gender doesn't disambiguate, call order decides deterministically. To place a parent into a specific slot regardless of sex, usegramps_set_family_parentwith an explicitrole.Structured relative trees.
gramps_get_descendantsandgramps_get_ancestorsreturn nested JSON trees bounded togradegenerations, andgramps_get_relationsgives a person's full family context in one call — rather than flat lists.Bloodline ≠ gender. In GEDCOM-imported data a family's
father/motherslots follow the bloodline, not sex. The relation/ancestor tools therefore never infer sex from a slot: every person carries its owngender, and partners are resolved as "the other slot" regardless of gender.gramps_set_family_parentfollows the same rule — you pass an explicitrole(father/mother), and it never reorders by sex.Batch writes with one guard.
gramps_set_gender_bulk/gramps_set_surname_bulkapply many updates under a single record-count guard. They are best-effort (not atomic): a failing item is reported inerrorsand does not abort the rest, and the count guard is reported (count_guard_ok) rather than raised so partial results are never lost.
Development
Install the dev dependencies and run the test suite:
python3 -m venv .venv
.venv/bin/pip install -r requirements-dev.txt
.venv/bin/python -m pytest -qThe tests mock the Gramps Web HTTP layer, so no live instance is required. Test fixtures use generic placeholder names.
Linting
This project uses ruff for linting and formatting
(config in pyproject.toml):
.venv/bin/ruff check . # lint
.venv/bin/ruff format . # auto-format
.venv/bin/ruff format --check . # verify formatting (what CI checks)Enable the git hooks so linting runs on every commit (auto-fixing) and blocks a push when anything is unclean:
.venv/bin/pre-commit install --hook-type pre-commit --hook-type pre-pushCI (.github/workflows/lint.yml) runs the same checks on every pull request; a green
ruff check is required to merge into main.
Notes on the Gramps Web API
docs/blog-crud.md— how blog posts are modelled in Gramps Web (aSourcetaggedBlog, not a note) and how to CRUD them over the REST API, including verified pitfalls aroundPUTsemantics,If-Matchand styled text.
Related projects
Several other MCP servers target Gramps; if this one doesn't fit your stack, one of these might:
cabout-me/gramps-mcp — Python, Gramps Web REST API, HTTP + stdio, with a broader ~16-tool set that also covers events, places, sources, citations and media (AGPL-3.0).
Alexey-N-Chernyshov/gramps-web-mcp-rs — a Rust server for the Gramps Web API with an optional read-only mode.
Scormave/gramps-web-mcp — a .NET 8 server for Gramps Web.
dsblank/gramps-ez-mcp — an easy-to-use Gramps MCP server.
adamhathcock/gramps-db-tool — works directly on a local Gramps database file rather than the Web API.
This project's niche is remote operation against a live Gramps Web instance with a small, opinionated, review-oriented guarded-write workflow: the unconfirmed-record lifecycle plus before/after and record-count guards.
License
Released under the MIT License.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityCmaintenanceMCP server for the GitHub REST API that enables interaction with repositories, pull requests, issues, branches, commits, reviews, and code search, with configurable write and destructive operations.
- AlicenseBqualityBmaintenanceEnables MCP clients to manage Overleaf projects via Git sync, including listing, reading, writing, and syncing files.445MIT
- AlicenseAqualityAmaintenanceProvides a single-writer MCP server for a governance-grade knowledge base of markdown documents with version control and query capabilities.12918Apache 2.0
- FlicenseAqualityBmaintenanceMCP server for the Gripp API, enabling CRUD operations on Gripp entities with built-in confirmation safety for mutations.9121
Related MCP Connectors
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
MCP server for AgentDocs (agentdocs.eu): read, search, write, comment on & share Markdown docs.
MCP server for Open Archives: Dutch genealogical records and historical page transcriptions.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/CyberGitJul/gramps-remote-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server