# Gramps MCP MCP Server (pypi · gramps-mcp-full)

MCP server for Gramps genealogy via the Gramps Web API: CRUD, search, merge, timelines, DNA.

- Trust score: 80/100 (high trust)
- Change this week: +16
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-02

## Components

- remote · `ghcr.io`: 25/100, [markdown](https://verifymcp.io/servers/oliverhruby-gramps-mcp/oliverhruby-gramps-mcp-latest.md), [page](https://verifymcp.io/servers/oliverhruby-gramps-mcp/oliverhruby-gramps-mcp-latest)
- pypi · `gramps-mcp-full`: 80/100 (this document), [markdown](https://verifymcp.io/servers/oliverhruby-gramps-mcp/gramps-mcp-full.md), [page](https://verifymcp.io/servers/oliverhruby-gramps-mcp/gramps-mcp-full)

## Channel facts

- Registry: `pypi`
- Package: `gramps-mcp-full`
- Version: `0.2.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-02.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs setuptools.build_meta at install time, a recognised build step with no custom scripting around it.
  - 0 of 28 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to oliverhruby/gramps-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 11 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 63/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 7830 tokens (~290/item across 27 items; 27 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 37/100
  - Stability observed for 11 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 67/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
- **Tool Safety**: 75/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - 0 of 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "merge_objects" implies "merge" and declares no destructiveHint at all, which the MCP spec reads as destructive by default.
  - An AI judge read all 27 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the Gramps MCP MCP Server server?

Gramps MCP MCP Server runs locally as a PyPI package, launched with uvx gramps-mcp-full. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add oliverhruby-gramps-mcp -- uvx gramps-mcp-full
```

### Cursor

```json
{
  "mcpServers": {
    "oliverhruby-gramps-mcp": {
      "command": "uvx",
      "args": [
        "gramps-mcp-full"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "oliverhruby-gramps-mcp": {
      "command": "uvx",
      "args": [
        "gramps-mcp-full"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add oliverhruby-gramps-mcp -- uvx gramps-mcp-full
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "oliverhruby-gramps-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "gramps-mcp-full"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add oliverhruby-gramps-mcp --command uvx --arg gramps-mcp-full
```

### Hermes

```yaml
mcp_servers:
  oliverhruby-gramps-mcp:
    command: "uvx"
    args: ["gramps-mcp-full"]
```

### Netclaw

```json
{
  "McpServers": {
    "oliverhruby-gramps-mcp": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "gramps-mcp-full"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add oliverhruby-gramps-mcp -t stdio -c uvx -a gramps-mcp-full
```

### Other

```json
{
  "mcpServers": {
    "oliverhruby-gramps-mcp": {
      "command": "uvx",
      "args": [
        "gramps-mcp-full"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-02 (score 80, +1)

No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-30 (score 79, +1)

No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-29 (score 78, +3)

- [functional improvement] Stability: unverified → 0.27

### 2026-09-28 (score 75, +11)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-09-25 (score 64, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-09-22 (score 64, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-09-21 (score 49)

First indexed and scored.

## MCP tools (27)

### `ping` (~37 tokens)

Health check. Read-only.

Args:
    (none)

Returns:
    dict: {"pong": true, "version": <server version>}.

### `get_instances` (~65 tokens)

List the configured target instances. Read-only.

Args:
    (none)

Returns:
    dict: {"instances": [<base url>, ...], "scope": "<value of
    GRAMPS_MCP_INSTANCES, or 'auto-discovery' when unset>"}.

### `manage_person` (~358 tokens)

Create, read, update or delete Gramps Person records. Writes: create, update, delete.

\`action=get` lists people (`handle` empty, paginated) or returns one person
(`handle` set, `?profile=&extend=` via `query`). `action=create` posts a
full Person JSON object in `data` (handles are assigned by the server).
\`action=update` PUTs `data` to /people/<handle>; `action=delete` removes it.
Person payload fields follow the Gramps schema (gramps_id, gender,
primary_name, names, event_ref_list, family_list, person_ref_list,
attribute_list, media_list, address_list, url_list, note_list, change, ...).

Args:
    action: The operation, "get", "create", "update" or "delete".
    handle: Person handle (e.g. 'P0001'); required for get-one, update, delete.
    data: The Person object for create/update (required for those).
    query: Optional dict of extra query-string parameters (e.g. {"page": 1,
        "pagesize": 20, "keys": "handle,name", "strip": true, "profile": "all",
        "extend": "all", "locale": "en"}).
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status": <http status>, "url": <api url>, "data": <object(s) | transaction>}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `handle` (string)
- `instance` (string)
- `query` (object)

### `manage_family` (~285 tokens)

Create, read, update or delete Gramps Family records. Writes: create, update, delete.

\`action=get` lists families (`handle` empty) or returns one family by
handle. `action=create` posts a full Family JSON object in `data`;
\`action=update` PUTs `data` to /families/<handle>; `action=delete` removes
it. Family payload fields: gramps_id, father_handle, mother_handle,
child_ref_list, event_ref_list, attribute_list, media_list, note_list,
change, relationship, ... . Creating a family rewrites its parents' and
children's person records, so it requires edit + add permissions upstream.

Args:
    action: The operation, "get", "create", "update" or "delete".
    handle: Family handle (e.g. 'F0001'); required for get-one, update, delete.
    data: The Family object for create/update (required for those).
    query: Optional dict of extra query-string parameters for reads.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data"}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `handle` (string)
- `instance` (string)
- `query` (object)

### `manage_event` (~258 tokens)

Create, read, update or delete Gramps Event records. Writes: create, update, delete.

\`action=get` lists events (`handle` empty) or returns one event by handle.
\`action=create` posts a full Event JSON object in `data`; `action=update`
PUTs `data` to /events/<handle>; `action=delete` removes it. Event payload
fields: gramps_id, type, date, description, place, citations, notes,
attribute_list, media_list, change, ... . Events are typically referenced
by Person/Family event_ref_list entries.

Args:
    action: The operation, "get", "create", "update" or "delete".
    handle: Event handle; required for get-one, update, delete.
    data: The Event object for create/update (required for those).
    query: Optional dict of extra query-string parameters for reads.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data"}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `handle` (string)
- `instance` (string)
- `query` (object)

### `manage_place` (~274 tokens)

Create, read, update or delete Gramps Place records. Writes: create, update, delete.

\`action=get` lists places (`handle` empty) or returns one place by handle.
\`action=create` posts a full Place JSON object in `data`; `action=update`
PUTs `data` to /places/<handle>; `action=delete` removes it. Place payload
fields: gramps_id, name, type, longitude, latitude, alt_names,
place_ref_list, enclosed_by, media_list, note_list, change, ... . Use
manage_place with a filter query instead of search when you need raw
object data rather than full-text hits.

Args:
    action: The operation, "get", "create", "update" or "delete".
    handle: Place handle; required for get-one, update, delete.
    data: The Place object for create/update (required for those).
    query: Optional dict of extra query-string parameters for reads.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data"}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `handle` (string)
- `instance` (string)
- `query` (object)

### `manage_source` (~260 tokens)

Create, read, update or delete Gramps Source records. Writes: create, update, delete.

\`action=get` lists sources (`handle` empty) or returns one source by
handle. `action=create` posts a full Source JSON object in `data`;
\`action=update` PUTs `data` to /sources/<handle>; `action=delete` removes
it. Source payload fields: gramps_id, title, author, pubinfo, abbrev,
reporef_list, media_list, note_list, change, ... . Citations of a source
are managed with manage_citation.

Args:
    action: The operation, "get", "create", "update" or "delete".
    handle: Source handle; required for get-one, update, delete.
    data: The Source object for create/update (required for those).
    query: Optional dict of extra query-string parameters for reads.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data"}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `handle` (string)
- `instance` (string)
- `query` (object)

### `manage_citation` (~264 tokens)

Create, read, update or delete Gramps Citation records. Writes: create, update, delete.

\`action=get` lists citations (`handle` empty) or returns one citation by
handle. `action=create` posts a full Citation JSON object in `data`;
\`action=update` PUTs `data` to /citations/<handle>; `action=delete` removes
it. Citation payload fields: gramps_id, source_handle, date, page,
confidence, note_list, media_list, change, ... . Attach a citation to a
Person/Family/Event by adding its handle to that object's citation_list.

Args:
    action: The operation, "get", "create", "update" or "delete".
    handle: Citation handle; required for get-one, update, delete.
    data: The Citation object for create/update (required for those).
    query: Optional dict of extra query-string parameters for reads.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data"}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `handle` (string)
- `instance` (string)
- `query` (object)

### `manage_note` (~262 tokens)

Create, read, update or delete Gramps Note records. Writes: create, update, delete.

\`action=get` lists notes (`handle` empty) or returns one note by handle.
\`action=create` posts a full Note JSON object in `data`; `action=update`
PUTs `data` to /notes/<handle>; `action=delete` removes it. Note payload
fields: gramps_id, type, text, format, note_list, change, ... . Notes are
referenced by other objects' note_list fields; DNA match segment strings
live in notes (see analyze_dna).

Args:
    action: The operation, "get", "create", "update" or "delete".
    handle: Note handle; required for get-one, update, delete.
    data: The Note object for create/update (required for those).
    query: Optional dict of extra query-string parameters for reads.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data"}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `handle` (string)
- `instance` (string)
- `query` (object)

### `manage_media` (~479 tokens)

Manage Gramps Media objects and their files. Writes: create, update, delete, upload.

Standard CRUD via /media/ plus binary operations:
  get/create/update/delete  -> as in manage_person (GET/POST/PUT/DELETE).
  upload                    -> POST /media/ streaming `file_path` bytes with
                               `mime_type` (required); the API computes the
                               checksum and creates the Media row.
  file                      -> GET /media/<handle>/file; returns base64 bytes.
  thumbnail                 -> GET /media/<handle>/thumbnail/<size>; returns
                               base64 image; pass {"square": true} in `query`.
  ocr                       -> GET /media/<handle>/ocr; returns OCR text.
  face_detection            -> GET /media/<handle>/face_detection; returns
                               detected/test faces (see upstream for params).
Repeat `action` for repeated sub-actions; 'create' accepts a Media JSON body
in `data` (needs an already-uploaded file), while 'upload' bulk-loads a
local file. Consider merge_objects for duplicate media.

Args:
    action: "get", "create", "update", "delete", "upload", "file",
        "thumbnail", "ocr" or "face_detection".
    handle: Media handle; required for get-one, update, delete, file,
        thumbnail, ocr, face_detection.
    data: The Media object for create/update (required for those).
    query: Optional dict of extra query-string parameters (e.g. {"square": true}).
    file_path: Local file path for the 'upload' action (required there).
    mime_type: MIME type of the upload (e.g. 'image/jpeg'); required for 'upload'.
    size: Thumbnail target size in pixels (required for 'thumbnail').
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data"} where binary results carry base64/mimetype.

Input parameters:

- `action` (string, required)
- `data` (object)
- `file_path` (string)
- `handle` (string)
- `instance` (string)
- `mime_type` (string)
- `query` (object)
- `size` (integer)

### `manage_repository` (~251 tokens)

Create, read, update or delete Gramps Repository records. Writes: create, update, delete.

\`action=get` lists repositories (`handle` empty) or returns one by handle.
\`action=create` posts a full Repository JSON object in `data`;
\`action=update` PUTs `data` to /repositories/<handle>; `action=delete`
removes it. Repository payload fields: gramps_id, type, name, address_list,
url_list, note_list, change, ... . Sources link to a repository through
their reporef_list entry.

Args:
    action: The operation, "get", "create", "update" or "delete".
    handle: Repository handle; required for get-one, update, delete.
    data: The Repository object for create/update (required for those).
    query: Optional dict of extra query-string parameters for reads.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data"}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `handle` (string)
- `instance` (string)
- `query` (object)

### `manage_tag` (~246 tokens)

Create, read, update or delete Gramps Tag records. Writes: create, update, delete.

Tags are lightweight labels attachable to any object. `action=get` lists
tags (`handle` empty) or returns one by handle; `action=create` posts a Tag
JSON object (`name` required) in `data`; `action=update` PUTs `data` to
/tags/<handle>; `action=delete` removes it. To tag an object, reference the
tag handle in that object's `tag_list`.

Args:
    action: The operation, "get", "create", "update" or "delete".
    handle: Tag handle; required for get-one, update, delete.
    data: The Tag object for create/update (required for those).
    query: Optional dict of extra query-string parameters for reads.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data"}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `handle` (string)
- `instance` (string)
- `query` (object)

### `search` (~383 tokens)

Full-text (or semantic) search across the Gramps tree. Read-only.

Hits the search index: type-ahead style queries for people, families,
events, places, sources, citations, repositories, media and notes. `type`
is a comma-delimited allowlist of object types; `query` is required. Use
\`manage_<type>` with a get/filter instead when you already know the handle
or want raw object data.

Args:
    query: The search string (required).
    type: Comma-delimited object types to include, e.g. "person,family,source".
    page: 1-based result page.
    pagesize: Results per page (default 20).
    sort: Comma-delimited sort keys; "change" or "type", '-' prefix for
        descending (e.g. "-change").
    profile: Comma-delimited profile sections: all,self,age,span,events,
        families,references.
    strip: If true, drop empty-valued keys from hits.
    semantic: If true, use the vector/semantic index instead of full text.
    change: ISO-8601 last-change filter, prefix with '>' or '<'.
    locale: Language code for localized profile output.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": [hits], "total": <match count>}.

Input parameters:

- `change` (string)
- `instance` (string)
- `locale` (string)
- `page` (integer)
- `pagesize` (integer)
- `profile` (string)
- `query` (string, required)
- `semantic` (boolean)
- `sort` (string)
- `strip` (boolean)
- `type` (string)

### `merge_objects` (~275 tokens)

Merge two Gramps objects of the same type into one. Writes: merge.

\`handle1` (the "phoenix") survives; `handle2` (the "titanic") is absorbed
and deleted. Supported obj_type values: person, family, event, place,
source, citation, repository, media, note. Person merges accept
{"family_merger": bool} in `data`; family merges accept
{"phoenix_father_handle", "phoenix_mother_handle"}. Requires edit+delete
permissions upstream. For duplicate handling of other object types, use
manage_* to probe first, then merge_objects to combine.

Args:
    obj_type: Object type to merge, e.g. "person" or "family".
    handle1: Handle that survives the merge (phoenix).
    handle2: Handle that is absorbed and deleted (titanic).
    data: Optional merge options dict (person/family specific).
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": {}} on success.

Input parameters:

- `data` (object)
- `handle1` (string, required)
- `handle2` (string, required)
- `instance` (string)
- `obj_type` (string, required)

### `get_timeline` (~470 tokens)

Chronological event timeline for a person, family, or the whole tree. Read-only.

\`kind=person` -> /people/<handle>/timeline; `kind=family` ->
/families/<handle>/timeline; `kind=people` and `kind=families` return
tree-wide timelines (no handle). Events can be grouped into generations
(`ancestors`/`offspring`), filtered by event class (`event_classes` via
\`query`), and paged (`page`/`pagesize`).

Args:
    kind: "person", "family", "people" or "families".
    handle: Person/family handle; required for kinds 'person' and 'family'.
    page: 1-based page of the event list.
    pagesize: Events per page.
    strip: If true, drop empty-valued keys from returned objects.
    discard_empty: If true, omit placeholder slot rows.
    omit_anchor: If true, exclude the anchor object's own event row.
    ratings: If true, include per-event relevance ratings.
    keys: Comma-delimited subset of object keys to return.
    skipkeys: Comma-delimited keys to exclude.
    precision: Significant time components (1-3) for age/span strings.
    ancestors: Number of ancestor generations to include (person kind).
    offspring: Number of descendant generations to include (person kind).
    query: Optional dict of extra timeline params (event_classes, events,
        relative_events, relatives, first, last, handles, ...).
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": [timeline rows]}.

Input parameters:

- `ancestors` (integer)
- `discard_empty` (boolean)
- `handle` (string)
- `instance` (string)
- `keys` (string)
- `kind` (string, required)
- `offspring` (integer)
- `omit_anchor` (boolean)
- `page` (integer)
- `pagesize` (integer)
- `precision` (integer)
- `query` (object)
- `ratings` (boolean)
- `skipkeys` (string)
- `strip` (boolean)

### `get_relation` (~210 tokens)

Compute a genealogical relationship between two people. Read-only.

Without `all`, returns the shortest/most direct relationship (relationship
string plus distances). With `all=true`, lists every possible relationship,
including common ancestors per path. Uses /relations/<h1>/<h2> or
/relations/<h1>/<h2>/all with an optional `depth` cap on generations.

Args:
    handle1: First person handle.
    handle2: Second person handle.
    all: If true, return all possible relationships (and ancestors).
    depth: Maximum generations to search for a common ancestor (default 15,
        minimum 2).
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": relationship(s)}.

Input parameters:

- `all` (boolean)
- `depth` (integer)
- `handle1` (string, required)
- `handle2` (string, required)
- `instance` (string)

### `get_living` (~250 tokens)

Estimate whether (or until when) a person is alive. Read-only.

\`mode=status` returns {"living": bool} from /living/<handle>;
\`mode=dates` returns probable birth/death date estimates plus an
explanation from /living/<handle>/dates. Tune the heuristic with the
three optional integer parameters (upstream defaults: 20 / 110 / 20).

Args:
    handle: Person handle.
    mode: "status" (default) or "dates".
    average_generation_gap: Average years between generations (>= 1).
    max_age_probably_alive: Max age in years still considered alive (>= 1).
    max_sibling_age_difference: Max sibling age gap tolerated (>= 1).
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": <living verdict or date estimates>}.

Input parameters:

- `average_generation_gap` (integer)
- `handle` (string, required)
- `instance` (string)
- `max_age_probably_alive` (integer)
- `max_sibling_age_difference` (integer)
- `mode` (string)

### `analyze_dna` (~282 tokens)

DNA match analysis and raw match-string parsing. Writes: parse only.

Actions:
  matches -> GET /people/<handle>/dna/matches; per-match relationship,
             segments, common-ancestor profiles and citation-linked notes.
  ydna    -> GET /people/<handle>/ydna; Y-DNA haplogroup clade lineage.
  parse   -> POST /parsers/dna-match with `data` = the raw DNA match text
             (e.g. 23andMe/Ancestry segment blocks); returns parsed segments.
\`matches` accepts `raw=true` to include the raw segment strings. Matches
are stored as "DNA" associations plus notes; see manage_person/manage_note.

Args:
    action: "matches", "ydna" or "parse".
    handle: Person handle; required for matches and ydna.
    data: Raw DNA match string; required for parse.
    raw: If true, include raw segment strings in matches output.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": matches, clade or parsed segments}.

Input parameters:

- `action` (string, required)
- `data` (string)
- `handle` (string)
- `instance` (string)
- `raw` (boolean)

### `manage_import` (~330 tokens)

List importers or import a family tree file (Gramps XML, GEDCOM...). Writes: file, restore.

\`action=list` returns every available importer (GET /importers/);
\`action=info` describes one importer (GET /importers/<extension>);
\`action=file` uploads `file_path` to /importers/<extension>/file (raw body,
extension picks the importer) and returns the import counts;
\`action=restore` resets the tree to match an uploaded Gramps backup via
/importers/<extension>/file/restore (replaces all content; requires batch
delete permission). Use `dry_run=true` on file/restore to preview counts and
changes without touching the tree. Extensions: gramps, gpkg, ged, gedcom,
csv, etc., depending on installed plugins.

Args:
    action: "list", "info", "file" or "restore".
    extension: Importer extension (e.g. 'gramps' or 'ged'); required for
        info, file, restore.
    file_path: Local path of the file to upload (required for file/restore).
    dry_run: If true, compute counts/summary without importing (file/restore).
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": importer list or import summary}.

Input parameters:

- `action` (string, required)
- `dry_run` (boolean)
- `extension` (string)
- `file_path` (string)
- `instance` (string)

### `manage_export` (~362 tokens)

List exporters or produce an export file (GEDCOM, Gramps XML...). Writes: run.

\`action=list` returns every available exporter (GET /exporters/);
\`action=info` describes one exporter (GET /exporters/<extension>);
\`action=run` starts an asynchronous export (POST /exporters/<extension>/file)
and returns a task reference (poll with manage_transaction or re-call to
fetch); `action=file` runs a synchronous export (GET /exporters/<extension>/file)
and returns the file as base64. Exports run on the whole tree unless
filtered; pass `options` as a dict of query params: compress, living
(IncludeAll/FullNameOnly/LastNameOnly/ReplaceCompleteName/ExcludeAll),
private, person, event, note, reference, sequence, handle, gramps_id,
years_after_death, current_year, locale, include_individuals,
include_children, include_marriages, include_places, include_media,
include_witnesses, translate_headers. Extensions: ged, gramps, gw, csv, etc.

Args:
    action: "list", "info", "run" or "file".
    extension: Exporter extension (e.g. 'ged' or 'gramps'); required for
        info, run, file.
    options: Dict of export option query parameters (see docstring).
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": exporter list, task ref, or base64 file}.

Input parameters:

- `action` (string, required)
- `extension` (string)
- `instance` (string)
- `options` (object)

### `manage_report` (~352 tokens)

List, configure or generate Gramps reports (PDF, text, web...). Writes: run.

\`action=list` returns all available reports (GET /reports/);
\`action=info` describes one report and its options (GET /reports/<id>);
\`action=run` generates a report in the background
(POST /reports/<id>/file?options=<json>) returning a task reference;
\`action=file` generates it synchronously (GET /reports/<id>/file) and
returns the produced file as base64; `action=result` downloads a
previously generated file by `filename` (pass via `options` or a separate
call: GET /reports/<id>/file/processed/<filename>). Report options are a
JSON dict documented by each report's options_help (see action=info).

Args:
    action: "list", "info", "run", "file" or "result".
    report_id: Report id (e.g. 'descend_report'); required for info, run,
        file, result.
    options: Dict of report options (JSON-serialized into the options param).
    locale: Language code for report output (default server locale).
    include_help: If true, include the options-help dictionary in list/info.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": reports, task ref, or base64 file}.

Input parameters:

- `action` (string, required)
- `include_help` (boolean)
- `instance` (string)
- `locale` (string)
- `options` (object)
- `report_id` (string)

### `manage_transaction` (~496 tokens)

Apply raw DB transactions, undo history, or bulk create/delete. Writes: all actions.

Low-level database operations that the object endpoints cannot express:
  apply            -> POST /transactions/ replaying `payload` (a raw
                      transaction dict of {add, update, delete} operations).
  undo             -> POST /transactions/?undo=1 applying the inverse of
                      `payload`; pass a recent transaction to revert it.
  history          -> GET /transactions/history/ (list of past transactions).
  history_id       -> GET /transactions/history/<transaction_id>.
  undo_history     -> POST /transactions/history/<transaction_id>/undo.
  create_objects   -> POST /objects/ with `payload` = list of object dicts
                      (validated and added together in one transaction).
  delete_objects   -> POST /objects/delete/?namespaces=<csv> batches an
                      async delete of whole object types (e.g. 'people,notes').
  delete_by_handle -> POST /objects/delete-by-handle/ with `namespace` (e.g.
                      'people') and `handles` (list) to delete specific objects.
\`params` forwards query args for apply/undo: undo, message, force, background.
Prefer the typed manage_* tools for single-record work; raw apply skips
cross-reference maintenance and can corrupt a tree if malformed.

Args:
    action: "apply", "undo", "history", "history_id", "undo_history",
        "create_objects", "delete_objects" or "delete_by_handle".
    payload: Transaction dict (apply/undo) or list of objects (create_objects).
    params: Optional dict for apply/undo (undo, message, force, background).
    transaction_id: History transaction id; required for history_id, undo_history.
    namespace: Object plural namespace (e.g. 'people'); for delete_objects /
        delete_by_handle.
    handles: List of handles to delete; for delete_by_handle.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "d…

Input parameters:

- `action` (string, required)
- `handles` (array)
- `instance` (string)
- `namespace` (string)
- `params` (object)
- `payload` (object)
- `transaction_id` (integer)

### `manage_user` (~270 tokens)

Administer Gramps Web users. Writes: create, update, delete, change_password.

\`action=list` lists users (GET /users/); `action=get` returns one user by
name; `action=create` POSTs `data` (full_name, email, password, role and
tree required by the API) to /users/; `action=update` PUTs `data` (role,
email, full_name, name_new, tree) to /users/<user_name>/; `action=delete`
removes the user; `action=change_password` POSTs with data = {"old_password",
"new_password"}. Requires owner/admin permissions upstream for most actions.

Args:
    action: "list", "get", "create", "update", "delete" or "change_password".
    user_name: The user's name; required for get/update/delete/change_password.
    data: Body dict; required for create/update/change_password.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": user list/object or empty}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `instance` (string)
- `user_name` (string)

### `manage_tree` (~338 tokens)

Inspect or administer Gramps Web family trees. Writes: create, update, disable, enable, repair, migrate, verify, config_set.

\`action=list` lists trees (GET /trees/); `action=get` inspects one tree
(tree_id '-' means the current tree); `action=create` adds a tree
(data = {"name": <required>, "quota_media", "quota_people", "min_role_ai"});
\`action=update` renames/rescales a tree; `action=disable`/`action=enable`
toggle login for a tree; `action=repair` checks/repairs its database;
\`action=migrate` upgrades its schema; `action=verify` runs integrity
checks; `action=config_get`/`action=config_set` read or write tree
configuration. Admin-only upstream. Note: this API version has no tree
delete endpoint (delete trees via the server CLI).

Args:
    action: "list", "get", "create", "update", "disable", "enable",
        "repair", "migrate", "verify", "config_get" or "config_set".
    tree_id: Tree id; required except for list/create; '-' = current tree.
    data: Body dict for create/update/config_set (create requires 'name').
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": tree details or configuration}.

Input parameters:

- `action` (string, required)
- `data` (object)
- `instance` (string)
- `tree_id` (string)

### `manage_bookmark` (~250 tokens)

Read or edit bookmarks per object namespace. Writes: add, remove.

Bookmarks are per-user, per-type handle shortcuts. `namespace` is one of:
citations, events, families, media, notes, people, places, repositories,
sources. `action=list_all` returns every namespace's bookmarks
(GET /bookmarks/); `action=list` returns one namespace (GET /bookmarks/<ns>);
\`action=add` bookmarks a handle (PUT /bookmarks/<ns>/<handle>, idempotent);
\`action=remove` unbookmarks it (DELETE). Adding validates that the object
exists.

Args:
    namespace: Bookmark namespace (one of the nine object plurals).
    action: "list_all", "list", "add" or "remove" (default "list").
    handle: Object handle to bookmark/unbookmark; required for add/remove.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": bookmark list or empty}.

Input parameters:

- `action` (string)
- `handle` (string)
- `instance` (string)
- `namespace` (string, required)

### `manage_type` (~346 tokens)

List Gramps type vocabularies (custom + default) for all object types. Read-only.

Enumerates the controlled vocabularies used across the schema, e.g. event
types, name types, place types, child reference types, gender types.
\`action=all` merges default and custom types (GET /types/); `action=defaults`
lists every default vocabulary; `action=default` returns one vocabulary
(e.g. 'event_types'); `action=default_map` returns its machine-readable
mapping (standard key -> localized string); `action=customs` lists every
custom vocabulary; `action=custom` returns one. Datatypes include:
event_types, event_role_types, name_types, name_origin_types, place_types,
note_types, repository_types, source_attribute_types, source_media_types,
url_types, attribute_types, family_relation_types, child_reference_types,
gender_types (+ person/family/media/event attribute_types on custom).
Values are the strings Gramps objects use in their `type` fields.

Args:
    action: "all", "defaults", "default", "default_map", "customs" or "custom".
    datatype: Vocabulary name (e.g. 'event_types'); required for default,
        default_map, custom.
    locale: If true, translate default type names to the server locale.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": vocabulary dict or list}.

Input parameters:

- `action` (string)
- `datatype` (string)
- `instance` (string)
- `locale` (boolean)

### `get_server_info` (~177 tokens)

Read Gramps Web server, database, locale and object-count metadata. Read-only.

Wraps GET /metadata/: database id/name/type, Gramps + Gramps Web API + QL
versions, locale, per-type object counts, tree researcher info, search
index details, and server capabilities (multi-tree, task queue, OCR,
semantic search, chat, face detection, thumbnails). When `surnames` is
true, the response additionally lists every surname in the database.

Args:
    surnames: If true, include the full list of surnames in the database.
    instance: Gramps Web base URL from get_instances; default = first.

Returns:
    dict: {"status", "url", "data": metadata object}.

Input parameters:

- `instance` (string)
- `surnames` (boolean)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/oliverhruby-gramps-mcp/gramps-mcp-full#diagnostics

## Score history

- 2026-10-02: 80
- 2026-10-01: 79
- 2026-09-30: 79
- 2026-09-29: 78
- 2026-09-28: 75
- 2026-09-27: 64
- 2026-09-26: 64
- 2026-09-25: 64
- 2026-09-24: 64
- 2026-09-23: 64
- 2026-09-22: 64
- 2026-09-21: 49

## Common questions

### What is the Gramps MCP MCP Server server?

Gramps MCP MCP Server is listed in the public MCP registry as io.github.oliverhruby/gramps-mcp. MCP server for Gramps genealogy via the Gramps Web API: CRUD, search, merge, timelines, DNA. This page covers its PyPI package (gramps-mcp-full).

### Is the Gramps MCP MCP Server server safe to use?

Gramps MCP MCP Server scores 80 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 2 October 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Gramps MCP MCP Server server expose?

Gramps MCP MCP Server exposes 27 tools: ping, get_instances, manage_person, manage_family, manage_event, and 22 more. Their descriptions and schemas cost roughly 7,830 tokens of context every time the server is loaded.

### Is the Gramps MCP MCP Server server still maintained?

Gramps MCP MCP Server is still listed as active in the MCP registry. We last reached this channel on 2 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Gramps MCP MCP Server server under?

Gramps MCP MCP Server declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/gramps-mcp-full/
- Socket report: https://socket.dev/pypi/package/gramps-mcp-full
- Repository: https://github.com/oliverhruby/gramps-mcp
- Changelog RSS feed: https://verifymcp.io/servers/oliverhruby-gramps-mcp/gramps-mcp-full.xml
- Changelog JSON feed: https://verifymcp.io/servers/oliverhruby-gramps-mcp/gramps-mcp-full.json
- HTML version of this page: https://verifymcp.io/servers/oliverhruby-gramps-mcp/gramps-mcp-full
