Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.JinyangWang27/people-context

PYPI · PEOPLE-CONTEXT

Local-first MCP server giving AI agents contextual knowledge about the people in your life

Available components

−5 this week 89 Trust /100

Last scanned (5 hours ago)

Scores higher than 91% of PyPI servers

Category Memory and Knowledge

Trust breakdown (7 categories)

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. How we score → Why this is hard to score →

Supply Chain Security100
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • Runs hatchling.build at install time, a recognised build step with no custom scripting around it. View diagnostics → Pass
  • 1 of 30 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency100
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Cryptographically verified build provenance (signed, bound to JinyangWang27/people-context). View diagnostics → Pass
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 0 days ago).Pass
  • Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability77
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (good).Pass
  • Context-footprint check failed: tool/resource definitions use about 6516 tokens (~141/item across 46 items; 44 tools + 2 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management70
  • Stability observed for 21 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage71
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 0% of tool parameters carry a description.Fail
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • All 3 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 46 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
What we tested

Checks we ran (16)

  • Malware scan
  • Known CVEs
  • Install scripts
  • Dependency health
  • Source repository
  • Provenance
  • License
  • Maintenance
  • Security disclosure
  • Schema quality
  • Stability
  • Tool coverage
  • Injection markers
  • Destructive annotations
  • Judged manipulation
  • MCP protocol

Does not apply to this package (2)

  • Endpoint SecurityScored on hosted endpoints only. A package has no live endpoint of its own for us to probe.
  • Transport & ReachabilityScored on hosted endpoints only. A package has no live endpoint of its own for us to probe.

The score does not measure everything. What the score does not measure →

Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 6 Nov 26 0
    • Malware scan: pass → unverified ▼ security
    • Schema quality: 5718 → 6516 ▼ functional
    • Package version: 1.4.0 → 1.5.0 functional
  • 5 Nov 26 +15
    • Malware scan: unverified → pass ▲ security
  • 4 Nov 26 −20
    • Malware scan: pass → unverified ▼ security
    • Stability: pass → 0.63 functional
  • 1 Nov 26 +15
    • Malware scan: unverified → pass ▲ security
  • 31 Oct 26 −15
    • Malware scan: pass → unverified ▼ security
    • Package version: 1.3.0 → 1.4.0 functional
  • 30 Oct 26 +15
    • Malware scan: unverified → pass ▲ security
  • 29 Oct 26 +1
    • Stability: 0.97 → pass security
  • 28 Oct 26 −16
    • Malware scan: pass → unverified ▼ security
    • Stability: pass → 0.97 functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 6 Nov 2026 · Analysed pypi/people-context@1.5.0

Provenance Verified

A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.

Result Verified
Ecosystem pypi
Reason Verified
Discovered via Registry attestation endpoint
Source repo JinyangWang27/people-context
Certificate issuer https://token.actions.githubusercontent.com
Certificate SAN https://github.com/JinyangWang27/people-context/.github/workflows/release.yml@refs/tags/v1.5.0
Rekor log index 3708709280
Predicate type PyPI publish attestation https://docs.pypi.org/attestations/publish/v1
Subject digest sha256:e212f5af7a833080c084f3fc4bdada712a903b69e048df27e4e3f802194c7157

Background: How many MCP packages publish verified provenance →

Install scripts 1 script
Hook Tier Command
build_backend Known build tool hatchling.build

Background: Why install scripts are a supply-chain risk →

Dependencies 30 packages
Packages resolved 30
No linked repository 1
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 44 exposed · ~6,160 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
add_alias ~111

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.

NameTypeReqDescription
kind–––
lang–––
person_idstringyes–
script–––
valuestringyes–

Structured output declared, but exposes no named fields.

No examples provided.

add_group_membership ~195

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.

NameTypeReqDescription
confidence–––
group_idstringyes–
person_idstringyes–
role–––
sensitivity–––
temporal_basis–––
valid_from–––
valid_to–––

Structured output declared, but exposes no named fields.

No examples provided.

amend_candidate ~79

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.

NameTypeReqDescription
batch_idstringyes–
candidate_idstringyes–
expected_batch_digest–––
patchobjectyes–

Structured output declared, but exposes no named fields.

No examples provided.

close_group_membership ~101

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.

NameTypeReqDescription
ended_onstringyes–
membership_idstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

commit_import ~126

Commit accepted people and resolvable interactions idempotently. The receipt is the verification: an id in `committed_ids` is stored. Read records back only for ids in `unresolved_ids` or `skipped_ids`, or when the user asks to see them. 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.

NameTypeReqDescription
accepted_idsarrayyes–
batch_idstringyes–
expected_batch_digest–––

Structured output declared, but exposes no named fields.

No examples provided.

complete_reminder ~24

Transition one active reminder to completed.

NameTypeReqDescription
reminder_idstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

correct_record ~44

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

NameTypeReqDescription
entity_idstringyes–
entity_typestringyes–
fieldsobjectyes–

Structured output declared, but exposes no named fields.

No examples provided.

create_group ~148

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.

NameTypeReqDescription
kind–yes–
namestringyes–
organization_id–––
sensitivity–––

Structured output declared, but exposes no named fields.

No examples provided.

explain_shared_connections ~317

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.

NameTypeReqDescription
limitinteger––
person_a–––
person_a_id–––
person_b–––
person_b_id–––

Structured output declared, but exposes no named fields.

No examples provided.

find_connection ~45

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

NameTypeReqDescription
max_depthinteger––
person_astringyes–
person_bstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

find_groups ~96

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.

NameTypeReqDescription
kind–––
limitinteger––
name–––

Structured output declared, but exposes no named fields.

No examples provided.

forget ~33

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

NameTypeReqDescription
scopestringyes–
targetstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

get_communication_guidance ~72

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.

NameTypeReqDescription
person–––
person_id–––
situation–––

Structured output declared, but exposes no named fields.

No examples provided.

get_consolidation_context ~428

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.

NameTypeReqDescription
limitinteger––
person–––
person_id–––

Structured output declared, but exposes no named fields.

No examples provided.

get_group ~81

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`.

NameTypeReqDescription
group_idstringyes–
limitinteger––

Structured output declared, but exposes no named fields.

No examples provided.

get_person_context ~167

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.

NameTypeReqDescription
include_communicationboolean––
max_itemsinteger––
person–––
person_id–––
purpose–––

Structured output declared, but exposes no named fields.

No examples provided.

get_person_timeline ~140

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.

NameTypeReqDescription
limitinteger––
person–––
person_id–––

Structured output declared, but exposes no named fields.

No examples provided.

get_relationship_graph ~69

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.

NameTypeReqDescription
depthinteger––
person–––
person_id–––
types–––

Structured output declared, but exposes no named fields.

No examples provided.

get_stale_relationships ~45

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

NameTypeReqDescription
category–––
limitinteger––
threshold_daysinteger––

Structured output declared, but exposes no named fields.

No examples provided.

import_content ~235

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.

NameTypeReqDescription
content–––
forcedboolean––
path–––
self_sender–––
source_typestringyes–

Structured output declared, but exposes no named fields.

No examples provided.

list_group_memberships ~87

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`.

NameTypeReqDescription
limitinteger––
person–––
person_id–––

Structured output declared, but exposes no named fields.

No examples provided.

list_reminders ~73

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.

NameTypeReqDescription
due_before–––
person–––
person_id–––
status–––

Structured output declared, but exposes no named fields.

No examples provided.

merge_people ~35

Merge a duplicate person into a primary person atomically.

NameTypeReqDescription
duplicate_idstringyes–
primary_idstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

record_fact ~100

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.

NameTypeReqDescription
confidence–––
person_idstringyes–
predicatestringyes–
sensitivity–––
valid_from–––
valid_to–––
valuestringyes–

Structured output declared, but exposes no named fields.

No examples provided.

record_interaction ~50

Record a concise interaction summary after validating all participants.

NameTypeReqDescription
channel–––
occurred_at–––
participant_idsarrayyes–
sensitivity–––
summarystringyes–

Structured output declared, but exposes no named fields.

No examples provided.

record_observation ~45

Record a subjective observation, separate from disclosed context.

NameTypeReqDescription
observed_at–––
person_idstringyes–
sensitivity–––
textstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

record_trait ~116

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.

NameTypeReqDescription
category–yes–
confidence–––
evidence_ids–––
evidence_note–––
person_idstringyes–
sensitivity–––
valuestringyes–

Structured output declared, but exposes no named fields.

No examples provided.

remember ~371

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.

NameTypeReqDescription
kindstring––
note–––
occurred_at–––
org–––
personstringyes–
predicate–––
relationship–––
role–––
sensitivity–––
sourcestring––
trait_category–––

Structured output declared, but exposes no named fields.

No examples provided.

remember_person ~166

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. An email address is contact information: store it as a `handle` alias, never as `name`. Set `summary` to describe who they are, and `is_self=True` only for the user themselves. Returns the person and whether it was created.

NameTypeReqDescription
aliases–––
is_selfboolean––
namestringyes–
sourcestring––
summary–––

Structured output declared, but exposes no named fields.

No examples provided.

remove_alias ~104

Remove one alias, matched by normalized value, from an existing person. Use this to undo a wrong alias, such as an email address stored as a name. The person and all of their other names and records stay intact. An alias that is not present returns `removed: false` and changes nothing; the canonical name is refused with `alias_conflict` (use `rename_person` instead).

NameTypeReqDescription
person_idstringyes–
valuestringyes–

Structured output declared, but exposes no named fields.

No examples provided.

rename_person ~129

Replace a person's canonical name; the old name stays on as an alias. Use this to correct a wrong name, such as an email address stored as the name: the old name is kept as a `former_name` alias, or as a `handle` when it is an email address, so it is still contact information and imports still match on it. An email address as the new name is refused with `name_is_email`; a name that already belongs to another person is refused with `name_conflict`.

NameTypeReqDescription
namestringyes–
person_idstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

resolve_person ~153

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`.

NameTypeReqDescription
hints–––
limitinteger––
querystringyes–

Structured output declared, but exposes no named fields.

No examples provided.

review_import ~170

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. A new-person row may carry `possible_matches`: existing people sharing its given name or a short form of it. They are not matches. Ask the user; to reuse one, pass its id as `matched_person_id` to `amend_candidate`, otherwise commit to create a new person. A row with `name_is_email: true` stays unresolved at commit: ask the user for the person's name and amend `name` to it, keeping the address as a `handle` alias.

NameTypeReqDescription
batch_idstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

search_people ~66

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.

NameTypeReqDescription
limitinteger––
querystringyes–

Structured output declared, but exposes no named fields.

No examples provided.

semantic_search ~76

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.

NameTypeReqDescription
kinds–––
limitinteger––
querystringyes–

Structured output declared, but exposes no named fields.

No examples provided.

set_affiliation ~63

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

NameTypeReqDescription
confidence–––
orgstringyes–
person_idstringyes–
rolestringyes–
valid_from–––
valid_to–––

Structured output declared, but exposes no named fields.

No examples provided.

set_communication_philosophy ~29

Store communication philosophy verbatim while auditing lengths only.

NameTypeReqDescription
textstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

set_relationship ~62

Create a directed relationship between two existing people.

NameTypeReqDescription
confidence–––
label–––
object_idstringyes–
subject_idstringyes–
typestringyes–
valid_from–––
valid_to–––

Structured output declared, but exposes no named fields.

No examples provided.

set_reminder ~89

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).

NameTypeReqDescription
due_at–––
kind–yes–
person_idstringyes–
recurrence–––
textstringyes–

Structured output declared, but exposes no named fields.

No examples provided.

stage_candidates ~1,172

Stage agent-extracted people, interactions, records, relationships, groups, and memberships. Candidate types are `person`, `interaction`, `affiliation`, `fact`, `observation`, `trait`, `relationship`, `group`, and `group_membership`. Stage every candidate from one source in a single call. Required fields, beyond `type`; any key the type does not declare is refused: `person` `ref`, `name` (optional `aliases`); `affiliation` `person_ref`, `org`, `role`; `fact` `person_ref`, `predicate`, `value`; `observation` `person_ref`, `text`; `trait` `person_ref`, `category`, `value`, `evidence_note`, `confidence`; `interaction` `summary`, `participant_refs`, `date`; `relationship` `from_ref`, `to_ref`, `relationship_type`; `group` `ref`, `name`, `kind`; `group_membership` `person_ref`, `group_ref`. Only `person` and `group` carry a `ref`; the rest point at one. Staging matches each `person` against stored people and review shows the outcome, so do not resolve names first. An email address is contact information, never a `name`: put it in `aliases` as `{"value": <address>, "kind": "handle"}`, which is also what matching reads. 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 p…

NameTypeReqDescription
candidatesarrayyes–
content_digest–––
external_source_id–––
extraction_fingerprint–––
label–––
sourcestringyes–
source_kind–––

Structured output declared, but exposes no named fields.

No examples provided.

supersede_fact ~186

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.

NameTypeReqDescription
confidence–––
effective_fromstringyes–
fact_idstringyes–
new_valuestringyes–
sensitivity–––

Structured output declared, but exposes no named fields.

No examples provided.

upcoming_dates ~62

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).

NameTypeReqDescription
person–––
person_id–––
window_daysinteger––

Structured output declared, but exposes no named fields.

No examples provided.

update_alias ~126

Correct one alias in place, matched by normalized value; omitted fields stay unchanged. Keeps the alias's id. A `new_value` that normalizes to the canonical name or to another alias is refused with `alias_conflict`; an unknown alias is refused with `alias_not_found`. The result lists which of `value`, `kind`, `lang`, and `script` actually changed.

NameTypeReqDescription
kind–––
lang–––
new_value–––
person_idstringyes–
script–––
valuestringyes–

Structured output declared, but exposes no named fields.

No examples provided.

withdraw_candidates ~74

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.

NameTypeReqDescription
batch_idstringyes–
candidate_idsarrayyes–
expected_batch_digest–––

Structured output declared, but exposes no named fields.

No examples provided.

Install

How do I install the io.github.JinyangWang27/people-context MCP server?

io.github.JinyangWang27/people-context runs locally as a PyPI package, launched with uvx --from people-context==1.5.0 people-context. Ready-made configuration for Claude, Cursor, VS Code, Codex and 3 more is on this page, copied from each client's own documentation.

pypi · people-context

# add to Claude Code
claude mcp add jinyangwang27-people-context -- uvx --from people-context==1.5.0 people-context
Common questions

What is the io.github.JinyangWang27/people-context MCP server?

io.github.JinyangWang27/people-context is an MCP server listed in the public MCP registry as io.github.JinyangWang27/people-context. Local-first MCP server giving AI agents contextual knowledge about the people in your life. This page covers its PyPI package (people-context).

Is the io.github.JinyangWang27/people-context MCP server safe to use?

io.github.JinyangWang27/people-context scores 89 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 6 November 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 io.github.JinyangWang27/people-context MCP server expose?

io.github.JinyangWang27/people-context exposes 44 tools: resolve_person, get_person_context, search_people, semantic_search, remember_person, and 39 more. Their descriptions and schemas cost roughly 6,160 tokens of context every time the server is loaded.

Is the io.github.JinyangWang27/people-context MCP server still maintained?

io.github.JinyangWang27/people-context is still listed as active in the MCP registry. We last reached this channel on 6 November 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 io.github.JinyangWang27/people-context MCP server under?

io.github.JinyangWang27/people-context declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

What did VerifyMCP test on the io.github.JinyangWang27/people-context MCP server?

VerifyMCP ran 16 checks on io.github.JinyangWang27/people-context, covering Malware scan, Known CVEs, Install scripts, Dependency health and 12 more. Endpoint Security and Transport & Reachability do not apply to a PyPI package, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.