# io.github.JinyangWang27/people-context (pypi · people-context)

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

- Trust score: 60/100 (medium)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-21

## Components

- pypi · `people-context`: 60/100 (this document), [markdown](https://verifymcp.io/servers/jinyangwang27-people-context/people-context.md), [page](https://verifymcp.io/servers/jinyangwang27-people-context/people-context)

## Channel facts

- Registry: `pypi`
- Package: `people-context`
- Version: `1.2.1`
- 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-09-21.

- **Supply Chain Security**: 50/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised native-build step with no shell scripting around it.
  - 1 of 31 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 35/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - License check failed: no license is declared.
  - Actively maintained (last published 6 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 79/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 5193 tokens (~126/item across 41 items; 39 tools + 2 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 60/100
  - Stability observed for 18 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 71/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.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 41 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## 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 people-context. 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 jinyangwang27-people-context -- uvx people-context
```

### Cursor

```json
{
  "mcpServers": {
    "jinyangwang27-people-context": {
      "command": "uvx",
      "args": [
        "people-context"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "jinyangwang27-people-context": {
      "command": "uvx",
      "args": [
        "people-context"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add jinyangwang27-people-context -- uvx people-context
```

### opencode

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

### OpenClaw

```bash
openclaw mcp add jinyangwang27-people-context --command uvx --arg people-context
```

### Hermes

```yaml
mcp_servers:
  jinyangwang27-people-context:
    command: "uvx"
    args: ["people-context"]
```

### Netclaw

```json
{
  "McpServers": {
    "jinyangwang27-people-context": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "people-context"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add jinyangwang27-people-context -t stdio -c uvx -a people-context
```

### Other

```json
{
  "mcpServers": {
    "jinyangwang27-people-context": {
      "command": "uvx",
      "args": [
        "people-context"
      ]
    }
  }
}
```

## 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-09-20 (score 60, +1)

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

### 2026-09-18 (score 59, +1)

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

### 2026-09-15 (score 58, +1)

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

### 2026-09-14 (score 57, 0)

- [functional regression] Schema quality: 4168 → 5193
- [functional] Package version: 1.2.0 → 1.2.1

### 2026-09-13 (score 57, 0)

- [security improvement] Malware scan: unverified → pass
- [functional] Package version: 1.1.1 → 1.2.0

### 2026-09-12 (score 57, +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-11 (score 56, +4)

- [functional improvement] Stability: unverified → 0.27

### 2026-09-09 (score 52, −15)

- [security regression] Malware scan: pass → unverified

## MCP tools (39)

### `resolve_person` (~153 tokens)

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

Input parameters:

- `hints`
- `limit` (integer)
- `query` (string, required)

### `get_person_context` (~167 tokens)

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.

Input parameters:

- `include_communication` (boolean)
- `max_items` (integer)
- `person`
- `person_id`
- `purpose`

### `search_people` (~66 tokens)

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.

Input parameters:

- `limit` (integer)
- `query` (string, required)

### `semantic_search` (~76 tokens)

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.

Input parameters:

- `kinds`
- `limit` (integer)
- `query` (string, required)

### `remember_person` (~145 tokens)

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.

Input parameters:

- `aliases`
- `is_self` (boolean)
- `name` (string, required)
- `source` (string)
- `summary`

### `remember` (~371 tokens)

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.

Input parameters:

- `kind` (string)
- `note`
- `occurred_at`
- `org`
- `person` (string, required)
- `predicate`
- `relationship`
- `role`
- `sensitivity`
- `source` (string)
- `trait_category`

### `get_communication_guidance` (~72 tokens)

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.

Input parameters:

- `person`
- `person_id`
- `situation`

### `set_communication_philosophy` (~29 tokens)

Store communication philosophy verbatim while auditing lengths only.

Input parameters:

- `text` (string, required)

### `list_reminders` (~73 tokens)

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.

Input parameters:

- `due_before`
- `person`
- `person_id`
- `status`

### `set_reminder` (~89 tokens)

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

Input parameters:

- `due_at`
- `kind` (required)
- `person_id` (string, required)
- `recurrence`
- `text` (string, required)

### `complete_reminder` (~24 tokens)

Transition one active reminder to completed.

Input parameters:

- `reminder_id` (string, required)

### `add_alias` (~111 tokens)

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.

Input parameters:

- `kind`
- `lang`
- `person_id` (string, required)
- `script`
- `value` (string, required)

### `set_relationship` (~62 tokens)

Create a directed relationship between two existing people.

Input parameters:

- `confidence`
- `label`
- `object_id` (string, required)
- `subject_id` (string, required)
- `type` (string, required)
- `valid_from`
- `valid_to`

### `set_affiliation` (~63 tokens)

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

Input parameters:

- `confidence`
- `org` (string, required)
- `person_id` (string, required)
- `role` (string, required)
- `valid_from`
- `valid_to`

### `record_fact` (~100 tokens)

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.

Input parameters:

- `confidence`
- `person_id` (string, required)
- `predicate` (string, required)
- `sensitivity`
- `valid_from`
- `valid_to`
- `value` (string, required)

### `record_observation` (~45 tokens)

Record a subjective observation, separate from disclosed context.

Input parameters:

- `observed_at`
- `person_id` (string, required)
- `sensitivity`
- `text` (string, required)

### `record_trait` (~116 tokens)

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.

Input parameters:

- `category` (required)
- `confidence`
- `evidence_ids`
- `evidence_note`
- `person_id` (string, required)
- `sensitivity`
- `value` (string, required)

### `record_interaction` (~50 tokens)

Record a concise interaction summary after validating all participants.

Input parameters:

- `channel`
- `occurred_at`
- `participant_ids` (array, required)
- `sensitivity`
- `summary` (string, required)

### `correct_record` (~44 tokens)

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

Input parameters:

- `entity_id` (string, required)
- `entity_type` (string, required)
- `fields` (object, required)

### `supersede_fact` (~186 tokens)

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.

Input parameters:

- `confidence`
- `effective_from` (string, required)
- `fact_id` (string, required)
- `new_value` (string, required)
- `sensitivity`

### `get_relationship_graph` (~69 tokens)

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.

Input parameters:

- `depth` (integer)
- `person`
- `person_id`
- `types`

### `find_connection` (~45 tokens)

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

Input parameters:

- `max_depth` (integer)
- `person_a` (string, required)
- `person_b` (string, required)

### `create_group` (~148 tokens)

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.

Input parameters:

- `kind` (required)
- `name` (string, required)
- `organization_id`
- `sensitivity`

### `add_group_membership` (~195 tokens)

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.

Input parameters:

- `confidence`
- `group_id` (string, required)
- `person_id` (string, required)
- `role`
- `sensitivity`
- `temporal_basis`
- `valid_from`
- `valid_to`

### `close_group_membership` (~101 tokens)

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.

Input parameters:

- `ended_on` (string, required)
- `membership_id` (string, required)

### `find_groups` (~96 tokens)

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.

Input parameters:

- `kind`
- `limit` (integer)
- `name`

### `get_group` (~81 tokens)

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

Input parameters:

- `group_id` (string, required)
- `limit` (integer)

### `list_group_memberships` (~87 tokens)

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

Input parameters:

- `limit` (integer)
- `person`
- `person_id`

### `explain_shared_connections` (~317 tokens)

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.

Input parameters:

- `limit` (integer)
- `person_a`
- `person_a_id`
- `person_b`
- `person_b_id`

### `get_stale_relationships` (~45 tokens)

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

Input parameters:

- `category`
- `limit` (integer)
- `threshold_days` (integer)

### `get_person_timeline` (~140 tokens)

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.

Input parameters:

- `limit` (integer)
- `person`
- `person_id`

### `get_consolidation_context` (~428 tokens)

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.

Input parameters:

- `limit` (integer)
- `person`
- `person_id`

### `upcoming_dates` (~62 tokens)

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

Input parameters:

- `person`
- `person_id`
- `window_days` (integer)

### `merge_people` (~35 tokens)

Merge a duplicate person into a primary person atomically.

Input parameters:

- `duplicate_id` (string, required)
- `primary_id` (string, required)

### `forget` (~33 tokens)

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

Input parameters:

- `scope` (string, required)
- `target` (string, required)

### `import_content` (~235 tokens)

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.

Input parameters:

- `content`
- `forced` (boolean)
- `path`
- `self_sender`
- `source_type` (string, required)

### `stage_candidates` (~617 tokens)

Stage agent-extracted people, interactions, affiliations, facts, observations, traits, and relationships.

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.

\`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, `.`, `_`, `-…

Input parameters:

- `candidates` (array, required)
- `content_digest`
- `external_source_id`
- `extraction_fingerprint`
- `label`
- `source` (string, required)
- `source_kind`

### `review_import` (~25 tokens)

Return staged candidates and statuses for one batch.

Input parameters:

- `batch_id` (string, required)

### `commit_import` (~36 tokens)

Commit accepted people and resolvable interactions idempotently.

Input parameters:

- `accepted_ids` (array, required)
- `batch_id` (string, required)

## Diagnostics

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

## Score history

- 2026-09-21: 60
- 2026-09-20: 60
- 2026-09-19: 59
- 2026-09-18: 59
- 2026-09-17: 58
- 2026-09-16: 58
- 2026-09-15: 58
- 2026-09-14: 57
- 2026-09-13: 57
- 2026-09-12: 57
- 2026-09-11: 56
- 2026-09-10: 52
- 2026-09-09: 52
- 2026-09-08: 67
- 2026-09-07: 52
- 2026-09-06: 67
- 2026-09-05: 67
- 2026-09-04: 67
- 2026-09-03: 52

## 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 60 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 21 September 2026. 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 39 tools: resolve_person, get_person_context, search_people, semantic_search, remember_person, and 34 more. Their descriptions and schemas cost roughly 4,837 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 21 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- PyPI project: https://pypi.org/project/people-context/
- Socket report: https://socket.dev/pypi/package/people-context
- Repository: https://github.com/JinyangWang27/people-context
- Changelog RSS feed: https://verifymcp.io/servers/jinyangwang27-people-context/people-context.xml
- Changelog JSON feed: https://verifymcp.io/servers/jinyangwang27-people-context/people-context.json
- HTML version of this page: https://verifymcp.io/servers/jinyangwang27-people-context/people-context
