npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@reconcrap/people-network-memory

v0.1.0

Published

Local-first personal network memory MCP for OpenClaw and other MCP harnesses.

Readme

People Network Memory MCP

Local-first V1 scaffold for a personal social-memory MCP. The implementation keeps the product logic independent from Graphiti/MCP/OpenClaw so the core can be tested without external services.

Quick Commands

python -m pip install -e .
python -m unittest discover -s tests -v
people-memory start --test-mode --once
people-memory doctor --test-mode
people-memory load-fixtures --summary
people-memory eval-fixtures
people-memory eval-fixtures --failures-only --output .people-network-memory/eval-report.json
people-memory spike-graphiti
people-memory check-embedding
people-memory tool-schemas
people-memory smoke-graphiti --isolated
people-memory graphiti-gate --isolated --output .people-network-memory/graphiti-gate.json
people-memory index-graphiti --resume --limit 10 --output .people-network-memory/index-graphiti.json
people-memory graphiti-ladder --steps 1,3,10 --cumulative --output-dir .people-network-memory/test-artifacts/graphiti-ladder
people-memory smoke-openclaw
people-memory eval-harness-integration
people-memory release-check
people-memory eval-graphiti --isolated --max-interactions 3 --max-queries 3
people-memory install-openclaw --dry-run
people-memory list-reviews
people-memory backup --output .people-network-memory/backup.json
people-memory backup-archive --output .people-network-memory/backup.zip
people-memory restore --input .people-network-memory/backup.json

The base test suite uses unittest and does not require Graphiti, Docker, or a graph database:

python -m unittest discover -s tests -v
python -m people_network_memory.cli release-check
powershell -ExecutionPolicy Bypass -File .\scripts\run_tests_with_artifacts.ps1

The artifact runner writes command output, JSON reports, and a manifest with exit codes to .people-network-memory/test-artifacts/latest/ by default. That directory is ignored by git so local verification reports do not leak into the package.

Local Install

npm Install

The recommended end-user distribution path is the npm wrapper. It keeps the product code in Python, but gives OpenClaw users a familiar install/update surface:

npm install -g @reconcrap/people-network-memory
people-memory doctor --test-mode
people-memory install-openclaw --backend local_json
people-memory doctor --agent openclaw

The npm people-memory command lazily creates a private Python 3.11+ venv and installs this package into it. The default venv locations are:

  • Windows: %LOCALAPPDATA%\people-network-memory\npm-venv
  • macOS: ~/Library/Application Support/people-network-memory/npm-venv
  • Linux: ${XDG_DATA_HOME:-~/.local/share}/people-network-memory/npm-venv

Set PEOPLE_MEMORY_NPM_VENV to override that location, or PEOPLE_MEMORY_PYTHON to choose a specific Python command. For Graphiti extras, either run with --backend graphiti or set PEOPLE_MEMORY_NPM_EXTRAS=graphiti.

When install-openclaw is run through the npm command, the installer writes OpenClaw to launch the absolute Node executable plus the npm wrapper script. That keeps the MCP server independent of shell PATH differences between visible terminals and hidden OpenClaw gateway sessions on Windows and macOS.

Update flow:

npm update -g @reconcrap/people-network-memory
people-memory install-openclaw --backend local_json

Source Checkout Install

For a clean Windows checkout, use the bootstrap script. It creates .venv, installs the package, runs the test suite, runs doctor, and starts the MCP server once in test mode:

powershell -ExecutionPolicy Bypass -File .\scripts\install_windows.ps1

Install optional Graphiti/Kuzu dependencies as part of the same flow:

powershell -ExecutionPolicy Bypass -File .\scripts\install_windows.ps1 -Graphiti

To also wire OpenClaw to a managed bootstrap command:

powershell -ExecutionPolicy Bypass -File .\scripts\install_windows.ps1 -OpenClaw

The managed OpenClaw entry starts scripts/people_memory_bootstrap.py. On each server start, that bootstrapper checks for a local .venv, creates it if missing, installs or updates dependencies when pyproject.toml changes, then launches the MCP server from the venv. This lets an AI harness repair missing Python package dependencies without the user manually running pip.

For a trusted git checkout, add -AutoUpdate to let the bootstrapper run git pull --ff-only before dependency checks:

powershell -ExecutionPolicy Bypass -File .\scripts\install_windows.ps1 -OpenClaw -AutoUpdate

This still requires a system Python 3.11+ command to exist. On Windows the managed entry uses py -3.11; on macOS/Linux it uses python3.

For Graphiti-backed OpenClaw, first configure the embedding and LLM environment variables in OpenClaw or the launching shell, then run:

powershell -ExecutionPolicy Bypass -File .\scripts\install_windows.ps1 -Graphiti -OpenClaw -Backend graphiti

The bootstrap script does not write API keys or model credentials.

For the current Windows development setup, the live Graphiti artifact run can reuse Volcengine/Doubao embeddings and the LLM values from the Liepin screening config:

$env:VOLCENGINE_API_KEY="<secret>"
powershell -ExecutionPolicy Bypass -File .\scripts\run_graphiti_live_from_liepin.ps1

That wrapper maps the embedding endpoint/model to Volcengine, reads baseUrl/model/credential from ~/.liepin-recommend-mcp/screening-config.json for the LLM provider, disables Graphiti telemetry, and stores verification artifacts under .people-network-memory/test-artifacts/graphiti-live/.

spike-graphiti is the prerequisite gate. graphiti-gate is the promotion gate: it keeps local_json as the default, runs live embedding plus a full Graphiti/Kuzu fixture eval when providers are configured, and reports whether Graphiti/Kuzu is ready to become the recommended recall backend.

Backends

  • local_json is the default non-test backend and persists to ~/.people-network-memory/people-memory.json.
  • inmemory is used for tests and quick smoke checks.
  • graphiti is gated behind people-memory graphiti-gate; do not treat it as the recommended recall backend until that command passes with live providers.
  • For local Graphiti, prefer embedded Kuzu first. It avoids Docker and server setup.

Python 3.11 venv setup for Graphiti + Kuzu:

py -3.11 -m venv .venv
.\.venv\Scripts\python.exe -m pip install --upgrade pip
.\.venv\Scripts\python.exe -m pip install -e ".[graphiti]"
.\.venv\Scripts\python.exe -m people_network_memory.cli spike-graphiti
.\.venv\Scripts\python.exe -m people_network_memory.cli smoke-graphiti --isolated
.\.venv\Scripts\python.exe -m people_network_memory.cli eval-graphiti --isolated --max-interactions 3 --max-queries 3 --output .people-network-memory/graphiti-eval.json
.\.venv\Scripts\python.exe -m people_network_memory.cli graphiti-gate --isolated --output .people-network-memory/graphiti-gate.json

Eval reports include Recall@3, Recall@5, per-category breakdowns, evidence coverage, no-result counts, sensitive-leak counts, and optional case-level diagnostics. When --max-interactions is used, evals default to queries whose source fixture interactions were ingested. Add --all-queries only when you intentionally want to test missing/unanswerable targets.

Case-level diagnostics include the query, expected people/terms, matched and missed expected values, and the actual top retrieval results with evidence source text/date. The artifact runner saves these full case diagnostics by default in eval-fixtures.json; Graphiti live artifacts save them in graphiti-gate.json and graphiti-eval.json.

eval-graphiti without --max-* runs the full fixture set. The small bounded form above is only a quick smoke check. graphiti-gate uses the full fixture set by default and requires Recall@3 >= 70%, Recall@5 >= 85%, complete returned evidence, zero sensitive leaks, at least 40 checked queries, and at least 60 ingested interactions unless you intentionally bound the run.

Graphiti indexing should be treated as resumable background work. Local JSON is the canonical capture store; index-graphiti reads saved local interactions and adds compact text episodes into Graphiti/Kuzu one by one, saving progress after each successful episode:

people-memory index-graphiti --resume --limit 10 --output .people-network-memory/index-graphiti.json
people-memory index-graphiti --resume --limit 10

Use the ingestion ladder to find the point where the live Graphiti/LLM path slows down or fails. Each step writes a separate JSON artifact:

people-memory graphiti-ladder --steps 1,3,10,20,40,90 --output-dir .people-network-memory/test-artifacts/graphiti-ladder

Add --cumulative when testing larger rungs. It reuses one artifact-local Graphiti/Kuzu store plus one state file, so a 20,40,90 run indexes only the additional interactions at each step and leaves the test database under the artifact directory:

people-memory graphiti-ladder --steps 20,40,90 --cumulative --output-dir .people-network-memory/test-artifacts/graphiti-ladder-cumulative

If that command is interrupted, rerun it with --resume-cumulative against the same output directory to keep the existing state file:

people-memory graphiti-ladder --steps 20,40,90 --cumulative --resume-cumulative --output-dir .people-network-memory/test-artifacts/graphiti-ladder-cumulative

For slow live providers, raise the per-episode timeout without changing code:

$env:PEOPLE_MEMORY_GRAPHITI_ADD_TIMEOUT_SECONDS="600"
$env:PEOPLE_MEMORY_GRAPHITI_RETRY_ATTEMPTS="4"
people-memory graphiti-ladder --steps 20,40,90 --cumulative --resume-cumulative --output-dir .people-network-memory/test-artifacts/graphiti-ladder-cumulative

Bounded ladder runs are diagnostics only; they cannot promote Graphiti/Kuzu to the recommended backend.

After an existing Graphiti/Kuzu fixture graph has been indexed, evaluate search quality without re-ingesting episodes:

people-memory eval-graphiti-search --data-path .people-network-memory/test-artifacts/graphiti-ladder-cumulative/cumulative-store/projection --graphiti-kuzu-path .people-network-memory/test-artifacts/graphiti-ladder-cumulative/cumulative-store/graphiti.kuzu --indexed-interactions 90 --output .people-network-memory/test-artifacts/graphiti-search/eval.json

If the graph was populated by the fixture ladder before the projection cache was hydrated, rebuild that local cache without calling Graphiti again:

people-memory hydrate-graphiti-cache --data-path .people-network-memory/test-artifacts/graphiti-ladder-cumulative/cumulative-store/projection --fixture-seed 42 --limit 90 --output .people-network-memory/test-artifacts/graphiti-search/cache-hydration.json

Build the optional local semantic sidecar over the hydrated projection cache:

people-memory build-semantic-cache --data-path .people-network-memory/test-artifacts/graphiti-ladder-cumulative/cumulative-store/projection --limit 90 --reset --output .people-network-memory/test-artifacts/graphiti-search/semantic-cache.json

With that sidecar present, Graphiti retrieval merges three sources: Graphiti graph search, local semantic interaction search, and local token/event search. The strict eval report checks intent-aware matches, not just loose token overlap: who mentioned X must return the speaker, promise queries must return follow-up items, and profile queries must combine the requested terms in one returned result. For intentionally broad fixture queries, the report also keeps expected_person_rank as a diagnostic because several mock people may satisfy the same place/topic or company/topic query.

Optional LLM Retrieval Judge

The default retrieval path is deterministic and fully testable. For a final quality pass, enable the optional OpenAI-compatible LLM judge:

$env:PEOPLE_MEMORY_RETRIEVAL_JUDGE="llm"
$env:PEOPLE_MEMORY_RETRIEVAL_JUDGE_TIMEOUT_SECONDS="30"
$env:PEOPLE_MEMORY_LLM_BASE_URL="<base-url>"
$env:PEOPLE_MEMORY_LLM_MODEL="<model>"
$env:PEOPLE_MEMORY_LLM_API_KEY="<secret>"

When enabled, retrieve_network_context fetches a broader candidate set, asks the judge to rank only candidates that directly answer the query, and falls back to deterministic ranking if the judge fails or returns invalid JSON.

The intended harness split is hybrid:

  • This tool owns social-memory retrieval quality: query expansion, graph/semantic search, deterministic social-intent checks, optional LLM reranking, evidence, sensitivity policy, and stable person IDs.
  • The AI harness owns user-aware synthesis: applying its memory of the user's goals, style, preferences, and current constraints to the retrieved social evidence.
  • The OpenClaw skill instructs the harness to retrieve from this MCP first, treat returned people/network facts as source-backed evidence, then combine them with the harness's own user memory for final recommendations, briefs, drafts, or plans.

Run the deterministic harness integration eval to check that contract without needing a live AI harness:

people-memory eval-harness-integration --output .people-network-memory/harness-integration-eval.json

The eval seeds a small social graph and verifies planning, intro drafting, conflict resolution, missing-person evidence, and follow-up cases. Each case records the prompt, simulated harness memory, MCP tool calls, actual retrieval results, hydrated person cards when needed, and pass/fail checks for source boundaries.

LLM Ingestion Extractor

The capture path defaults to the OpenAI-compatible LLM extractor when usable, then falls back to deterministic normalization. This improves messier Chinese, alias, and bilingual social notes without making a fresh install depend on LLM credentials. To provide an LLM, set:

$env:PEOPLE_MEMORY_INGESTION_EXTRACTOR="llm"
$env:PEOPLE_MEMORY_INGESTION_EXTRACTOR_TIMEOUT_SECONDS="30"
$env:PEOPLE_MEMORY_LLM_BASE_URL="<base-url>"
$env:PEOPLE_MEMORY_LLM_MODEL="<model>"
$env:PEOPLE_MEMORY_LLM_API_KEY="<secret>"

The extractor proposes participants, aliases, topics, claims, relationships, and follow-ups from source_text. The application layer still preserves the original note as evidence, strips model-invented person_id values, applies the deterministic normalizer, and sends identity ambiguity to review instead of silently merging cards. If the extractor fails or returns invalid JSON, capture falls back to the deterministic rules.

To force deterministic-only capture:

$env:PEOPLE_MEMORY_INGESTION_EXTRACTOR="off"

OpenClaw installs default to PEOPLE_MEMORY_INGESTION_EXTRACTOR=llm. Use people-memory install-openclaw --ingestion-extractor off only when you want to disable the LLM extraction pass for that harness.

Embeddings

Local-first default recommendation:

$env:PEOPLE_MEMORY_EMBEDDING_PROVIDER="ollama"
$env:PEOPLE_MEMORY_EMBEDDING_BASE_URL="http://localhost:11434/v1"
$env:PEOPLE_MEMORY_EMBEDDING_MODEL="nomic-embed-text"
people-memory check-embedding

OpenAI-compatible cloud endpoints use the same command with:

$env:PEOPLE_MEMORY_EMBEDDING_PROVIDER="openai_compatible"
$env:PEOPLE_MEMORY_EMBEDDING_BASE_URL="https://ark.cn-beijing.volces.com/api/coding/v3"
$env:PEOPLE_MEMORY_EMBEDDING_MODEL="doubao-embedding-vision-251215"
$env:PEOPLE_MEMORY_EMBEDDING_API_KEY="<secret>"
people-memory check-embedding

Do not commit API keys or write them into config files.

Sensitivity Policy

Sensitivity labels such as sensitive and do_not_surface_unprompted are kept as metadata, but V1 defaults to personal surfacing because this is a private single-user memory tool.

$env:PEOPLE_MEMORY_SENSITIVITY_POLICY="personal"    # private recall includes sensitive context
$env:PEOPLE_MEMORY_SENSITIVITY_POLICY="strict"      # hide sensitive context unless explicitly requested
$env:PEOPLE_MEMORY_SENSITIVITY_POLICY="task_aware"  # include for private recall, hide for shareable output

The MCP retrieval tool also accepts sensitivity_policy, output_context, and the explicit include_sensitive override per request.

Graphiti also needs an LLM provider for episode extraction. Embeddings alone are enough for vector smoke checks, but not enough for live Graphiti ingestion. Some OpenAI-compatible gateways do not support response_format; leave PEOPLE_MEMORY_LLM_RESPONSE_FORMAT unset or set it to none for those providers. Use json_object or json_schema only when the provider explicitly supports that mode.

$env:PEOPLE_MEMORY_BACKEND="graphiti"
$env:PEOPLE_MEMORY_GRAPH_BACKEND="kuzu"
$env:PEOPLE_MEMORY_LLM_PROVIDER="openai_compatible"
$env:PEOPLE_MEMORY_LLM_BASE_URL="<base-url>"
$env:PEOPLE_MEMORY_LLM_MODEL="<model>"
$env:PEOPLE_MEMORY_LLM_API_KEY="<secret>"
$env:PEOPLE_MEMORY_LLM_RESPONSE_FORMAT="none"
.\.venv\Scripts\python.exe -m people_network_memory.cli smoke-graphiti --isolated

reset is intentionally guarded:

people-memory reset --confirm DELETE

It deletes only the configured local JSON data file for local_json.

Backup

Use JSON backup for portable person-card projection data:

people-memory backup --output .people-network-memory/backup.json
people-memory restore --input .people-network-memory/backup.json

Use archive backup when the backend has local storage beyond the projection cache. For graphiti + Kuzu, the archive includes projection.json and the configured Kuzu database directory:

people-memory backup-archive --backend graphiti --output .people-network-memory/graphiti-backup.zip
people-memory restore-archive --backend graphiti --input .people-network-memory/graphiti-backup.zip --confirm OVERWRITE

restore-archive requires explicit confirmation and rejects unsafe archive member paths.

Low-Friction Capture

The MCP tool accepts raw source_text first. If the harness can confidently extract structure, it should include it. If not, it can still send the original note and the server will conservatively normalize obvious people, places, topics, mentions, work/school facts, contacts, interests, and follow-ups.

Review Queue

Ambiguous identity matches are captured without blocking the original note. Use the review commands to clean them up later:

people-memory list-reviews
people-memory resolve-review --review-id review_0001 --source-person-id person_0003 --target-person-id alice
people-memory dismiss-review --review-id review_0002 --note "not enough information"

Resolving an identity review merges the source person into the target person, preserves aliases, interactions, facts, claims, follow-ups, relationships, and evidence, then marks the review item as resolved.

OpenClaw

Install or preview the OpenClaw adapter:

people-memory install-openclaw --dry-run
people-memory install-openclaw
people-memory install-openclaw --managed-bootstrap
people-memory doctor --agent openclaw
people-memory smoke-openclaw
people-memory eval-harness-integration

The installer updates only the people-network-memory MCP server entry in the active OpenClaw config. Current OpenClaw builds use ~/.openclaw/openclaw.json under mcp.servers; when that file exists the installer updates it, and also maintains the legacy/generic ~/.openclaw/mcp.json shape for older MCP harnesses. It preserves unrelated MCP servers and writes the mirrored skill to ~/.openclaw/skills/ppl/SKILL.md. The MCP server namespace remains people-network-memory for tool compatibility, but the user-facing OpenClaw slash trigger is /ppl; /people_network_memory and /people-network-memory remain accepted aliases for existing prompts. By default it uses the active Python executable with -m people_network_memory.cli start, so it does not require the people-memory console script to be on PATH. For end-user harness installs, prefer --managed-bootstrap: that stores a tiny stdlib launcher in the MCP command so the harness can recreate the venv and refresh Python dependencies automatically.

smoke-openclaw installs into a temporary OpenClaw home by default, checks the adapter config and skill text, verifies prompt-routing examples, and exercises the three public MCP workflows with the test backend.