mcpField
G
Gramps Web MCP

Gramps Web MCP

Local
github.com/ScormaveGames & Entertainment15Updated today

About Gramps Web MCP

Gramps Web MCP is a companion server for existing Gramps Web installations, giving AI agents structured access to genealogy data. It combines kinship queries with guarded, undoable edits and supports multiple transports and a read-only mode.

Key features

  1. 01Read and edit genealogy records
  2. 02Full-text search and filtered browsing
  3. 03Query ancestors, descendants, and relations
  4. 04Undo edits with conflict checks
  5. 05Expose resources, prompts, and media previews
  6. 06Support read-only mode and multiple transports

Use cases

  1. 01Search and browse family-tree records
  2. 02Explore kinship and timelines
  3. 03Add or update people and families
  4. 04Review and revert changes to a tree

MCP support

It exposes genealogy tools, resources, and prompts to MCP clients. Transports include stdio, Streamable HTTP, and legacy SSE; read-only mode is available.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"scormave-gramps-web": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"MCP_TRANSPORT",
"-e",
"GRAMPS_API_URL",
"-e",
"GRAMPS_USERNAME",
"-e",
"GRAMPS_PASSWORD",
"-e",
"GRAMPS_REFRESH_TOKEN",
"-e",
"GRAMPS_TREE_ID",
"-e",
"GRAMPS_READ_ONLY",
"-e",
"GRAMPS_MUTATION_SERIALIZE",
"-e",
"GRAMPS_MUTATION_MIN_INTERVAL_MS",
"-e",
"GRAMPS_CONFIRMATION",
"-e",
"GRAMPS_LOG_LEVEL",
"-e",
"GRAMPS_MEDIA_RESOURCES_ENABLED",
"-e",
"GRAMPS_MEDIA_MAX_BYTES",
"-e",
"GRAMPS_MEDIA_ALLOW_PRIVATE",
"-e",
"GRAMPS_MEDIA_UPLOAD_DIRS",
"-e",
"GRAMPS_MEDIA_UPLOAD_MAX_BYTES",
"ghcr.io/scormave/gramps-web-mcp:2.7.0"
],
"env": {
"MCP_TRANSPORT": "<MCP_TRANSPORT>",
"GRAMPS_API_URL": "<GRAMPS_API_URL>",
"GRAMPS_USERNAME": "<GRAMPS_USERNAME>",
"GRAMPS_PASSWORD": "<GRAMPS_PASSWORD>",
"GRAMPS_REFRESH_TOKEN": "<GRAMPS_REFRESH_TOKEN>",
"GRAMPS_TREE_ID": "<GRAMPS_TREE_ID>",
"GRAMPS_READ_ONLY": "<GRAMPS_READ_ONLY>",
"GRAMPS_MUTATION_SERIALIZE": "<GRAMPS_MUTATION_SERIALIZE>",
"GRAMPS_MUTATION_MIN_INTERVAL_MS": "<GRAMPS_MUTATION_MIN_INTERVAL_MS>",
"GRAMPS_CONFIRMATION": "<GRAMPS_CONFIRMATION>",
"GRAMPS_LOG_LEVEL": "<GRAMPS_LOG_LEVEL>",
"GRAMPS_MEDIA_RESOURCES_ENABLED": "<GRAMPS_MEDIA_RESOURCES_ENABLED>",
"GRAMPS_MEDIA_MAX_BYTES": "<GRAMPS_MEDIA_MAX_BYTES>",
"GRAMPS_MEDIA_ALLOW_PRIVATE": "<GRAMPS_MEDIA_ALLOW_PRIVATE>",
"GRAMPS_MEDIA_UPLOAD_DIRS": "<GRAMPS_MEDIA_UPLOAD_DIRS>",
"GRAMPS_MEDIA_UPLOAD_MAX_BYTES": "<GRAMPS_MEDIA_UPLOAD_MAX_BYTES>"
}
}
}
}
Run commanddocker run -i --rm -e MCP_TRANSPORT -e GRAMPS_API_URL -e GRAMPS_USERNAME -e GRAMPS_PASSWORD -e GRAMPS_REFRESH_TOKEN -e GRAMPS_TREE_ID -e GRAMPS_READ_ONLY -e GRAMPS_MUTATION_SERIALIZE -e GRAMPS_MUTATION_MIN_INTERVAL_MS -e GRAMPS_CONFIRMATION -e GRAMPS_LOG_LEVEL -e GRAMPS_MEDIA_RESOURCES_ENABLED -e GRAMPS_MEDIA_MAX_BYTES -e GRAMPS_MEDIA_ALLOW_PRIVATE -e GRAMPS_MEDIA_UPLOAD_DIRS -e GRAMPS_MEDIA_UPLOAD_MAX_BYTES ghcr.io/scormave/gramps-web-mcp:2.7.0
Environment variables to set
MCP_TRANSPORTPinned to stdio for registry-installed containers that the client spawns itself. The image's own default is http (Streamable HTTP on port 8080) for networked Docker deployments; see the README for that setup.
GRAMPS_API_URLBase URL of your Gramps Web instance
GRAMPS_USERNAMEGramps Web API username; required with GRAMPS_PASSWORD unless GRAMPS_REFRESH_TOKEN is set
GRAMPS_PASSWORDSecretGramps Web API password; required with GRAMPS_USERNAME unless GRAMPS_REFRESH_TOKEN is set
GRAMPS_REFRESH_TOKENSecretRefresh token for instances with password login disabled; replaces GRAMPS_USERNAME and GRAMPS_PASSWORD
GRAMPS_TREE_IDGramps Web tree UUID
GRAMPS_READ_ONLYSet to true to block create, update, and delete tools
GRAMPS_MUTATION_SERIALIZESerialize create/update/delete HTTP calls in-process (set false to allow parallel writes)
GRAMPS_MUTATION_MIN_INTERVAL_MSMinimum milliseconds between mutation HTTP calls. Use 250 or 500 on SQLite if you see database is locked
GRAMPS_CONFIRMATIONWhether delete_object and undo_change ask the user to confirm through MCP elicitation: when-supported, required (refuse in clients that cannot ask), or off
GRAMPS_LOG_LEVELServer log level: Trace, Debug, Information, Warning, Error, Critical, or None. Debug and Trace also log request and response bodies, which contain genealogy data
GRAMPS_MEDIA_RESOURCES_ENABLEDSet to true to expose read_media and the media resources for thumbnails and full files, and to allow uploads from GRAMPS_MEDIA_UPLOAD_DIRS
GRAMPS_MEDIA_MAX_BYTESMaximum bytes returned by read_media or a media resource
GRAMPS_MEDIA_ALLOW_PRIVATESet to true to return bytes for media records marked private
GRAMPS_MEDIA_UPLOAD_DIRSAbsolute folders, separated by : (; on Windows), that create_media and update_media may upload photos, scans and PDFs from while GRAMPS_MEDIA_RESOURCES_ENABLED is true. Unset turns uploading off and hides create_media
GRAMPS_MEDIA_UPLOAD_MAX_BYTESLargest file create_media or update_media uploads

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
ocighcr.io/scormave/gramps-web-mcp:2.7.0

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

gramps-web-mcp

License: AGPL v3 .NET 10 MCP server version CI Docker on GHCR Gramps Web MCP MCP server – quality and maintenance score on Glama

Warning

Update to 2.3.1 or later. Before 2.3.1 the update_* tools could drop stored data that the call did not mention (#5). If you edited a tree with an earlier version, check it for dropped data.

Companion MCP server for the Gramps Web open-source genealogy platform. It gives AI agents structured, tool-based access to family trees through the Model Context Protocol.

This project is not a standalone genealogy UI or replacement for Gramps Web. Run it alongside an existing Gramps Web instance; your users, trees, media, permissions, and genealogy editing UI stay in Gramps Web.

Install in VS Code Install in VS Code Insiders Add to Cursor

The buttons add the server to VS Code or Cursor, which start it from the Docker image, so Docker must be installed. Details are under Over stdio in Docker; for Claude Desktop, install the MCPB extension.

Features

  • Up to 32 MCP tools — read, create, update, and delete people, families, events, places, sources, citations, notes, media, repositories, and tags
  • Search and browse — full-text search and paginated object listing, filtered by Gramps QL or by Gramps filter rules (everyone related to a person, people with no family links)
  • Kinship tools — ancestors, descendants, relationships, and timelines
  • Incremental links — add or remove one event, child, citation, or note with linkMode, keeping every other link
  • Undo — revert one transaction of the edit history, deletions included, after a check that it would not overwrite later edits or break links
  • Confirmation dialogs — delete_object and undo_change ask the user, not the model, before they change the tree, in clients that support MCP elicitation
  • Dates as Gramps writes them — ranges, before/after/about, and every Gramps calendar (1856-07-20 (Julian)), stored with the sort value Gramps computes
  • 8 MCP resources — type vocabularies, input guide, tree metadata, name settings, filter rules, and opt-in media previews/files for vision-capable agents
  • Media safeguards — size limits, private-record defaults, and previews with EXIF/GPS metadata stripped
  • MCP prompts — guided workflows for research, finding connections, adding people/families, imports, changing links, and citing facts
  • Multiple transports — stdio (local clients), Streamable HTTP, legacy SSE
  • Read-only mode — publish only read tools and block direct mutation calls

See the tool catalog for the full list. Upgrading from 1.x? Follow the 2.0 migration guide to update saved tool calls and client settings.

All outgoing requests to Gramps Web, including authentication, media downloads, and health checks, automatically identify this application with User-Agent: gramps-web-mcp/<version> (+https://github.com/Scormave/gramps-web-mcp). The version comes from the application build; no configuration is required.

Prerequisites

  • .NET 10 SDK (for local development)
  • A running Gramps Web instance with API access
  • Docker (optional, for container deployment)

Quick start

Local development (demo server)

run-local-server.sh connects to the public demo.grampsweb.org instance using well-known demo credentials (owner / owner):

./run-local-server.sh

The server starts with HTTP transport at http://127.0.0.1:8080/mcp. No API key is required when binding to loopback only.

Docker

Pre-built multi-arch images (linux/amd64, linux/arm64) are published to GitHub Container Registry. Docker picks the matching architecture automatically; amd64 covers most Unraid and x86 hosts, arm64 covers Apple Silicon and ARM SBCs:

docker pull ghcr.io/scormave/gramps-web-mcp:latest

docker run -p 8080:8080 \
  -e GRAMPS_API_URL=https://your-gramps.example.com \
  -e GRAMPS_USERNAME=your-user \
  -e GRAMPS_PASSWORD=your-password \
  -e GRAMPS_TREE_ID=your-tree-uuid \
  -e MCP_API_KEY=your-secret-api-key \
  ghcr.io/scormave/gramps-web-mcp:latest

For refresh-token authentication, replace the GRAMPS_USERNAME and GRAMPS_PASSWORD lines with -e GRAMPS_REFRESH_TOKEN=your-refresh-token.

Each published image has a build provenance attestation: a signed record, kept by GitHub and in the registry, of the repository, workflow and commit that built it. With the GitHub CLI, check that an image was built by this repository's GitHub Actions (with Docker Desktop installed, start it first: gh asks it for registry credentials):

gh attestation verify oci://ghcr.io/scormave/gramps-web-mcp:latest --repo Scormave/gramps-web-mcp

The image exposes a GET /health endpoint for Docker HEALTHCHECK, Unraid container health, and other uptime monitors. It returns HTTP 200 when the MCP server can authenticate against Gramps Web, or HTTP 503 otherwise. Probes reuse the token the tools use, so they do not log in to Gramps Web each time. The public response is minimal: { "status": "healthy" } or { "status": "unhealthy" }. Startup logs include a line such as Connected to Gramps Web at … once the API is reachable.

The image is built on Ubuntu Chiseled and has no shell or curl. Its HEALTHCHECK runs dotnet /app/GrampsWeb.Mcp.dll --health-check, which requests /health on the port from ASPNETCORE_URLS and exits with 0 on HTTP 200 and 1 otherwise. A health check you define yourself, in Compose or in a NAS app template, runs the same command:

healthcheck:
  test: ["CMD", "dotnet", "/app/GrampsWeb.Mcp.dll", "--health-check"]

If the server listens on an address that ASPNETCORE_URLS does not give, pass the URL after the option, for example --health-check http://localhost:9000.

The image defaults to Streamable HTTP (MCP_TRANSPORT=http) on port 8080, which is what the commands above use. Clients that spawn the container themselves (such as MCP Registry installs) instead run it over stdio with -e MCP_TRANSPORT=stdio and stdin kept open (docker run -i); that is the mode declared in server.json.

For read-only mode, add -e GRAMPS_READ_ONLY=true:

docker run -p 8080:8080 \
  -e GRAMPS_API_URL=https://your-gramps.example.com \
  -e GRAMPS_USERNAME=your-user \
  -e GRAMPS_PASSWORD=your-password \
  -e GRAMPS_TREE_ID=your-tree-uuid \
  -e MCP_API_KEY=your-secret-api-key \
  -e GRAMPS_READ_ONLY=true \
  ghcr.io/scormave/gramps-web-mcp:latest
Unraid installation

Unraid users can install gramps-web-mcp from Community Applications. The template source is maintained at Scormave/gramps-web-mcp-unraid. For Unraid-specific help, see the support thread on the Unraid forums.

Basic setup:

  1. In Unraid, open Apps / Community Applications.
  2. Search for gramps-web-mcp and install the template.
  3. Set GRAMPS_API_URL, GRAMPS_TREE_ID, and either GRAMPS_USERNAME plus GRAMPS_PASSWORD or GRAMPS_REFRESH_TOKEN for your Gramps Web instance. Set MCP_API_KEY when the MCP port is reachable from other machines on your network.
  4. Keep the default container port 8080, or map it to another host port.
  5. Start the container and check /health; it returns HTTP 200 once the service can authenticate to Gramps Web, with a minimal JSON response.

For the easiest pairing, run Gramps Web and gramps-web-mcp on the same Unraid Docker network and set GRAMPS_API_URL to the Gramps Web container URL. The MCP endpoint for clients is http://<unraid-host>:<mapped-port>/mcp; see Other MCP clients to connect them.

Gramps Web + MCP (Docker Compose)

To run Gramps Web and the MCP server on the same host and Docker network, use docker-compose.example.yml as a starting point:

cp docker-compose.example.yml docker-compose.yml
cp .env.example .env
# Complete the Gramps Web setup wizard, then set an authentication method in .env
docker compose up -d

Gramps Web is published on port 5055; MCP is on 8080 (/mcp and /health). Inside the compose network the MCP container reaches Gramps Web at http://grampsweb:5000.

Claude Desktop (MCPB extension)

One-click install for Claude Desktop is available as an MCP Bundle (.mcpb) from GitHub Releases. Download the bundle for your platform:

PlatformArtifact
macOS Apple Silicongramps-web-mcp-claude-desktop-osx-arm64-v*.mcpb
macOS Intelgramps-web-mcp-claude-desktop-osx-x64-v*.mcpb
Windows x64gramps-web-mcp-claude-desktop-win-x64-v*.mcpb
Linux x64gramps-web-mcp-claude-desktop-linux-x64-v*.mcpb
Linux ARM64gramps-web-mcp-claude-desktop-linux-arm64-v*.mcpb
  1. Download the .mcpb file for your OS from the latest release.
  2. Double-click it, or drag it into the Claude Desktop window.
  3. Enter your Gramps Web URL, username, password/token, and tree UUID.
  4. Leave Read-only mode enabled for your first session; disable it only when you want Claude to create or edit records.
  5. Complete installation and start a new chat.

The extension runs locally over stdio and does not require the .NET SDK on your machine. To check that a downloaded bundle came from this repository, see the attestation note under the release binary. See mcpb/README.md for packaging details and PRIVACY.md for the privacy policy.

To build a bundle locally:

./scripts/pack-release.sh osx-arm64   # or osx-x64, win-x64, linux-x64, linux-arm64
Other MCP clients

Other MCP clients, such as Claude Code, VS Code, Cursor, Codex, Antigravity CLI and Open WebUI, connect in one of three ways:

  • Over HTTP to a server that already runs in Docker, on Unraid or with Docker Compose. Each client needs only the server's address and API key, nothing is installed on the client's machine, and all clients share the one server.
  • Over stdio in Docker: the client starts the server's image for itself. Each machine needs Docker and the Gramps Web credentials. VS Code and Cursor add this setup with one click.
  • Over stdio with the release binary: the client starts the server from a single file downloaded from the release. Each machine needs the Gramps Web credentials, but neither Docker nor .NET.

Claude Desktop connects to servers added by URL from Anthropic's cloud, not from your computer, so it cannot reach a server on your home network. Use the MCPB extension there.

Over HTTP

Set MCP_API_KEY on the server (see HTTP authentication), then give each client the address and the key. The examples use http://192.168.1.10:8080/mcp and your-secret-api-key; replace both with your own.

Claude Code:

claude mcp add --transport http --scope user gramps-web http://192.168.1.10:8080/mcp \
  --header "Authorization: Bearer your-secret-api-key"

VS Code, in the user mcp.json or a workspace's .vscode/mcp.json. VS Code asks for the key when the server starts for the first time:

{
  "inputs": [
    {
      "type": "promptString",
      "id": "gramps-web-mcp-key",
      "description": "Gramps Web MCP API key",
      "password": true
    }
  ],
  "servers": {
    "gramps-web": {
      "type": "http",
      "url": "http://192.168.1.10:8080/mcp",
      "headers": { "Authorization": "Bearer ${input:gramps-web-mcp-key}" }
    }
  }
}

Cursor, in ~/.cursor/mcp.json:

{
  "mcpServers": {
    "gramps-web": {
      "url": "http://192.168.1.10:8080/mcp",
      "headers": { "Authorization": "Bearer your-secret-api-key" }
    }
  }
}

Codex, in ~/.codex/config.toml. Codex reads the key from the environment variable that bearer_token_env_var names, so set GRAMPS_WEB_MCP_KEY before you start it:

[mcp_servers.gramps-web]
url = "http://192.168.1.10:8080/mcp"
bearer_token_env_var = "GRAMPS_WEB_MCP_KEY"

Antigravity CLI, in ~/.gemini/config/mcp_config.json. Gemini CLI takes the same entry in ~/.gemini/settings.json, with httpUrl in place of serverUrl:

{
  "mcpServers": {
    "gramps-web": {
      "serverUrl": "http://192.168.1.10:8080/mcp",
      "headers": { "Authorization": "Bearer your-secret-api-key" }
    }
  }
}

Open WebUI 0.6.31 or later: an administrator opens Settings → Admin → Integrations, and under External Tool Servers adds a connection of type MCP (Streamable HTTP) with the server URL, auth Bearer and the API key in Key. Open WebUI connects from its own container, where localhost is that container: use the host's address, or the MCP container's name when both share a Docker network.

Keep in mind:

  • Plain HTTP carries the key and the tree data unencrypted. Keep the port on a network you trust, and from elsewhere connect to that network through a VPN rather than publishing the port on the internet.
  • The Cursor and Antigravity CLI files hold the key itself, so keep them out of a project's repository.
  • Every client works as the Gramps Web account the server is configured with, and Gramps Web records all their edits under that account.
  • Over stateless HTTP, the default, delete_object and undo_change cannot show their confirmation dialog; see Confirming deletes and undos.

To check the address and the key from a terminal, send an initialize request. The key also works as X-Api-Key: <key>:

curl -X POST http://192.168.1.10:8080/mcp \
  -H "Authorization: Bearer $MCP_API_KEY" \
  -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}},"id":1}'
Over stdio in Docker

The client starts a container for each session and removes it when the session ends. MCP_TRANSPORT=stdio is required because the image defaults to HTTP, and -e NAME without a value hands the container the variable from env, so the password stays off the docker command line:

{
  "mcpServers": {
    "gramps-web": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT=stdio",
        "-e", "GRAMPS_API_URL",
        "-e", "GRAMPS_USERNAME",
        "-e", "GRAMPS_PASSWORD",
        "-e", "GRAMPS_TREE_ID",
        "ghcr.io/scormave/gramps-web-mcp:latest"
      ],
      "env": {
        "GRAMPS_API_URL": "https://your-gramps.example.com",
        "GRAMPS_USERNAME": "your-user",
        "GRAMPS_PASSWORD": "your-password",
        "GRAMPS_TREE_ID": "your-tree-uuid"
      }
    }
  }
}

The install buttons at the top of this README add this entry to VS Code or Cursor. VS Code asks for the Gramps Web address, user name, password and tree ID when the server starts for the first time, and keeps the password in its secret storage. Cursor adds the placeholders shown above; replace them with your own before the first start.

  • Cursor (~/.cursor/mcp.json), Antigravity CLI (~/.gemini/config/mcp_config.json) and Gemini CLI (~/.gemini/settings.json) take this entry as it is.
  • Claude Code: pass the gramps-web object to claude mcp add-json --scope user gramps-web '<object>'.
  • VS Code: put the entry under servers instead of mcpServers and add "type": "stdio".
  • Codex: put the same command, args and env under [mcp_servers.gramps-web] in ~/.codex/config.toml.
  • Open WebUI connects over HTTP only.

Before the first start:

  • Pull the image once with docker pull ghcr.io/scormave/gramps-web-mcp:latest. Some clients give a server only a few seconds to start, too few for the download.
  • Inside the container localhost is the container itself. If Gramps Web runs on the same computer, use host.docker.internal in GRAMPS_API_URL; on Linux, also add "--add-host=host.docker.internal:host-gateway" to args.
  • For a refresh token, replace GRAMPS_USERNAME and GRAMPS_PASSWORD with GRAMPS_REFRESH_TOKEN in both lists. For read-only mode, add "-e", "GRAMPS_READ_ONLY=true" before the image name; other settings go the same way.
  • Uploads read files inside the container, so mount the upload folder with -v.
Over stdio with the release binary

Each release also carries the server as one self-contained file, the same one the Claude Desktop bundles hold. It starts over stdio unless told otherwise:

PlatformArchive
macOS Apple Silicongramps-web-mcp-osx-arm64.tar.gz
macOS Intelgramps-web-mcp-osx-x64.tar.gz
Windows x64gramps-web-mcp-win-x64.zip
Linux x64gramps-web-mcp-linux-x64.tar.gz
Linux ARM64gramps-web-mcp-linux-arm64.tar.gz

Unpack the archive for your platform into a folder of its own. On macOS or Linux (here Apple Silicon; change the archive name for yours):

mkdir -p ~/.local/share/gramps-web-mcp
curl -fL https://github.com/Scormave/gramps-web-mcp/releases/latest/download/gramps-web-mcp-osx-arm64.tar.gz \
  | tar -xz -C ~/.local/share/gramps-web-mcp

On Windows, in PowerShell:

curl.exe -fLo "$env:TEMP\gramps-web-mcp.zip" https://github.com/Scormave/gramps-web-mcp/releases/latest/download/gramps-web-mcp-win-x64.zip
Expand-Archive -Force "$env:TEMP\gramps-web-mcp.zip" "$env:LOCALAPPDATA\gramps-web-mcp"

Then point the client at the binary by its full path, since clients start it without a shell that would expand ~:

{
  "mcpServers": {
    "gramps-web": {
      "command": "/Users/you/.local/share/gramps-web-mcp/GrampsWeb.Mcp",
      "env": {
        "GRAMPS_API_URL": "https://your-gramps.example.com",
        "GRAMPS_USERNAME": "your-user",
        "GRAMPS_PASSWORD": "your-password",
        "GRAMPS_TREE_ID": "your-tree-uuid"
      }
    }
  }
}

On Windows, command is "C:\\Users\\you\\AppData\\Local\\gramps-web-mcp\\GrampsWeb.Mcp.exe": JSON needs each backslash doubled. Each client takes this entry the way it takes the Docker entry above.

  • Every setting is an environment variable in env, such as GRAMPS_REFRESH_TOKEN instead of the user name and password, or "GRAMPS_READ_ONLY": "true". Unlike in Docker, localhost in GRAMPS_API_URL and the upload folders are those of your own computer.
  • To update, close the client (Windows cannot replace a running binary), run the same commands again and start the client: the archive name carries no version, so the link always fetches the latest release, and the new binary replaces the old one.
  • The binary is not notarized by Apple. curl does not mark the download, so macOS runs it; if you downloaded the archive in a browser, macOS may refuse to start the binary until you remove the mark with xattr -d com.apple.quarantine ~/.local/share/gramps-web-mcp/GrampsWeb.Mcp.
  • On Linux it needs glibc and ICU (libicu), which desktop distributions include; on Alpine or a minimal system, use Docker.
  • SHA256SUMS in each release lists the checksums of its files, and every file, the bundles included, has a build provenance attestation. To check a download, save the archive instead of piping it to tar and run gh attestation verify gramps-web-mcp-osx-arm64.tar.gz --repo Scormave/gramps-web-mcp with the GitHub CLI: it fails unless this repository's release workflow built that file.

The same binary can also serve the other machines over HTTP, like the image does; see Transports. To run the server from a source checkout instead, see Local development in the developer guide.

Images for vision-capable agents

Vision-capable agents can read opt-in media through read_media or through binary MCP resources such as gramps://media/{handle}/thumbnail/{size} and gramps://media/{handle}/file. read_media defaults to a thumbnail: a JPEG preview (PNG when the image has transparency) rendered by the server from the original, 1568 pixels on the long edge so handwriting and small print in document scans stay legible. Pass size (1–4096) for a smaller or larger preview; images are never upscaled. Previews are re-encoded from pixels, so EXIF (including GPS), XMP, IPTC, and ICC metadata are not sent. They can be rendered from JPEG, PNG, GIF, WebP, BMP, TIFF, TGA, PBM, and QOI originals; multi-page files use the first page. PDF and other non-image media, and AVIF, HEIC/HEIF, JPEG XL, and SVG images, have no preview. Use mode: "file" for an original file and omit size. File mode returns image, audio, or embedded blob resource content depending on MIME type; images that MCP clients cannot display, such as TIFF, come back as an embedded blob with a hint to use the thumbnail. End-to-end analysis depends on the MCP client forwarding the typed tool content or binary resource content to a capable model.

Configuration

Gramps connection
VariableDescription
GRAMPS_API_URLBase URL of your Gramps Web instance (no trailing slash)
GRAMPS_USERNAMEAPI user name
GRAMPS_PASSWORDAPI password
GRAMPS_TREE_IDTree UUID on that server
Refresh token instead of a password

If Gramps Web has password login turned off (OIDC_DISABLE_LOCAL_AUTH=true), set GRAMPS_REFRESH_TOKEN and leave GRAMPS_USERNAME and GRAMPS_PASSWORD unset. The server exchanges it for access tokens at /api/token/refresh/.

Get one while password login is still on:

curl -s -X POST https://gramps.example.com/api/token/ \
  -H 'Content-Type: application/json' \
  -d '{"username":"mcp","password":"..."}' | jq -r .refresh_token

Gramps Web refresh tokens do not expire. Treat it like a password. Deleting the user or rotating the Gramps Web secret key invalidates it.

Runtime mode
VariableDefault
GRAMPS_READ_ONLYfalse
GRAMPS_MUTATION_SERIALIZEtrue
GRAMPS_MUTATION_MIN_INTERVAL_MS0
  • GRAMPS_READ_ONLY: set to true to publish only read tools and block direct create, update, and delete calls.
  • GRAMPS_MUTATION_SERIALIZE: runs create/update/delete HTTP calls one at a time in this process. It also protects the complete read/modify/write sequence of update tools against other such calls in this process.
  • GRAMPS_MUTATION_MIN_INTERVAL_MS: minimum pause between mutation HTTP calls.

Runtime notes:

  • GRAMPS_READ_ONLY=false means the server starts in read/write mode.
  • The Claude Desktop MCPB extension is the exception: its setup form defaults to read-only for safer first use.
  • Write serialization and the optional interval protect typical Gramps Web SQLite trees from agent write bursts.
  • The write gate is in-process only. It does not coordinate across multiple MCP replicas, the Gramps Web UI, or other API clients.
  • SQLite deployments that still see database is locked on sequential edits should set GRAMPS_MUTATION_MIN_INTERVAL_MS=250 or 500.
  • On SQLite lock errors or upstream HTTP 429, mutation tools return a retryable MCP error with a short backoff hint instead of a generic 500.
  • Set GRAMPS_MUTATION_SERIALIZE=false when Gramps Web uses PostgreSQL and you want parallel writes.
Confirming deletes and undos

delete_object and undo_change ask the user to confirm in a dialog before they change the tree, when the client supports MCP elicitation. The dialog names the record, or lists what the undo will change, and the user ticks a box to go ahead. Declining or closing it changes nothing. Dry runs and refusals do not ask.

VariableDescriptionDefault
GRAMPS_CONFIRMATIONwhen-supported asks clients that support elicitation and runs as before in the others; required refuses deletes and undos in clients that cannot ask; off never askswhen-supported
  • Stateless Streamable HTTP (MCP_STATELESS=true, the default) cannot send requests to the client, so it never asks, and required refuses every delete and undo there. Set MCP_STATELESS=false to confirm over HTTP; stdio and legacy SSE keep a session and can ask.
  • Both tools also carry the anthropic/requiresUserInteraction tool metadata, whatever the setting. Clients that honour it, such as Claude Code, ask their own permission first, so the user may confirm twice; off keeps only the client's prompt.
  • The tool call lasts until the user answers. If the client cancels the call first, nothing changes.
  • The server logs once per client whether it asks.

See the tool catalog for the dialog and the replies.

Updating linked records

The nine update_* tools that accept link lists have a linkMode argument: replace (default), add, or remove. For example, update_person(handle: "PERSON_HANDLE", noteHandles: ["NOTE_HANDLE"], linkMode: "add") adds a note without copying the person's existing note list. remove takes the handles to unlink. An omitted list remains unchanged; [] clears a list only in replace mode. The mode applies to every supplied link list in the call. Existing link metadata is preserved by add; use replace to change that metadata. See the tool catalog for supported lists and concurrency limits.

Data dropped by updates before 2.3.1

Before 2.3.1 the update_* tools could drop stored data the call did not mention (#5). If you edited a tree with an earlier version, scripts/find-update-losses.py reads the Gramps Web transaction history and lists every value an update emptied, with the value it had and whether the record still lacks it:

GRAMPS_API_URL=https://gramps.example.com GRAMPS_USERNAME=me GRAMPS_PASSWORD=... \
  python3 scripts/find-update-losses.py --user MCP_ACCOUNT --until 2026-10-07 --json losses.json

It needs Python 3.9 or later and an account that may see private records, and it only reads. The history also holds edits made in the Gramps Web interface, and a value cleared on purpose looks the same as a dropped one, so check each finding before you restore it.

Media file access

Media byte tools/resources are disabled by default. get_object with objectType: "media" remains available for metadata without enabling file downloads. When disabled, read_media is omitted from tools/list; direct calls by a client that already knows its name return a configuration error without downloading bytes. The same setting switches uploads on and off.

VariableDescriptionDefault
GRAMPS_MEDIA_RESOURCES_ENABLEDEnables binary media tools/resources for thumbnails and full files, and uploadsfalse
GRAMPS_MEDIA_MAX_BYTESMaximum bytes returned by read_media or any media resource5242880
GRAMPS_MEDIA_ALLOW_PRIVATEAllows bytes for Gramps media records marked privatefalse

Prefer read_media(mode: "thumbnail") or gramps://media/{handle}/thumbnail/{size} for AI analysis. Full files can be large and sensitive, carry their original metadata, and are still subject to the size and private-record checks.

GRAMPS_MEDIA_MAX_BYTES limits what is returned to the client. To render a thumbnail, the server downloads the original from Gramps Web into memory, up to 50 MiB or GRAMPS_MEDIA_MAX_BYTES, whichever is larger, and up to 100 megapixels; only the preview is returned.

GRAMPS_MEDIA_ALLOWED_MIME_TYPES is no longer used. Remove it from your configuration; the server ignores it and logs a warning at startup if it is set.

Media upload

create_media uploads a photo, document scan or PDF from a folder on the server and shows it on the records named in attachTo; update_media takes filePath to replace a record's file. Uploading needs media file access (GRAMPS_MEDIA_RESOURCES_ENABLED=true) and at least one folder in GRAMPS_MEDIA_UPLOAD_DIRS; until both are set, create_media is hidden. Only files inside those folders can be read, symbolic links included, and only JPEG, PNG, GIF, WebP, TIFF, BMP and PDF files, judged by content. A file the tree already stores is reused, not uploaded twice. In Docker, mount the folder into the container and set the path as seen inside it.

VariableDescriptionDefault
GRAMPS_MEDIA_UPLOAD_DIRSAbsolute folders, separated by : (; on Windows), that create_media and update_media may upload fromunset (off)
GRAMPS_MEDIA_UPLOAD_MAX_BYTESLargest file create_media or update_media uploads52428800
Transports

Set GRAMPS_API_URL, GRAMPS_TREE_ID, and either the username/password pair or GRAMPS_REFRESH_TOKEN as described above.

ValueBehavior
(unset or stdio)JSON-RPC over stdin/stdout (default; local clients).
httpStreamable HTTP at MCP_PATH (default /mcp).
sseLegacy MCP SSE: GET {MCP_PATH}/sse + POST {MCP_PATH}/message. Stateful; use for older clients only.

For HTTP transport, responses stream over SSE. See the Streamable HTTP spec for protocol details. Set ASPNETCORE_URLS to choose the listen address, for example http://127.0.0.1:8080.

Optional (MCP transport)
VariableDescriptionDefault
ASPNETCORE_URLSListen URLs for HTTP/SSE—
MCP_PATHURL prefix for MCP endpoints/mcp
MCP_STATELESSStateless mode for Streamable HTTPtrue
MCP_ENABLE_LEGACY_SSEExpose legacy /sse with http transportfalse
MCP_API_KEYShared secret for HTTP/SSE transport (comma-separated for rotation; min 16 characters)—
MCP_ALLOWED_ORIGINSBrowser origins allowed to call HTTP/SSE endpoints, comma-separated; requests from other origins get 403—
HTTP authentication

When MCP_API_KEY is set, all MCP HTTP/SSE endpoints require the key on every request. GET /health stays anonymous for Docker and load-balancer probes.

Generate a key:

openssl rand -base64 32

Without a key, the server still starts (backward compatible). If the listen address is not loopback-only, a warning is logged recommending that you set MCP_API_KEY, use a reverse proxy with its own authentication, or bind to 127.0.0.1 for local use only.

Inside Docker, ASPNETCORE_URLS is typically http://0.0.0.0:8080, so the warning appears even when the host publishes the port on 127.0.0.1 only. That is expected when external access is already restricted.

Browser origins

Browsers send an Origin header with their requests, and the server refuses with 403 every request whose origin is not listed in MCP_ALLOWED_ORIGINS. This keeps a web page on another site from calling tools with the server's Gramps credentials, also through DNS rebinding, which works even when the server listens on 127.0.0.1 only. MCP clients outside a browser, such as Claude Desktop, Claude Code and SDK clients, send no Origin and need no setting. For a browser-based MCP client you trust, list its origin:

MCP_ALLOWED_ORIGINS=https://app.example.com

SECURITY.md also describes the optional AllowedHosts check of the Host header.

Logging
VariableDescriptionDefault
GRAMPS_LOG_LEVELLog level for the server's own messages: Trace, Debug, Information, Warning, Error, Critical, NoneInformation

Logs go to stderr. Claude Desktop saves them to a local file (~/Library/Logs/Claude/mcp-server-Gramps Web MCP.log on macOS).

At Information, each Gramps API call is logged as its method, path (without the query string), status, duration, and body length; media downloads log the content type and length instead of the body length. Request and response bodies and full URLs hold genealogy data (names, dates, search terms), so they are logged only at Debug or Trace. Fields that look like credentials are redacted even then. Use Debug only while troubleshooting, and delete the log file afterwards.

Development

dotnet test

See CONTRIBUTING.md and the developer guide.

Documentation

DocumentDescription
docs indexAll documentation files
Tool catalogComplete MCP tool reference
Claude Desktop MCPBDesktop extension packaging
Privacy policyData handling for the desktop extension
System promptSuggested prompt for MCP clients
ArchitectureSystem design overview

Contributing

Contributions are welcome. See CONTRIBUTING.md.

Security

To report a vulnerability, see SECURITY.md.

Privacy Policy

The Claude Desktop extension is a local MCP server. It sends data only to the Gramps Web instance you configure and does not collect analytics or conversation data. See PRIVACY.md for full details.

License

Copyright (c) Scormave

This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later). Because this is network server software, hosting a modified version requires making the corresponding source available to users interacting with it over a network.

Bundled third-party components, such as ImageSharp, the MCP C# SDK, and the .NET runtime, keep their own Apache 2.0 or MIT licenses; see THIRD-PARTY-NOTICES.txt. The MCP Bundles and the Docker image ship that file next to LICENSE.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.