People Context

io.github.JinyangWang27由 GitHub 帳號 JinyangWang27 發布v1.5.0更新於 Nov 7, 2026

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

已驗證STDIO僅桌面效率與工作流知識與記憶

概覽

AI 產生的概覽

本地優先的 MCP 伺服器,讓助理持久記住你生活中的人:身分、關係、事實與溝通偏好。

可以做什麼
  • 解析姓名、暱稱與別名,回傳排序後的候選人,並搜尋或瀏覽已存人物
  • 讀取單人有界上下文、時間軸、關係圖譜、最短路徑連結與共同群組關聯
  • 記錄人物、別名、關係、所屬機構、事實、觀察、特質、互動與群組,並支援更正與取代
  • 管理提醒、後續追蹤、生日與近期日期,並提供溝通建議與已儲存的溝通理念
  • 暫存匯入或由助理擷取的候選資料供後續審核,合併重複人物或徹底刪除紀錄
適用情境
適合希望助理記住某人是誰、你如何認識對方、上次約定了什麼,用於會前準備、後續追蹤、引薦與溝通建議。也適合偏好單一本地資料庫而非廠商端助理記憶的使用者。
執行需求
以本地 stdio 程序執行;README 要求 Python 3.11+ 與 uv,透過 uvx 啟動。日常使用不需帳號、API 金鑰或網路存取。選用功能:語意搜尋需本地語意索引;靜態加密需 SQLCipher,金鑰來自環境變數 PEOPLE_CONTEXT_DB_KEY。
安裝前請注意
資料庫預設為明文 SQLite,僅靠檔案權限保護,建議搭配全碟加密或啟用選用加密。它儲存關於他人的個人資料,包含敏感紀錄;寫入有稽核,forget 為徹底刪除。匯入與助理擷取的資料會先暫存待你審核,不會自動提交。選用的本機回環 HTTP 模式無身分驗證,僅限本機。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 People Context,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

people-context

English | 简体中文

Your agent already remembers your codebase. Now it can remember your people.

people-context is a local-first MCP server and CLI that gives AI agents durable memory about the people in your life: who someone is, how you know them, what you last agreed, and how they like to be talked to. One SQLite file on your machine. No account, no cloud, no network calls.

[CI] [codecov] [OpenSSF Scorecard] [OpenSSF Best Practices] [PyPI] [PyPI downloads] [Python] [License] [HOL Guard]

[pctx demo: seed a fictional dataset, list people, and print a brief]

Why

Ask an assistant "how should I approach Priya about the reporting delay?" and it has nothing: it does not know which Priya, that she is your counterpart at a partner org, that you agreed a new deadline last week, or that she prefers a short email over a call. That knowledge lives in your head, your inbox, and a notes file the agent cannot see.

people-context keeps it in one place the agent can query through narrow tools:

  • Who is this? Explainable name resolution over names, nicknames, aliases, and handles. Two Priyas come back as two candidates with a match reason, never a silent guess.
  • What do I know? Relationships, organisations and roles, durable facts, concise interaction summaries, traits, reminders, and a per-person timeline, each disclosed only as far as the request needs.
  • How do I talk to them? Communication guidance grounded in recorded traits, past friction, open follow-ups, and your own written philosophy.
  • Who has gone quiet? Stale-relationship and upcoming-date reports over what is already stored.
  • Get data in safely. Email, mbox, vCard, calendar, LinkedIn, Outlook, and WhatsApp exports are staged as reviewable candidates. You approve what gets recorded; raw source content is never kept.

It is opinionated about trust: writes are audited, forget is a real delete, sensitive records sit behind an operator-only gate that a prompt cannot open, and ordinary commands never touch the network.

Demo

A packaged fictional dataset is the fastest way to see identity resolution, graph traversal, and bounded context without touching real data:

bash
uvx --from people-context pctx demo --reset

The demo always writes its own dedicated database at {XDG_DATA_HOME or ~/.local/share}/people-context/demo.db. It ignores --db, PEOPLE_CONTEXT_DB, the config file, and --reset replaces only that file plus its -wal/-shm companions, so a real database is never read or modified. Seeding writes audited fictional people, handles, affiliations, facts, interactions, and a connected relationship graph, then prints the path-targeted server command and concrete tool calls that use the ids it just created:

text
Demo database: /home/you/.local/share/people-context/demo.dbStart MCP server: people-context-mcp --db /home/you/.local/share/people-context/demo.dbresolve_person {"query": "Amina Hassan"}get_relationship_graph {"person_id": "<amina-id>", "depth": 2}find_connection {"person_a": "<self-id>", "person_b": "<sofia-id>"}

Person ids are generated per seed, so the printed values differ from the placeholders above. Start the printed server command in an MCP client and run the printed calls verbatim. See docs/cli.md.

Quick start

Requires Python 3.11+ and uv. Pick your client; each is one step.

Claude Code
bash
claude plugin marketplace add JinyangWang27/people-contextclaude plugin install people-context@people-context-plugins

Restart Claude Code or run /reload-plugins. You get the server plus /people-context:who, /people-context:remember, and /people-context:reminders. Details: docs/claude-code-plugin.md.

Claude Desktop

Download people-context.mcpb from the latest release and open it. Claude Desktop installs the pinned release with its own uv runtime. Details: docs/desktop-and-editors.md.

Codex
bash
codex plugin marketplace add JinyangWang27/people-contextcodex plugin add people-context@people-context-plugins

Start a new Codex session. Details: docs/codex-plugin.md.

Cursor, Windsurf, VS Code, or any MCP client

Add the stdio server to your client's MCP config (.cursor/mcp.json, ~/.codeium/windsurf/mcp_config.json, .vscode/mcp.json, ...):

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

Or let the CLI write it: uvx --from people-context pctx setup cursor (also windsurf, vscode, claude-desktop; add --dry-run to preview). VS Code uses a servers key with "type": "stdio". Per-editor snippets: docs/desktop-and-editors.md.

OpenClaw
bash
openclaw plugins install clawhub:openclaw-plugin-people-context

The native plugin talks to the opt-in loopback HTTP server. Details: docs/openclaw-plugin.md.

CLI only
bash
uv tool install people-contextpctx init        # seed your own record, optionally import a vCard, then connect a clientpctx --help

people-context and people-context-mcp are the server commands; pctx is the human-operated CLI.

Then try, in your agent:

Who is Amina?

Remember that Amina from Open City Lab prefers short emails and hates surprise calls.

What should I know before my meeting with Daniel tomorrow?

The second one is a single remember tool call: the name is resolved, the person is created only if nobody matches, and the affiliation and preference are recorded in one audited transaction. Ambiguous names come back as candidates, never a guess.

Or, without an agent: pctx remember "Amina Hassan" "prefers short emails" --org "Open City Lab" and pctx brief "Amina Hassan". Five worked scenarios live in docs/use-cases.

Review and edit in your browser

Prefer a table to a terminal? pctx browse --open opens a local page over the same database:

  • browse people and open one person's brief;
  • add, correct, or remove a person's aliases and email addresses;
  • correct an affiliation, fact, trait, or reminder in place, with the before and after kept in the audit log;
  • review a staged import batch person by person, edit its candidates, then withdraw or commit them.

It binds 127.0.0.1 only, every request needs the per-launch token printed in its URL, and every write goes through the same audited use cases as the CLI and MCP tools. Sensitive records stay hidden unless the operator enables them. It runs until you press Done or Ctrl-C. See docs/cli.md.

What it remembers, and what it never does

It remembersIt never does
Names, nicknames, aliases, and handlesUpload anything, anywhere
Relationships with a canonical, extensible vocabularyStore raw imported emails, chats, or files
Organisations, roles, and time-bounded affiliationsLet a model enable sensitive disclosure or full export
Durable facts, observations, and traits with evidenceCommit imported or agent-extracted data without your review
Concise interaction summaries and a per-person timelineLog private values or keep a soft-deleted copy after forget
Reminders, follow-ups, and your communication philosophyMake a network request outside pctx reindex --semantic

How it compares

people-contextAssistant memory (ChatGPT, Claude)Memory platforms (Mem0 and similar)
Where data livesOne SQLite file you ownVendor accountVendor platform or your own deployment
Works offlineYesNoSelf-hosted only
Knows people as first-class recordsIdentity, relationships, roles, graph, guidanceFree-text notesFree-text or vector memories
Explains a matchRanked candidates with a reason; ambiguity is surfacedNoSimilarity score
Import review gateStage, review, commitn/aAutomatic extraction
DeletionHard delete plus audit redaction in one transactionRequest to vendorAPI delete
Backup and movepctx sync push / pull bundlen/aDeployment-specific

The dated, sourced version with vendor documentation links is in docs/privacy-and-safety.md.

Security model

This project executes local Python with the launching user's filesystem permissions. Ordinary MCP discovery excludes elevated sensitive context and full export. Operator-gated tools require process environment flags; models cannot enable them through arguments. Vault export is intentionally CLI-only.

The database is plaintext SQLite by default. On Unix-like systems a new one is created 0600, so other local accounts cannot read it. That is a boundary between accounts, not encryption, so pair it with full-disk encryption or opt into SQLCipher at-rest encryption (uv sync --extra encrypted, key read only from PEOPLE_CONTEXT_DB_KEY). See database file permissions and optional at-rest encryption.

Going further

  • Loopback HTTP for clients that cannot spawn stdio: people-context-mcp --http --host 127.0.0.1 --port 8765. Unauthenticated and local-only by design; prefer stdio. See docs/cli.md.
  • Semantic search: uv sync --extra semantic && pctx reindex --semantic downloads a pinned multilingual Model2Vec model once; server startup and search stay cache-only.
  • Obsidian: pctx export-vault --output ~/PeopleVault writes a deterministic, browsable vault, and a read-only Obsidian plugin renders live briefs. See docs/obsidian-plugin.md.
  • Import: pctx import stage SOURCE PATH then review and commit, over email, mbox, vCard, .ics, LinkedIn, Outlook, and WhatsApp exports. Agents can stage extracted candidates the same way. See docs/import.md.
  • Local browser: pctx browse --open serves a loopback-only, token-guarded page to browse people, edit their aliases, correct affiliations, facts, traits, and reminders, and review, edit, and commit staged import batches. See Review and edit in your browser.
  • Groups: record classes, teams, clubs, and households with pctx group, then ask how two people know each other with pctx group shared A B. See docs/shared-connections-examples.md.
  • Reports and maintenance: pctx stale, pctx upcoming, pctx timeline, pctx doctor, pctx stats.
  • Backup and second device: pctx sync push --output DIR and pctx sync pull --input PATH.
  • Docker: docker run --rm -i -v people-context-data:/data ghcr.io/jinyangwang27/people-context:latest. A convenience image, not a sandbox. See docs/docker.md.
  • Database location: --db, then PEOPLE_CONTEXT_DB, then the XDG config file, then the shared ~/.pctx/people.db. Inspect with pctx db-path -v.

The full command reference is in docs/cli.md; the MCP tool inventory and response contracts are in docs/mcp-interface.md; what stays stable across releases is in docs/compatibility.md.

Architecture

The codebase follows ports and adapters:

text
adapters (SQLite, MCP, filesystem, imports, CLI)        ↓ implementports (narrow Protocols)        ↑ used byapp (use cases and policy)        ↓ operates ondomain (entities and values)

Dependencies point inward. Vocabulary normalization and graph caps live in app/domain; recursive SQL and file writing live in adapters. One composition root wires both stdio and HTTP. See docs/architecture.md.

Documentation

DocumentContents
docs/architecture.mdLayering, dependency rule, entrypoint wiring
docs/data-model.mdSchema, migrations, and perspective display_type
docs/relationship-graph.mdVocabulary, normalization, perspective, traversal, curation
docs/identity-resolution.mdResolution stages, ambiguity, and why transliterations are stored aliases
docs/communication-guidance.mdCommunication signals and the coaching workflow
docs/vault-export.mdLayout, marker safety, determinism, sensitivity
docs/mcp-interface.mdMCP tools and stable response contracts
docs/compatibility.mdWhat stays stable across releases for MCP, DB, CLI, and JSON
docs/cli.mdCLI commands and DB resolution
docs/import.mdImport sources, staging, review, and commit
docs/design/sync.mdSync design and delivered local foundations
docs/releasing.mdPyPI trusted publishing, Codecov, and release procedure
docs/mcp-registry.mdMCP Registry namespace, server.json, and community-directory submission matrix
docs/distribution-checklist.mdAccount-owner walkthrough: Registry publish, directories, awesome lists, Desktop directory, Obsidian
docs/desktop-and-editors.mdNative-UV MCPB Desktop bundle and Cursor/Windsurf/VS Code snippets
docs/docker.mdOptional non-root stdio Docker image, data volume, and GHCR publishing
docs/claude-code-plugin.mdClaude Code install, runtime, privacy, validation, and publishing
docs/codex-plugin.mdCodex install, runtime, privacy, validation, and publishing
docs/openclaw-plugin.mdOpenClaw install, runtime, privacy, validation, and ClawHub publishing
docs/obsidian-plugin.mdObsidian read-only panes, subprocess safety, encryption, and mirrored releases
docs/privacy-and-safety.mdDisclosure, audit, forget, threat model
docs/use-casesNarrative recipes for onboarding, meeting prep, follow-up, migration, and auditing
docs/evals.mdEvaluation harness, fixed tasks, scoring rules, and dated recorded results
coaching, transcript, and shared-connection examplesFictional worked scenarios with review rubrics
docs/roadmap.mdDelivered milestones and remaining candidates

Contributing

Issues and pull requests are welcome; see CONTRIBUTING.md for the architecture rules, validation commands, and a list of good first issues. Questions and show-and-tell go to Discussions.

If people-context is useful to you, a star helps other people find it.

License

MIT. See LICENSE.

來源:README.md,提交 1030868

工具

44

resolve_person

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

輸入參數hintslimitquery必填

get_person_context

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.

輸入參數personpurposemax_itemsperson_idinclude_communication

search_people

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.

輸入參數limitquery必填

remember_person

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.

輸入參數name必填sourcealiasesis_selfsummary

remember

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.

輸入參數orgkindnoteroleperson必填sourcepredicateoccurred_atsensitivityrelationshiptrait_category

get_communication_guidance

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.

輸入參數personperson_idsituation

set_communication_philosophy

Store communication philosophy verbatim while auditing lengths only.

輸入參數text必填

list_reminders

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.

輸入參數personstatusperson_iddue_before

set_reminder

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

輸入參數kind必填text必填due_atperson_id必填recurrence

complete_reminder

Transition one active reminder to completed.

輸入參數reminder_id必填

add_alias

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.

輸入參數kindlangvalue必填scriptperson_id必填

remove_alias

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

輸入參數value必填person_id必填

update_alias

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.

輸入參數kindlangvalue必填scriptnew_valueperson_id必填

rename_person

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

輸入參數name必填person_id必填

set_relationship

Create a directed relationship between two existing people.

輸入參數type必填labelvalid_toobject_id必填confidencesubject_id必填valid_from

set_affiliation

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

輸入參數org必填role必填valid_toperson_id必填confidencevalid_from

record_fact

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.

輸入參數value必填valid_toperson_id必填predicate必填confidencevalid_fromsensitivity

record_observation

Record a subjective observation, separate from disclosed context.

輸入參數text必填person_id必填observed_atsensitivity

record_trait

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.

輸入參數value必填category必填person_id必填confidencesensitivityevidence_idsevidence_note

record_interaction

Record a concise interaction summary after validating all participants.

輸入參數channelsummary必填occurred_atsensitivityparticipant_ids必填

correct_record

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

輸入參數fields必填entity_id必填entity_type必填

supersede_fact

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.

輸入參數fact_id必填new_value必填confidencesensitivityeffective_from必填

get_relationship_graph

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.

輸入參數depthtypespersonperson_id

find_connection

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

輸入參數person_a必填person_b必填max_depth

create_group

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.

輸入參數kind必填name必填sensitivityorganization_id

add_group_membership

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.

輸入參數rolegroup_id必填valid_toperson_id必填confidencevalid_fromsensitivitytemporal_basis

close_group_membership

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.

輸入參數ended_on必填membership_id必填

find_groups

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.

輸入參數kindnamelimit

get_group

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

輸入參數limitgroup_id必填

list_group_memberships

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

輸入參數limitpersonperson_id

explain_shared_connections

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.

輸入參數limitperson_aperson_bperson_a_idperson_b_id

get_stale_relationships

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

輸入參數limitcategorythreshold_days

get_person_timeline

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.

輸入參數limitpersonperson_id

get_consolidation_context

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.

輸入參數limitpersonperson_id

upcoming_dates

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

輸入參數personperson_idwindow_days

merge_people

Merge a duplicate person into a primary person atomically.

輸入參數primary_id必填duplicate_id必填

forget

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

輸入參數scope必填target必填

import_content

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.

輸入參數pathforcedcontentself_sendersource_type必填

stage_candidates

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 o

輸入參數labelsource必填candidates必填source_kindcontent_digestexternal_source_idextraction_fingerprint

review_import

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.

輸入參數batch_id必填

amend_candidate

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.

輸入參數patch必填batch_id必填candidate_id必填expected_batch_digest

withdraw_candidates

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.

輸入參數batch_id必填candidate_ids必填expected_batch_digest

commit_import

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.

輸入參數batch_id必填accepted_ids必填expected_batch_digest

版本歷史

4
  1. v1.5.0最新Nov 6, 2026
  2. v1.4.0Oct 31, 2026
  3. v1.3.0Sep 22, 2026
  4. v1.2.1Sep 16, 2026

評分

已滿足適用檢查項的 90%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分
  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分