# Moltline Recall

> A portable knowledge-graph memory you pass in and get back. No database. 4 of 6 free.

- name: com.moltlinestudio/recall
- version: 1.2.0
- connection class: R0 (autonomous)
- trust: 84/100 flags: duplicate-repo
- quality: 91/100 (strong)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/com.moltlinestudio%2Frecall
- tools: https://api.protogrid.dev/v1/servers/com.moltlinestudio%2Frecall/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "recall": {
      "type": "http",
      "url": "https://mcp.moltlinestudio.com/recall"
    }
  }
}
```


## Trust

- hygiene: 60
- liveness: 97
- freshness: 85
- provenance: 85
- drivers: +repository +dns-namespace +website +reachable +uptime-91% ~updated-41d-ago -duplicate-repo(22 names)
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 91/100 (strong)

### protocol: 75 (weight 25)

- warn `protocol.modern`: newest supported version is 2025-11-25; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
- n/a `protocol.stateless`: only applies to 2026-07-28 servers
- pass `protocol.transport`: streamable HTTP
- n/a `protocol.list_ttl`: only applies to 2026-07-28 servers

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 100 (weight 30)

- pass `tools.descriptions`: every tool has a description
- pass `tools.description_length`: descriptions are concise
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 6 of 6 tools declare readOnlyHint or destructiveHint
- pass `tools.directory_hints`: every tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
- pass `tools.token_cost`: about 2,344 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 100 (weight 15)

- pass `stability.changes`: no tool changes in 30 days
- pass `stability.rug_pull`: no tool changed its meaning under the same name

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 6, about 2,344 tokens to load them all
- tool set hash: 52efb74c2852a853f815ffb6670bf3e2
- badge: [![protogrid quality](https://protogrid.dev/badge/com.moltlinestudio/recall.svg)](https://protogrid.dev/servers/com.moltlinestudio/recall)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

_No tool definition changes recorded._

## Remotes

- https://mcp.moltlinestudio.com/recall (streamable-http, auth none, reachable true, uptime30d 0.9142857)

## Packages

_none_

## Tools (6)

- `graph_at_time`: See the memory as it stood on a given day, optionally faded by age. PREMIUM (license).

Relations carrying since and until are filtered to those in force on the
date; with a half-life, confidence decays exponentially with age so a
two-year-old belief does not weigh the same as last week's. Typical input
{"graph": {...}, "as_of": "2026-06-01", "half_life_days": 180} returns
{"as_of": "2026-06-01", "graph": {...}, "dropped": {"not_yet": 1,
"expired": 2}, "decayed": 4}.

Use when the answer depends on when you ask. Not for what changed between
two points - that is graph_diff, which does not need dates at all. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "as_of must be a date like 2026-06-01"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
- `graph_compact`: Shrink a memory to the part that still earns its place. PREMIUM (license).

Ranks entities by how connected they are and how much is recorded about
them, keeps anything you name outright, and drops the rest along with the
relations that pointed at them. Typical input {"graph": {...},
"max_entities": 50, "keep": ["Acme Corp"]} returns {"graph": {...},
"kept": 50, "dropped_entities": ["Old Note", ...], "dropped_relations": 12,
"ranking": "degree, then observation count, then name"}.

Use when a graph has outgrown the context you can spend on it. Not for
removing wrong facts - graph_lint finds those, and deleting them is a
decision you should make deliberately rather than by ranking. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"}. Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
- `graph_diff`: Say exactly what changed between two versions of a memory. FREE.

The audit trail a database gives you for free, without the database.
Typical input {"before": {...}, "after": {...}} returns
{"entities_added": ["Beta Ltd"], "entities_removed": [],
"observations_added": {"Acme Corp": ["renewed in March"]},
"relations_added": [...], "changed": true}.

Use after an upsert to record what a session learned, or between two
agents to see what one knows that the other does not. Not for merging the
two - feed the differences back through graph_upsert for that. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"}. Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
- `graph_lint`: Find the breaks a memory graph accumulates as it grows. FREE.

Relations pointing at entities that do not exist, entities nothing points
at, near-duplicate names, and observations that contradict each other on
the same entity. Typical input {"graph": {...}} returns {"ok": false,
"dangling_relations": [{"from": "Acme Corp", "to": "Beta Ltd", "missing":
["Beta Ltd"]}], "orphan_entities": ["Old Note"], "near_duplicates":
[["Acme Corp", "Acme  Corp."]], "contradictions": []}.

Use before trusting a graph you did not build, or on a schedule as memory
grows. Not for comparing two graphs (graph_diff) and not for shrinking one
(graph_compact). Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"}. Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
- `graph_search`: Find what the graph knows about something, plus its neighbourhood. FREE.

Scores entities by how many query words appear in the name, type and
observations, then pulls in whatever is within the requested number of
hops - because the useful answer to "what do we know about Acme" is
usually Acme plus who it is connected to. Typical input {"graph": {...},
"query": "acme renewal", "hops": 1} returns {"matches": [{"name": "Acme
Corp", "score": 3, "why": ["name", "observation"]}], "neighbourhood":
{"entities": [...], "relations": [...]}, "hops": 1}.

Use to read memory back before answering. Not for writing (graph_upsert)
and not for narrowing by date, which graph_at_time does. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "query must contain at least one word or number"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
- `graph_upsert`: Fold new facts into a memory graph and get the whole graph back. FREE.

Idempotent by construction: re-adding the same entity, observation or
relation changes nothing, so an agent that replays its own history does not
end up with a graph full of duplicates. Typical input {"graph": {"entities":
[], "relations": []}, "entities": [{"name": "Acme Corp", "type":
"company", "observations": ["renewed in March"]}]} returns {"graph": {...},
"added": {"entities": 1, "observations": 1, "relations": 0}, "merged": 0}.

Use as the single write path for memory. Not for reading it back
selectively - that is graph_search - and not for finding out what a write
changed, which graph_diff answers precisely. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "graph exceeds <value> entities; split it"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
