# GhostPaw Affinity (npm · @ghostpaw/affinity)

Local relationship model and social CRM for contacts, relationships, evidence, and commitments.

- Trust score: 58/100 (low)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-24

## Components

- npm · `@ghostpaw/affinity`: 58/100 (this document), [markdown](https://verifymcp.io/servers/ghostpawjs-affinity/ghostpaw-affinity.md), [page](https://verifymcp.io/servers/ghostpawjs-affinity/ghostpaw-affinity)

## Channel facts

- Registry: `npm`
- Package: `@ghostpaw/affinity`
- Version: `0.3.0`
- 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-10-24.

- **Supply Chain Security**: 50/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - No production dependencies, so there is no dependency health to assess.
- **Provenance & Transparency**: 71/100
  - Repository check failed: the declared repository URL redirects; it must resolve directly.
  - Cryptographically verified build provenance (signed, bound to GhostPawJS/affinity).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 0 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 62/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 2344 tokens (~195/item across 12 items; 12 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **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 13 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).

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the GhostPaw Affinity MCP server?

GhostPaw Affinity runs locally as an npm package, launched with npx -y @ghostpaw/affinity. 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 ghostpawjs-affinity -- npx -y @ghostpaw/affinity
```

### Cursor

```json
{
  "mcpServers": {
    "ghostpawjs-affinity": {
      "command": "npx",
      "args": [
        "-y",
        "@ghostpaw/affinity"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "ghostpawjs-affinity": {
      "command": "npx",
      "args": [
        "-y",
        "@ghostpaw/affinity"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add ghostpawjs-affinity -- npx -y @ghostpaw/affinity
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ghostpawjs-affinity": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@ghostpaw/affinity"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add ghostpawjs-affinity --command npx --arg -y --arg @ghostpaw/affinity
```

### Hermes

```yaml
mcp_servers:
  ghostpawjs-affinity:
    command: "npx"
    args: ["-y", "@ghostpaw/affinity"]
```

### Netclaw

```json
{
  "McpServers": {
    "ghostpawjs-affinity": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "@ghostpaw/affinity"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add ghostpawjs-affinity -t stdio -c npx -a -y @ghostpaw/affinity
```

### Other

```json
{
  "mcpServers": {
    "ghostpawjs-affinity": {
      "command": "npx",
      "args": [
        "-y",
        "@ghostpaw/affinity"
      ]
    }
  }
}
```

## 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-10-24 (score 58)

First indexed and scored.

## MCP tools (12)

### `search_affinity` (~159 tokens)

Search contacts by name or identity, including exact natural-key lookups like email-style identifiers.

Use when: Use this when you want to find contacts from free text or a known routing identity such as an email or URL-like handle.
Not for: Do not use this when you already know the exact contact you want to inspect in depth.

Input parameters:

- `includeDormant` (boolean): Whether dormant contacts are included.
- `includeOwner` (boolean): Whether owner contacts are included.
- `kind` (string): Optional contact kind filter.
- `lifecycleState` (string): Optional lifecycle state filter.
- `limit` (integer): Optional result limit.
- `offset` (integer): Optional result offset.
- `query` (string, required): Free-text or natural-key query.

### `review_affinity` (~371 tokens)

Review one affinity surface such as contacts, journals, link queues, commitments, dates, graph state, or merge history.

Use when: Use this when you want a dashboard-style list or review view instead of inspecting one exact item.
Not for: Do not use this when you already know the exact contact or link you want to inspect in depth.

Input parameters:

- `commitmentType` (string): Optional commitment type filter.
- `contact` (object): Optional target contact locator.
- `contactIds` (array): Optional contact-id subset.
- `eventTypes` (array): Optional event-type filter.
- `exactOnly` (boolean): Whether duplicate review is exact-only.
- `horizonDays` (integer): Optional horizon-days filter.
- `includeArchived` (boolean): Whether archived links are included.
- `includeDismissed` (boolean): Whether dismissed pairs are included in duplicate review (marked with dismissed flag).
- `includeDormant` (boolean): Whether dormant rows are included.
- `includeObserved` (boolean): Whether observed links are included.
- `includeOwner` (boolean): Whether owner contacts are included.
- `kind` (string): Optional contact kind or link kind filter, depending on the view.
- `lifecycleState` (string): Optional contact lifecycle-state filter.
- `limit` (integer): Optional result limit.
- `link` (object): Optional target link locator.
- `linkState` (string): Optional link state filter.
- `minScore` (number): Optional duplicate minimum score.
- `momentKind` (string): Optional moment kind filter.
- `offset` (integer): Optional result offset.
- `recurrenceKind` (string): Optional recurrence-kind filter.
- `since` (integer): Optional lower timestamp bound.
- `until` (integer): Optional upper timestamp bound.
- `view` (string, required): Which review surface to return.

### `inspect_affinity_item` (~145 tokens)

Inspect one exact affinity item such as the owner profile, a contact profile, or one link detail.

Use when: Use this when you already know the exact item you want to inspect in depth.
Not for: Do not use this for search-style discovery or dashboard-like list reviews.

Input parameters:

- `contact` (object): Target contact. Required when kind=contact_profile. Provide contactId or identity.
- `kind` (string, required): What to inspect.
- `link` (object): Target link. Required when kind=link. Provide linkId or endpoints.
- `recentEventsLimit` (integer): Optional recent-events cap.
- `topLinksLimit` (integer): Optional top-links cap.

### `manage_contact` (~164 tokens)

Create a contact, revise one contact's core fields, or change lifecycle state. ALWAYS search_affinity first before creating — duplicates corrupt the graph.

Use when: Use this for contact creation and lifecycle-safe contact maintenance.
Not for: Do not use this for identities, links, attributes, or merges.

Input parameters:

- `action` (string, required): Operation to perform.
- `contact` (object): Target contact. Required when action=revise or set_lifecycle. Provide contactId or identity.
- `input` (object): New contact payload. Required when action=create.
- `lifecycleState` (string): Target lifecycle state. Required when action=set_lifecycle.
- `options` (object): Optional lifecycle metadata.
- `patch` (object): Allowed contact patch. Required when action=revise.

### `merge_contacts` (~108 tokens)

Merge one loser contact into one winner contact using explicit contact locators.

Use when: Use this only when two contacts are confirmed duplicates and the system should consolidate them.
Not for: Do not use this for routine contact edits or identity cleanup.

Input parameters:

- `loser` (object, required): Loser contact. Provide contactId or identity.
- `now` (integer): Optional merge timestamp.
- `reasonSummary` (string): Optional merge reason.
- `winner` (object, required): Winner contact. Provide contactId or identity.

### `manage_duplicate_dismissal` (~129 tokens)

Dismiss or un-dismiss a duplicate candidate pair so it does not resurface in listDuplicateCandidates.

Use when: Use dismiss after confirming two contacts are different people (not duplicates). Use undismiss to re-surface a pair for re-evaluation.
Not for: Do not use this to merge contacts — use merge_contacts for confirmed duplicates.

Input parameters:

- `action` (string, required): Action to perform.
- `left` (object, required): Left contact. Provide contactId or identity.
- `reason`: Optional reason for the dismissal.
- `right` (object, required): Right contact. Provide contactId or identity.

### `manage_identity` (~206 tokens)

Add, revise, verify, or remove one routing identity on a contact. Use this for emails, phone numbers, social handles, and URLs — anything that could locate a person. Do not use manage_attribute for these.

Use when: Use this for contact identity management such as email, handle, or phone routing keys.
Not for: Do not use this for contact core fields, links, or attributes.

Input parameters:

- `action` (string, required): Operation to perform.
- `contact` (object): Target contact. Required when action=add. Provide contactId or identity.
- `identityId` (integer): Identity id. Required when action=revise, verify, or remove.
- `input` (object): New identity payload. Required when action=add.
- `patch` (object): Identity patch. Required when action=revise.
- `removedAt` (integer): Removal timestamp. Optional for action=remove.
- `verifiedAt` (integer): Verification timestamp. Optional for action=verify.

### `manage_relationship` (~391 tokens)

Seed social links, revise bond and state, and manage structural ties. Seed a link as soon as a relationship is mentioned — do not wait for repeated evidence.

Use when: Use this for direct relationship modeling and link-state changes.
Not for: Do not use this for recording social evidence or resolving commitments.

Input parameters:

- `action` (string, required): Operation to perform.
- `bond`: Bond text. Required when action=revise_bond. Null to clear.
- `from` (object): Source contact. Required when action=seed_social_link or set_structural_tie. Provide contactId or identity.
- `input` (object): Full payload for seed_social_link or set_structural_tie. Alternative to top-level kind/role.
- `kind` (string): Link kind. Required for seed_social_link and set_structural_tie. Can be passed here or inside input. For seed_social_link: personal, family, professional, romantic, care, service, observed, other_rel…
- `link` (object): Target link. Required when action=revise_bond, override_state, or remove_structural_tie. Provide linkId or endpoints.
- `options` (object): Optional metadata.
- `removedAt` (integer): Removal timestamp. Optional for action=remove_structural_tie.
- `role` (string): Optional role for seed_social_link or set_structural_tie. Can be passed here or inside input.
- `state` (string): Link state. Required when action=override_state.
- `to` (object): Target contact. Required when action=seed_social_link or set_structural_tie. Provide contactId or identity.

### `record_event` (~119 tokens)

Record one social event such as an interaction, observation, milestone, or transaction. For interactions, milestones, and transactions the owner contact is auto-injected into participants if missing. Observations may omit the owner when recording third-party evidence.

Use when: Use this when you are capturing something that happened in the relationship graph.
Not for: Do not use this for commitments, date anchors, or direct relationship state overrides.

Input parameters:

- `input` (object, required): Event payload. Always required. Interaction events also require `type`.
- `kind` (string, required): Event kind.

### `manage_commitment` (~139 tokens)

Record or resolve one commitment such as a promise or agreement. The owner contact is auto-injected into participants if missing.

Use when: Use this when the work is specifically about a commitment lifecycle rather than a general event.
Not for: Do not use this for ordinary interactions or direct relationship state changes.

Input parameters:

- `action` (string, required): Operation to perform.
- `commitmentEventId` (integer): Commitment event id. Required when action=resolve.
- `input` (object): Commitment payload. Required when action=record.
- `options` (object): Optional metadata.
- `resolution` (string): How the commitment was resolved. Required when action=resolve.

### `manage_date_anchor` (~165 tokens)

Add, revise, or remove recurring date anchors on contacts or links. Use this for birthdays, anniversaries, and yearly events — not manage_attribute.

Use when: Use this for birthdays, anniversaries, renewals, memorials, and other recurring anchors.
Not for: Do not use this for one-off events or relationship state changes.

Input parameters:

- `action` (string, required): Operation to perform.
- `anchorEventId` (integer): Anchor event id. Required when action=revise or remove.
- `input` (object): Date anchor payload. Required when action=add.
- `options` (object): Optional metadata.
- `patch` (object): Anchor patch. Required when action=revise.
- `removedAt` (integer): Removal timestamp. Optional for action=remove.

### `manage_attribute` (~179 tokens)

Set, unset, or replace custom metadata attributes on contacts and links. For emails, phones, handles, and URLs use manage_identity instead — those are routing keys, not attributes.

Use when: Use this for metadata such as tags, notes, or small labeled facts attached to a contact or link.
Not for: Do not use this for core contact fields, identities, or direct relationship mechanics.

Input parameters:

- `action` (string, required): Operation to perform.
- `entries` (array): Key-value map to replace all attributes. Required when action=replace.
- `name` (string): Attribute name. Required when action=set or unset.
- `removedAt` (integer): Removal timestamp. Optional for action=unset.
- `target` (object): Attribute target. Always required.
- `value`: Attribute value. Required when action=set. Null for presence/tag semantics.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/ghostpawjs-affinity/ghostpaw-affinity#diagnostics

## Score history

- 2026-10-24: 58

## Common questions

### What is the GhostPaw Affinity MCP server?

GhostPaw Affinity is an MCP server listed in the public MCP registry as io.github.GhostPawJS/affinity. Local relationship model and social CRM for contacts, relationships, evidence, and commitments. This page covers its npm package (@ghostpaw/affinity).

### Is the GhostPaw Affinity MCP server safe to use?

GhostPaw Affinity scores 58 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 24 October 2026. It declares no install or post-install scripts. 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 GhostPaw Affinity MCP server expose?

GhostPaw Affinity exposes 12 tools: search_affinity, review_affinity, inspect_affinity_item, manage_contact, merge_contacts, and 7 more. Their descriptions and schemas cost roughly 2,275 tokens of context every time the server is loaded.

### Is the GhostPaw Affinity MCP server still maintained?

GhostPaw Affinity is still listed as active in the MCP registry. We last reached this channel on 24 October 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 GhostPaw Affinity MCP server under?

GhostPaw Affinity declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- npm package: https://www.npmjs.com/package/@ghostpaw/affinity
- Socket report: https://socket.dev/npm/package/@ghostpaw/affinity
- Changelog RSS feed: https://verifymcp.io/servers/ghostpawjs-affinity/ghostpaw-affinity.xml
- Changelog JSON feed: https://verifymcp.io/servers/ghostpawjs-affinity/ghostpaw-affinity.json
- HTML version of this page: https://verifymcp.io/servers/ghostpawjs-affinity/ghostpaw-affinity
