Skip to main content
Glama
ianderso
by ianderso

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
GRAMPS_MCP_HOSTNoHost for http transport to listen on (default 127.0.0.1)
GRAMPS_MCP_PORTNoPort for http transport to listen on (default 8090)
GRAMPS_MCP_CONFIGNoPath to the TOML config (default ./gramps_mcp.toml, from the working directory)
GRAMPS_MCP_API_URLYesBase URL of gramps-webapi, e.g. http://gramps.example.org:5000
GRAMPS_MCP_PASSWORDYesIts password
GRAMPS_MCP_USERNAMEYesThe dedicated MCP user
GRAMPS_MCP_TRANSPORTNoTransport to use: stdio (default) or http
GRAMPS_MCP_EXPOSE_PRIVATENoOverride the TOML expose_private flag (default false)

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
add_personA

Create a new person, optionally with cited birth and/or death events.

Use this to add someone to the tree. Good practice: attach the birth event with a citation to the specific record that proves it (a birth or baptism certificate, a census entry), setting the citation's confidence honestly. If you only have a legacy-tree hint with no underlying record, either omit the event or set require_citation=False so it's flagged for follow-up.

Returns the new person's handle and gramps_id.

add_event_to_personA

Add a dated/placed event (fact) to an existing person.

Use for facts beyond birth/death: residence, occupation, census, baptism, immigration, marriage-adjacent events, etc. The event's citation should point at the record establishing the fact. Adding a 'Birth'/'Death' event will set the person's primary birth/death reference if not already set.

add_familyA

Create a family linking parents and children, with an optional cited marriage.

All members must already exist (create them first with add_person). Creating the family automatically links each person's family/parent-family lists, so you don't need to update the individuals separately. Cite the marriage event to a marriage record where possible.

add_sourceA

Create a Source (a body of evidence: a record set, book, certificate, website).

In the Gramps evidence model a Source is what you cite through a Citation. Create the source once, then create citations against it for each fact it supports. Optionally link it to a Repository (where the source is held).

add_citationA

Create a standalone Citation on a Source (or reuse an existing one).

Usually you don't call this directly -- pass a CitationInput to add_person / add_event_to_person / add_family instead, which creates the citation and attaches it to the fact in one step. Use this when you want a reusable citation handle to attach to several facts.

add_repositoryA

Create a Repository (an institution or place that holds sources).

Repositories sit at the top of the evidence model: Repository -> Source -> Citation -> fact. Create these for archives, libraries, cemeteries, or websites you'll cite sources from.

add_noteA

Create a research/general note, optionally attached to an object.

Use notes for research logs, reasoning about conflicting evidence, or transcriptions. Attach to a person/event/source by giving target + target_type.

attach_mediaA

Attach an image or document to an object -- a new upload, or one already in the tree.

With file_path, the bytes are uploaded into the tree's managed media directory (so don't point at files you don't want copied); if that exact file is already present it is reused rather than duplicated. With media_ref, an existing Media object is linked.

One image should be ONE Media object, linked from each object it belongs to and cited once per fact it proves. Uploading the same photograph separately for the husband and the wife creates duplicates that have to be unpicked later. The write is verified afterwards: verified: false means nothing attached, whatever the rest of the result says.

cite_eventA

Attach a citation to an event that ALREADY exists.

Use this to source an event you didn't create with an inline citation -- e.g. one added through the Gramps web UI, or an unsourced event surfaced by list_unsourced_facts. The citation is resolved/created (existing handle/id, or an inline source_title + page + confidence) and appended to the event's citation list (no duplicates). Does not change any other event field.

update_eventA

Edit an existing event's date, place, and/or description.

Only the fields you provide are changed; the rest are left as-is. This does NOT change the event's citations -- use cite_event to add a source.

delete_objectA

Permanently delete an object from the tree by handle or gramps_id.

DESTRUCTIVE and irreversible. Deleting an object does not clean up references to it, so this can leave dangling references (e.g. deleting a person still referenced by a family, or an event still listed on a person). Prefer deleting leaf objects, and detach references first where possible.

tag_objectA

Attach a named Tag to an object, creating the Tag if it doesn't exist yet.

Tags are lightweight cross-cutting labels ('Verified', 'Needs review', 'DNA-confirmed'). Matching is by exact name; an existing tag is reused.

add_attributeA

Add a typed key/value attribute to an object.

Sources and citations use a SrcAttribute; everything else uses an Attribute. The right class is chosen automatically from object_type.

add_urlA

Add a web URL to a person, place, or repository.

Only these three object types carry a URL list. For sources/citations, record a web address as an attribute (add_attribute) instead.

update_urlA

Edit or remove ONE existing URL entry on a person, place, or repository.

add_url can only append -- this corrects an entry already there (the classic case: a Find a Grave link filed under the wrong type). The other fields on the object are untouched.

set_privateA

Set (or clear) the Gramps private flag on an object.

Private records are withheld from bulk output (queries, searches, tree walks, timelines, reports) unless a call passes include_private.

update_sourceB

Edit an existing source's title, author, publication info, and/or abbreviation.

Only the fields you provide are changed; the rest are left as-is.

link_repositoryA

Link an existing source to an existing repository that holds it.

Adds a repository reference (with an optional call number) to the source. Both objects must already exist. Duplicate links to the same repository are skipped.

add_event_to_familyA

Add a dated/placed event (fact) to an existing family.

Use for family-level facts: marriage, divorce, residence, census. The event is added with the 'Family' role. Cite it to the record establishing the fact.

add_child_to_familyA

Add an existing person as a child of an existing family.

Links the child both ways: a ChildRef is added to the family and the family is added to the child's parent-family list. The child must already exist. Duplicate children are skipped.

add_alternate_nameA

Add an alternate (non-primary) name to a person.

Use for maiden/married names, aliases, anglicized forms, or nicknames-of-record. The person's primary name is left unchanged.

get_personA

Get full detail for one person: name, gender, events (with citation counts), family links, and media count.

Direct lookup is allowed even for living/private individuals (this is your own local tool); only bulk/list tools filter them. Use this to inspect someone before adding facts, or to check whether an event is already cited.

search_peopleA

Search people by name substring and optional birth-year range.

Bulk output: probably-living people (born < 110 years ago with no recorded death) and records marked private are returned as redacted stubs (ids only) unless include_private is set. Fetch a specific person by id with get_person if you need their detail.

get_familyA

Get a family: relationship type, parent handles, child handles, event count.

get_ancestorsA

Walk a person's ancestors up to N generations (a nested parents tree).

Living/private ancestors appear as redacted stubs unless include_private is set.

get_descendantsA

Walk a person's descendants up to N generations (a nested children tree).

Living/private descendants appear as redacted stubs unless include_private is set.

list_unsourced_factsA

Audit: list events that lack a citation or are tagged UNSOURCED.

This is the core quality query for a fully-cited tree -- run it to find facts that still need a source. Returns each offending event with its person, type, date, and the reason ('no-citation' or 'tagged-unsourced').

db_statsA

Counts of people, families, events, citations, sources, repositories, places, media, and notes in the tree. A quick health/overview check.

list_tagsA

List all tags in the tree with their handle, name, and color.

Use to see what labels already exist before tagging (tag_object matches by exact name).

get_sourceA

Get a source: title, author, publication info, abbreviation, linked repositories, media/note counts, attributes, and citation count.

Use to inspect a source before citing through it or editing it.

get_repositoryB

Get a repository: name, type, URLs, address count, and (if available) the number of sources it holds.

get_eventA

Get an event: type, date, place handle, description, citation count, and attributes. Use to inspect an event before citing or editing it.

query_objectsA

Query any collection with a server-side filter. The workhorse for audits.

Use this instead of fetching a collection and filtering it yourself: whole-collection pulls are slow on any real tree, and the filter runs in the database. Typical audit questions it answers directly:

  • uncited high-confidence claims: citations where confidence >= 3 AND page = ""

  • documents with no image: sources where media_list.length = 0

  • anonymous media: media where desc = ""

To ask "what cites this source?" use get_backlinks -- a source has no citation_list, because citations point at IT, and reading citation_list on a source reports zero for every source in the tree.

Private records and living people come back as redacted stubs.

get_backlinksA

List everything that references this object, grouped by type.

The right way to ask "is this source actually cited?", "which facts rest on this citation?", or "is it safe to delete this?" -- an object with zero backlinks is orphaned; one with backlinks will leave dangling references if deleted.

find_duplicatesA

Find likely-duplicate objects. Reports only -- it never merges anything.

Duplicates are not merely untidy: a duplicate SOURCE makes a single-sourced fact look corroborated, which is a false evidentiary claim. But the reverse error is just as real -- an index entry and the register page it indexes are TWO documents and must stay separate. This tool finds candidates; deciding which are truly the same document is yours. Merge with merge_objects.

list_object_typesA

The tree's type vocabularies (event types, attribute types, and so on).

Check an unfamiliar type string here first: Gramps accepts an unrecognised one as a NEW custom type rather than rejecting it, so a typo permanently enters the tree's vocabulary.

get_objectA

Read any object's raw record -- including places, media, notes and citations, which have no shaped getter.

Returns the record as stored, which is what you want before editing one. For people and sources the shaped getters (get_person, get_source) are easier to read.

update_citationA

Edit a citation's locator, confidence, date, or the source it points at.

A page-less citation on a long document is not a locator, and a confidence is a per-instance judgement, not a property of the source class.

IMPORTANT: a citation carries ONE confidence, and it belongs to ONE claim. Every fact attached to this citation shares whatever you set here. If the same page supports a second, different claim (a census page proving both "this child appears here" and "these are her parents"), make a SECOND citation on the same source and page -- do not re-grade this one.

update_mediaB

Edit a media object's description, date, or path.

update_personA

Edit a person's gender, primary name, or privacy flag.

Replacing the primary name preserves the old one as an 'Also Known As': a name in the tree came from some record, and dropping it loses the link to whatever document used it. To add a name without replacing the primary one, use add_alternate_name.

update_object_fieldsA

Set scalar fields on any object -- the escape hatch for places, notes, repositories and the rest.

Only scalar fields are settable. Structural lists (citation_list, event_ref_list, media_list, ...) are refused on purpose: replacing one wholesale is exactly how references get silently dropped. Each has its own tool -- cite_object, detach_object, tag_object, attach_media.

update_placeA

Edit a place's type, parent enclosure, name, title, or coordinates.

This is the tool update_object_fields deliberately refuses to be: place_type and the enclosure are structural, so they get guard rails here -- the parent must already exist, setting it cannot create an enclosure cycle, and a place holding several dated enclosures (a territory-to-state succession) is refused rather than silently flattened. Aim for every place typed, every non-country place parented, and street addresses on events rather than in the place tree.

cite_objectA

Attach a citation to any object that carries one -- not just events.

cite_event covers facts; this covers the rest. The important case is the FAMILY, whose citation supports a claim no event makes: that these two people were a couple. Person-level citations are for evidence about the individual as a whole (an identity document) rather than about one dated fact -- prefer citing the specific event where one exists.

To cite a parent-child link, use cite_child_link: that is a different claim and needs its own citation.

cite_child_linkA

Cite the parent-child link itself, on the family's ChildRef.

"This child belongs to these parents" is a DIFFERENT claim from "this child appears in this record", and it needs its own citation object. Reusing the child's existing citation handle makes the link inherit a confidence that was assigned to another claim entirely, so the link displays a confidence its evidence never earned.

Note what a ChildRef citation asserts: BOTH sides of the link. A census naming only the mother does not document the father. Where only one parent is evidenced, cite that parent's relationship instead of implying both.

unciteA

Detach a citation from an object, deleting it if it is left orphaned.

Detaching without deleting is how orphan citations accumulate: the fact the citation supported is gone, but the citation sits in the database still looking like evidence of something. Use this when a citation was attached to the wrong fact, or when a superseded bucket citation is replaced by the real record.

merge_objectsA

Merge two objects that are the same thing. Dry-run by default.

This uses Gramps' own server-side merge: every reference to drop is re-pointed at keep and the subordinate lists are unioned, in one transaction. Do NOT do this by hand: a manual merge that misses one of the lists the dropped object carries loses what was on it.

Before merging, be sure they really are one thing. Two records OF the same event are two documents: an index entry and the register page it indexes stay separate, and merging them would turn two independent citations into one, silently weakening every fact that rested on both. Conversely, the same census page entered once per household member IS one document, and leaving the duplicates makes single-sourced facts look corroborated.

Reversible: the merge is one transaction, so list_transactions + undo_transaction can back it out.

detach_objectA

Remove a reference from an object: an event from a person, an image from a source, a tag, a note, a child from a family.

The reference is removed; the object itself survives unless delete_if_orphan is set AND nothing else points at it -- which is checked, because deleting something other facts still reference leaves dangling handles behind.

add_mediaA

Upload a document as a standalone Media object, reusing an identical file already in the tree.

One image, one Media object -- then attach it wherever it belongs with attach_media(media_ref=...) and cite it once per fact it proves. Uploading the same photograph once per person it depicts is the duplicate pattern that later has to be unpicked by hand.

ocr_mediaA

Run OCR on a document image, server-side, to locate text within it.

A finding aid, not evidence. OCR output is a machine's guess at the writing, and it is at its worst on exactly the handwritten records that matter most. Use it to find WHERE something appears in a long scan; read the image before citing what it says.

export_backupA

Write a full-tree export to disk. Take one before any bulk write.

Cheap insurance: a few seconds and one file. A bulk write that goes wrong cannot always be undone transaction by transaction; a dump can be re-imported.

list_transactionsA

Recent writes to the tree: what changed, when, by which user.

Each entry's transaction_id is what undo_transaction takes. Useful for "what did that bulk pass actually do?" and for finding the transaction to reverse when it did the wrong thing.

undo_transactionA

Undo a past transaction, after checking whether it can be undone cleanly.

A conflict means an object was edited again after this transaction; undoing anyway throws that later edit away. The conflict check is free and runs first, so the default tells you what you are dealing with before anything changes.

list_reportsA

List the reports this Gramps instance can generate.

Gramps ships a full report engine — Ahnentafel, descendant reports, family group sheets, kinship, fan and relationship charts, statistics, and an end-of-line report that lists exactly where research stops. Each entry names the option keys it accepts; read the defaults with get_report_options before overriding any.

get_report_optionsA

Read one report's default options before running it.

Reports take a full option dict, not a partial one, so the way to change a single setting is to read these defaults and override that key.

run_reportA

Generate a report and return the file it produced.

Living people and private records are left out (living_people 0, incl_private false) unless you pass those options or include_private; Gramps' own default includes both.

Usually runs in the background, returning a task_id to poll with get_task.

list_filter_rulesA

List the filter rules Gramps offers in a namespace.

This is the vocabulary that query_records and GrampsQL cannot reach: "is a descendant of", "has a common ancestor with", "matches another filter". Read it before building a custom filter with create_filter.

list_custom_filtersA

List the custom filters already saved on this instance.

A saved filter can be reused by name from query_objects and the timelines, so a complicated selection is defined once.

create_filterA

Save a reusable custom filter built from Gramps' own rules.

Worth doing for a selection you will run repeatedly — an audit scope, a branch of the tree — because the filter then has a name rather than being retyped each time.

delete_filterA

Delete a saved custom filter.

Deletes the filter definition only. Nothing in the tree is touched.

consolidated_timelineA

Merge several people or families into one chronological timeline.

The way to see a household move together through censuses, or to check whether a family's events are mutually consistent. Carries the same citation count and confidence per event as get_timeline, with an uncited_count across the whole set.

list_tasksA

List recent background jobs for this tree, newest first.

Use when you have lost a task_id, or to see whether anything is still running before starting a write session.

get_transactionA

Read one transaction in full, including the objects it changed.

list_transactions summarises; this shows what actually moved. Read it before undoing anything.

get_placeA

Read one place: name, title, type, enclosure, coordinates and URLs.

The enclosed_by handles are the jurisdictional chain. A place with none is orphaned in the hierarchy, which is usually a place that got minted from an event's place string rather than created deliberately.

get_citationA

Read one citation: page, confidence, date, and its source.

cited_by_count is the useful part. Zero means nothing references this citation — it is orphan debris, and uncite should have deleted it.

get_noteA

Read one note in full, with its type and what it is attached to.

Notes hold the researcher's own reasoning — why a conflict was resolved one way, what a hard-to-read page actually said — so the text comes back whole rather than truncated.

get_mediaA

Read one media object: path, mime type, checksum, description, date.

referenced_by_count above one is usually correct — one image cited from every fact it proves. Several media objects sharing a checksum is the duplicate that find_duplicates(kind='media_checksum') hunts.

add_placeA

Create a place deliberately, with a type and a parent.

Use this instead of letting a place appear as a side effect of naming one in an event. That route produces an untyped, unparented place whose title is the bare string you typed, which is how duplicate hierarchies start.

get_factsA

Read the tree's record-holders: oldest at death, youngest parent, most children.

Superlatives across a set of people, not statistics about one person. An implausible holder — a father at eight, a death at 130 — is usually a data error, which makes this a quick plausibility check. Living and private people are excluded unless include_private is set. Slow: the server computes it all per call.

get_researcherA

Read the researcher details recorded for this tree.

These are embedded in every export, so they travel with any GEDCOM or Gramps XML you hand to someone else. Worth checking before sharing one.

query_recordsA

Query any collection server-side, with columns, filters and sorting.

More capable than query_objects and the tool to reach for on an audit. It reads indexed columns, reaches arbitrary paths inside the stored object, and follows relationships — so "families where the mother died before the father" or "events whose place is in Ohio" are single queries.

It is the only way to filter events by type. GrampsQL cannot: the word is shadowed, so type = "Birth" silently matches nothing. Pass event_type here instead.

Returns rows plus a total count and a next_after cursor. Private records, living people and families with a living parent come back as redacted stubs.

list_event_typesA

List the event type names this tree uses, with their stored integers.

Useful before a query_records filter, and as a check on itself: an unexpected type name in the list is usually a typo that Gramps silently accepted as a new custom type.

add_dna_matchA

Record a DNA match as evidence, cited to the test that found it.

Stored as Gramps Web stores a match, so its interface and get_dna_matches read it back. Nothing is written unless the segments parse: unreadable data would otherwise record a match sharing no DNA.

A match proves the two share DNA, not how they are related. Record any relationship separately, with its own evidence.

get_dna_matchesA

List the DNA matches recorded against a person.

Each match reports total shared centiMorgans and the largest single segment — the two figures a relationship estimate actually rests on — plus any common ancestor already identified.

DNA evidence works differently from documentary evidence. A match proves a biological relationship exists; it does not say which one. Shared cM constrains the possibilities and rarely resolves them, and it says nothing about the paper trail. unattributed_count is the useful number: matches with no common ancestor identified are the open research.

get_ydnaA

Report a person's Y-DNA haplogroup, from broadest clade to terminal.

Y-DNA follows the direct paternal line only, so it speaks to one thread of a tree and is silent on every other. A shared terminal clade indicates a common paternal ancestor, usually far further back than any record reaches — it corroborates a surname line rather than proving a named link.

has_data is false when the person has no Y-DNA recorded, which is the normal case.

parse_dna_segmentsA

Parse pasted shared-segment data into structured segments and totals.

Use this to check what a match file actually contains before recording it. Returns each segment plus the total and largest-segment centiMorgans.

If nothing parses, parsed is false and the reason is given. That distinction matters: the server answers unreadable input with zero segments and a success status, which would otherwise read as "this person shares no DNA" rather than "I could not read that".

get_relationshipA

Work out how two people in the tree are related.

Returns the relationship in words plus the generation distance from each person to their common ancestor. related is false when no common ancestor was found within the search depth — which is a finding in itself if you expected one.

assess_livingA

Ask the server whether a person is probably still alive, and why.

The server walks relatives to decide, so it handles people with no dates of their own — someone undated whose children died a century ago. Use it before publishing or sharing anything, and use explain when you want to see the reasoning rather than just the verdict.

Note this is advisory. Bulk output is filtered by this server's own rule regardless of what this returns.

get_timelineA

Build a chronological timeline of someone's life events.

Each entry carries their age at the time, how many citations support the event, and the strongest confidence among them — so a timeline doubles as a readable audit of where the evidence thins out. uncited_count says how many events on it rest on nothing.

event_spanA

Measure the elapsed time between two events.

The arithmetic behind most plausibility checks: age at marriage, years between a census and a death, how long a widow waited. Doing this by hand from two formatted date strings is where transcription errors hide.

reindex_searchA

Rebuild the full-text search index.

search_text reads a stored index, and nothing refreshes it after writes. Run this after a bulk import or a large editing session, or searches will quietly miss everything added since the last build. Returns a task_id to poll with get_task.

get_taskA

Check whether a background job has finished, and whether it worked.

Undo, verification, import and reindex are dispatched to a worker and answer before the work is done. Poll this until finished is true, then read succeeded. Submitting one of those operations and never checking leaves you assuming an outcome you have not seen.

verify_treeA

Run Gramps' own genealogical plausibility checks over the whole tree.

This is a different audit from the citation ones. list_unsourced_facts asks whether a claim has evidence; this asks whether a claim is possible — a mother bearing a child at nine, a marriage lasting 120 years, a date that will not parse. A wrong date can be impeccably sourced, so these catch what a citation sweep cannot.

Leave the thresholds alone on a first run; the server's defaults are the conventional ones. Tighten a specific bound when chasing a specific class of error.

May run in the background, in which case a task_id comes back — poll it with get_task.

consult_referenceA

Consult the legacy GEDCOM reference layer for HINTS (never authoritative).

Searches the configured Ancestry/FamilySearch exports and returns, per file, matching individuals and their claimed facts. Crucially, each fact is flagged whether the legacy tree attached a source, with the source text if present -- so you can distinguish 'they cite an actual death certificate' from 'unsourced guess'. These are UNTRUSTED hints: use them to decide what real record to hunt for, then create the fact in the tree citing that record -- do not copy a hint in as a sourced fact. Probably-living people are withheld and counted.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.6/5.0

Scored across 83 tools

Disambiguation4/5

Most tools target distinct resources and actions, and descriptions often explicitly distinguish generic from specific tools (e.g. get_object vs get_person, cite_object vs cite_event). However, overlaps remain: query_objects vs query_records, add_media vs attach_media, and list_object_types vs list_event_types could still cause misselection.

Naming Consistency4/5

The set is overwhelmingly snake_case and action-oriented, with predictable verb_noun names across most CRUD, audit, and lifecycle operations. Minor deviations such as db_stats, event_span, consolidated_timeline, and uncite slightly break the strict verb_noun pattern.

Tool Count1/5

83 tools is far beyond a practical MCP surface for an agent, even for a complex genealogy evidence domain. While many tools are specialized and defensible, the count itself creates excessive selection burden and is an extreme mismatch for efficient tool use.

Completeness4/5

The surface is very comprehensive, covering people, families, events, sources, citations, repositories, media, places, DNA, reports, filters, transactions, and audits. Minor gaps exist, notably the apparent absence of a generic search_text tool despite reindex_search referencing one, with some operations reachable only through generic escape hatches.

Maintenance

ActivityMaintained
ResponsivenessNo issues