Skip to main content
Glama
JinyangWang27

people-context

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
PEOPLE_CONTEXT_DBNoPath to the SQLite database file. Overrides the --db flag; if not set, the database location is resolved from the XDG config file, an OpenClaw workspace, or the XDG data directory.
PEOPLE_CONTEXT_DB_KEYNoEncryption key for SQLCipher at-rest encryption. This key is read only from this environment variable and is only needed when the server is installed with the encrypted extra.

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
resolve_personA

Resolve a name, nickname, or partial reference to candidate people.

Call this first whenever the user mentions someone, before asking who they mean. Returns ranked candidates with a score and match reason. If two or more candidates are close, the result is flagged ambiguous and all are returned so you can disambiguate with extra context or a clarifying question. An empty candidate list means no confident match — use remember or remember_person to create a new record. Put distinguishing context in hints (org, role, relationship) rather than in query.

get_person_contextA

Assemble a minimal-disclosure context bundle for one person.

Pass person_id from resolve_person, or person (a name or alias) to resolve inline: an ambiguous name returns the candidates instead of context. Returns narrow identity fields, active relationships and affiliations, and one ranked facts/interactions slice capped by max_items. Set include_communication=true (or a purpose mentioning communication) to include communication traits. Sensitive and restricted records are never returned by this ordinary tool, and leave no trace that they exist. truncated says the item budget cut the list.

search_peopleA

Free-text search over stored people for browsing or lookup.

Broader than resolve_person: use this to list who is known that matches a query, rather than to pin down a single identity. Returns ranked candidates.

semantic_searchA

Search active people and safe interaction summaries by multilingual semantic similarity.

This optional local search requires an explicit pctx reindex --semantic first. It never downloads a model while serving a query and refuses to mix vectors from different model revisions.

remember_personA

Create a new person or update the existing one matching name.

Use this to durably record someone the user talks about. aliases is a list of {value, kind?, lang?, script?} objects (kinds: nickname, native_script, transliteration, handle, former_name, other); new aliases are merged into an existing record. Set summary to describe who they are, and is_self=True only for the user themselves. Returns the person and whether it was created.

rememberA

Record one thing the user stated about one person, in a single call.

Use this when the user directly tells you something durable — "Alice from Acme prefers short emails", "Bob is my manager", "I had coffee with Dana today". person is the name as the user said it: it is resolved first, and a new person is created only when nobody matches. org/role record an affiliation, relationship records how the user relates to them (e.g. manager_of, friend_of, from the user's point of view), and note records the statement as a fact, trait, or interaction. Leave kind as auto to classify the note by a fixed keyword rule, or set it explicitly when you know. Pass occurred_at when the statement says an interaction happened earlier ("met Dana last week"); without it such a note is refused rather than dated today, because that date is what the staleness report reads.

Identity is never guessed for a write: status: ambiguous or unconfirmed returns candidates and records nothing — ask the user, then call again with the exact canonical name or a unique alias. Everything recorded commits in one transaction and is audited like the individual tools. For material you extracted or inferred from a transcript rather than a direct statement, use stage_candidates so the user reviews it first.

get_communication_guidanceA

Return sensitivity-gated signal for client-composed communication advice.

Pass person_id from resolve_person, or person (a name or alias) to resolve inline; an ambiguous name returns candidates instead of guidance.

set_communication_philosophyB

Store communication philosophy verbatim while auditing lengths only.

list_remindersA

List pull-based reminders, due-dated first and communication notes last.

Filter by person_id, or by person (a name or alias) resolved inline; omit both for every person's reminders.

set_reminderA

Create a reminder for an existing person.

kind is follow_up (dated, something to do), occasion (a date that recurs), or communication_note (undated guidance surfaced with the person's context).

complete_reminderB

Transition one active reminder to completed.

add_aliasB

Add a normalized-deduplicated alias to an existing person.

kind is one of nickname, native_script, transliteration, handle, former_name, or other, and defaults to other. The published schema carries the enum, so an unlisted value is refused before the alias is built rather than dropped.

set_relationshipA

Create a directed relationship between two existing people.

set_affiliationC

Create an affiliation, resolving an org id or get/creating by name.

record_factA

Record a time-aware fact about an existing person.

sensitivity defaults to personal; sensitive and restricted records are withheld from ordinary reads. Prefer remember for a single statement named by a person's name.

record_observationB

Record a subjective observation, separate from disclosed context.

record_traitB

Record a derived trait with validated category and provenance.

category is one of communication_style, temperament, values, preference, topics_to_avoid, or other. Cite the observation or interaction it rests on in evidence_note or evidence_ids where you can.

record_interactionB

Record a concise interaction summary after validating all participants.

correct_recordC

Correct whitelisted assertion fields in place with before/after audit.

supersede_factA

Close a fact that was true and open its replacement from an effective date.

Use this when a stored value was historically correct and the real-world state changed; correct_record remains the tool for a value that was simply wrong. The old fact keeps its person, predicate, value, and provenance and is closed the day before effective_from; the replacement inherits the old assertion's original end date, so a bounded claim is never widened into an open-ended one. Person, predicate, and the replacement's end date cannot be changed here. Omitting confidence or sensitivity inherits the old fact's.

Both rows commit together under one logical transaction, or neither commits.

get_relationship_graphA

Return active relationship structure around one person, capped for bounded disclosure.

Pass person_id from resolve_person, or person (a name or alias) to resolve inline.

find_connectionC

Return one shortest relationship path, or a structured not-connected result.

create_groupA

Create one identified group: a class, cohort, team, department, club, household, or community.

Every call creates a new group; an equal name is never treated as the same group. Use find_groups first and reuse the returned id when the user confirms it is the same one. organization_id must name an existing organization and only places the group under it — it creates no affiliation. sensitivity defaults to personal; a sensitive or restricted group is withheld from ordinary reads together with every membership in it.

add_group_membershipA

Record that an existing person held a role in an existing group.

Record only what was stated or confirmed. Leave dates out when they are unknown — never guess a school year or fill a January 1 date. temporal_basis is unknown (no dates), period (at least one known bound; a missing bound means unknown, not open-ended), or ongoing (asserted current, no end date); it is inferred from the dates when omitted, except that ongoing must be stated. role defaults to member. sensitivity defaults to personal. Concurrent and historical memberships are all kept.

close_group_membershipA

Record the last day a historically true membership held.

Use this when someone left a group; the membership's earlier facts are preserved. It refuses a membership that already records an end (already_ended) or an end before its start (ends_before_start). Use correct_record with entity type group_membership when a stored membership was simply wrong.

find_groupsA

List groups whose normalized name contains name, optionally of one kind.

Results are candidates, not identity: two groups with the same name stay distinct, so ask the user which one is meant when several match. Sensitive and restricted groups are never returned by this ordinary tool. Ordered by normalized name then id; truncated reports more.

get_groupA

Return one group and a bounded page of its recorded memberships.

These are recorded memberships only: sharing a group is context, not proof that members know each other. Sensitive and restricted groups read as found: false, and sensitive or restricted memberships are omitted without affecting truncated.

list_group_membershipsA

Return a bounded page of one person's recorded group memberships with each group.

Pass person_id from resolve_person, or person (a name or alias) to resolve inline. Only ordinary memberships in ordinary groups are returned. An unknown or removed person returns found: false.

explain_shared_connectionsA

Explain how two people are connected through groups they were both recorded in, and when.

Use for shared-background, introduction, and "how do they know each other" questions. Pass each person as an id (person_a_id, person_b_id) or a name (person_a, person_b).

Each connection is one membership of each person in the same group, cited in full. label is classmates (both student in a class) or teammates (both participant in a team) only when the recorded dates prove a common day (temporal: overlap, with the overlap period); otherwise the connection is shared_context only. temporal is disjoint when the dates exclude a common time and unknown when they cannot tell. Sharing a club, household, or community is not friendship, kinship, or acquaintance; different groups under one organization, and people linked through a third person, share nothing here. direct_relationships are recorded relationships between the two, kept apart from derived results. No result means no shared group was found, not that they do not know each other. Only ordinary groups and memberships are used; truncated and memberships_truncated report a partial answer.

get_stale_relationshipsA

Return people you have not interacted with recently, using ordinary interactions only.

get_person_timelineA

Return one person's recent history, newest first, as a bounded chronology.

Pass person_id from resolve_person, or person (a name or alias) to resolve inline.

Entries project durable records — interactions, observations, facts, affiliations, relationships, and traits — with the stored timestamp each was placed by and which field that was. Sensitive and restricted records are never returned by this ordinary tool, and a trait names only evidence that is itself ordinary. An unknown or removed person returns found: false rather than an error.

get_consolidation_contextA

Return one person's stored facts, traits, observations, and affiliations and how they relate.

Pass person_id from resolve_person, or person (a name or alias) to resolve inline.

Use this before proposing maintenance. signals names pairs of records that share a predicate or category and says how they stand — duplicate_fact, restated_fact, contradictory_fact, succeeding_fact, duplicate_trait, divergent_trait — comparing normalized values and inclusive validity periods only. It decides nothing: reading the evidence and proposing a correct_record, a supersede_fact, or a merge_people for the user to approve is your job, and several observations supporting one trait are separate evidence rather than duplicates.

affiliations carries the person's stored roles at organizations — employment, education, membership — with their ids, dates, provenance, and any import receipt, so an incoming CV claim can be checked against what is already recorded. It has its own page and its own affiliations_truncated flag, and no signal is computed over it: two roles at one organization may be a promotion, a rehire, or two concurrent posts, and only you can read which. A valid_to of null means the stored assertion set no end, not that the role is confirmed current, and created_at is when the row was written rather than when the role began. A page that truncates is not evidence that a role is absent.

This read never writes. Sensitive and restricted records are never returned, and a trait names only evidence that is itself ordinary. Affiliations carry no disclosure level at all, so this collection adds no sensitivity control and is no route to a protected fact — background that needs one belongs in a fact. An unknown or removed person returns found: false rather than an error.

upcoming_datesB

Return ordinary birthdays and dated active reminders inside an inclusive upcoming window.

Optionally narrow to one person by person_id or by person (a name or alias).

merge_peopleB

Merge a duplicate person into a primary person atomically.

forgetA

Hard-delete a person or record and redact identifying audit history.

import_contentA

Extract and atomically stage header-only candidates from a supported source without bodies.

Accepted source_type values are email, mbox, vcard, ics, linkedin, outlook, and whatsapp. self_sender is an optional chat-export label for the user, such as a display name or a bare phone number, used to omit the user's own messages.

A path import records a receipt for the file it read, so importing that exact file again reports the existing batch instead of staging a second copy. forced says the repeat is intentional: it stages the same content as a distinct processing session and never weakens the duplicate rule for later calls. It is also the only way past source_previously_redacted after a hard forget — and for mbox, which is read from a path and cannot be resubmitted as inline content, the only way at all.

stage_candidatesA

Stage agent-extracted people, interactions, records, relationships, groups, and memberships.

Candidate types are person, interaction, affiliation, fact, observation, trait, relationship, group, and group_membership.

Use this after extracting concise candidates from user-provided notes, meeting transcripts, or other agent-visible text. Distinguish what was stated (fact), what happened in this source (observation), and what you inferred (trait, which requires an explicit confidence and a concise evidence_note). Relationship candidates carry batch-local from_ref/to_ref and are ordinary-disclosure only: omit a relationship the user would consider sensitive or restricted rather than staging it.

References are batch-local; raw notes and source text must not be included in candidate fields. A request using observation, trait, or relationship is bounded to 500 candidates, a 128-character source, 1 MiB of candidate JSON, and 8 KiB per string.

A fact or affiliation may record who asserted it in an optional stated_by of at most 256 characters: a person, a document, or a role. Attribution is not verification. A CV saying someone is analytical is that person's own claim about themselves, so stage it as a fact whose value says so and whose stated_by names them, never as an inferred trait. stated_by is separate from source, which names the process that wrote the row, and from source_kind below, which receipts the artifact read. Omit it when the attribution is unknown rather than guessing at a speaker.

A trait may name the records it was drawn from. Give a supporting observation or interaction any short evidence_ref label of your own and list those labels in the trait's evidence_refs; use evidence_ids for records already stored. Evidence must be about the trait's own person, and one trait cites at most 32 references and ids combined, each at most 256 characters.

A shared context is two candidates, never one. A group names an identified class, cohort, team, department, club, household, or community and carries a batch-local ref; a group_membership places one person_ref in one group_ref with a role, and requires a batch that passes source_kind, so a group committed in an earlier call can still be named. Group names never merge: staging looks nothing up by name, so committing a group candidate creates a new group unless you pass group_id — resolve an existing group with find_groups first and pass the id it returns. Record dates only where the source gave them. Absent dates stay absent and mean unknown, never "still going": temporal_basis is unknown without dates, period with them, and ongoing only when you set it because the source said so. Do not invent a year, a class number, or a yearly placement per grade; a confirmation that people stayed together records the people and the extent that were confirmed, and nothing more. "My classmate" with no identified group is a relationship, not an invented group.

source_kind optionally records an import receipt for this batch. It is a machine category such as meeting_transcript, at most 128 characters of letters, digits, ., _, -, or / — never a person, a title, or a description; put any human wording in label instead. If you can compute a SHA-256 over the exact source artifact, pass it as content_digest (64 lowercase hex characters) so re-importing that same source can be detected; without one, no duplicate detection is promised. extraction_fingerprint is optional and should be omitted unless you have explicit, bounded configuration semantics for it. None of these fields may carry source text.

review_importA

Return staged candidates and statuses for one batch.

The response carries a batch_digest. Pass it back to amend_candidate, withdraw_candidates, or commit_import to have the action refused if somebody else changed the batch after this read.

amend_candidateA

Correct one staged candidate before it is committed, returning the revised batch.

The patch replaces the named fields and leaves the rest alone. Nothing is committed: confirming an amendment is not acceptance of the batch.

withdraw_candidatesA

Drop staged candidates from consideration, returning the revised batch.

A withdrawn candidate stays listed as rejected so the user can see what was dropped, and is never committed. Nothing else about the batch changes.

commit_importB

Commit accepted people and resolvable interactions idempotently.

Accepting a withdrawn candidate refuses the whole commit. Supplying the expected_batch_digest from the review the user approved refuses it if the batch moved after they saw it.

Prompts

Interactive templates invoked by user choice

NameDescription
whoIdentify one person and read what is stored.
rememberRecord one direct statement with the `remember` tool, or stage extracted material for review.
meeting_prepOne short brief per attendee from stored context, guidance, and open follow-ups.
end_of_session_captureReview what was learned about people and stage it for the user to review; never commit.
maintenance_reviewRead timeline and consolidation signals, then propose corrections and wait for approval.

Resources

Contextual data attached and managed by the client

NameDescription
people-context-guideResolution-first reads, context vs. guidance, meeting prep, and propose-then-commit capture.
people-context-selfNarrow identity of the person marked as self: id, canonical name, aliases, summary.

TDQS

A3.5/5.0

Scored across 41 tools

Disambiguation4/5

Most tools target a distinct resource and action, and detailed descriptions separate similar readers like get_person_context, get_consolidation_context, and get_person_timeline. Some overlap remains between the broad remember convenience tool and the specialized record_*/set_* writers, but the descriptions give clear usage guidance.

Naming Consistency4/5

The naming is predominantly snake_case verb_noun and generally predictable (get_*, record_*, set_*, find_*, list_*). Minor deviations like semantic_search, upcoming_dates, and forget, plus mixed verb choices across create/set/add/record, keep it from being fully consistent.

Tool Count2/5

41 tools is well beyond the typical well-scoped range and exceeds the 25+ threshold for a heavy surface. While the domain is broad, several tools overlap in purpose and could be consolidated, such as remember versus the record_* family and the multiple get_* context variants.

Completeness4/5

The tool surface covers the main lifecycle well: identity, facts, traits, interactions, relationships, affiliations, groups, reminders, imports, corrections, merges, and deletion. Minor gaps exist, such as no dedicated end/remove operation for affiliations or relationships and no batch listing for staged imports, but these are workable.

Maintenance

ActivityActive
ResponsivenessWithin a week