# Tools

> The eight tools of the Geniffy MCP server, with every input, every result, and which ones change your memory.

The server offers eight tools. Five read your memory and three change it. An app connected for reading only
is never shown the three that change it.

| Tool | Reads or changes | Annotations |
| --- | --- | --- |
| [`search`](#search) | Reads | read-only |
| [`fetch`](#fetch) | Reads | read-only |
| [`ask`](#ask) | Reads | read-only |
| [`profile`](#profile) | Reads | read-only |
| [`list_memories`](#list_memories) | Reads | read-only |
| [`remember`](#remember) | Changes | not destructive |
| [`correct`](#correct) | Changes | destructive |
| [`forget`](#forget) | Changes | destructive, idempotent |

Every tool returns its result twice: as structured content that matches the tool's output schema, and as the
same JSON in a text block for apps that read only text. A memory is named `memory:<n>` and a source
`source:<id>`, the way `search` returns them; `fetch`, `correct` and `forget` take those names.

With an [API key](https://docs.geniffy.com/mcp#use-an-api-key-instead), every tool also takes `space`: one of your app's users, by the
name your app gives them.

## search

The facts that best match a query, each with what it says, when it was said and where it came from.

| Input | Type | |
| --- | --- | --- |
| `query` | string, required | What to look for, in plain words. Up to 2,000 characters |
| `limit` | integer | How many results, 1 to 25. Default 10 |

```json
{
  "results": [
    {
      "id": "memory:1042",
      "title": "Omkar prefers WhatsApp to email.",
      "url": "https://geniffy.com/app/memories?focus=1042",
      "text": "Omkar prefers WhatsApp to email.",
      "about": "Omkar",
      "kind": "pref",
      "said_at": "2026-10-03T09:41:00+00:00",
      "learned_at": "2026-10-03T09:42:00+00:00",
      "status": "current",
      "source": { "id": "source:3f2a9c1e5b7d4e8a9c217d4e5f6a8b90", "kind": "note", "title": "Contact preferences", "url": null }
    }
  ]
}
```

`kind` is one of `people`, `plan`, `pref` and `detail`. `status` is `current`, or `clash` when two memories
disagree.

## fetch

One memory or one source, by the id `search` or `list_memories` returned.

| Input | Type | |
| --- | --- | --- |
| `id` | string, required | `memory:<n>` or `source:<id>` |

For a memory, `text` is the memory and the exact line it came from, and `metadata` holds its `quote`, its
`source`, when it was said and learned, and its `history`: what it said before, if it changed. For a source,
`text` says what was added and how learning went, and `metadata` holds its `kind`, `status` and how many
facts it taught.

```json
{
  "id": "memory:1042",
  "title": "Omkar prefers WhatsApp to email.",
  "text": "Omkar prefers WhatsApp to email.\n\nThe line it came from: \"I prefer WhatsApp, never email.\"",
  "url": "https://geniffy.com/app/memories?focus=1042",
  "metadata": { "kind": "pref", "quote": "I prefer WhatsApp, never email.", "said_at": "2026-10-03T09:41:00+00:00", "history": [] }
}
```

## ask

An answer from your memory only, with the memories it rests on.

| Input | Type | |
| --- | --- | --- |
| `question` | string, required | The question, in plain words. Up to 2,000 characters |

```json
{
  "question": "When does Acme renew?",
  "answer": "In June, because SSO slipped.",
  "message": null,
  "memories": [{ "id": "memory:2", "text": "The Acme renewal moved to June because SSO slipped." }],
  "clash": false
}
```

When nothing stored supports an answer, `answer` is `null`, `memories` is empty, and `message` says so. The
server tells the app to say it doesn't know rather than guess. See
[When nothing is known](https://docs.geniffy.com/recall/when-nothing-is-known).

## profile

What is lastingly true about the person, and what is going on for them now.

| Input | Type | |
| --- | --- | --- |
| `subject` | string | A person or thing in the memory. Leave it out for the memory's owner |

The result has `lasting` and `current`, each a list of traits, and `memories`: how many memories the profile
was worked out from.

## list_memories

Memories, newest first.

| Input | Type | |
| --- | --- | --- |
| `kind` | string | `all`, `people`, `plan`, `pref` or `detail`. Default `all` |
| `limit` | integer | 1 to 50. Default 20 |
| `cursor` | integer | The `next` value from the previous page |

The result has `memories`, the `total` of that kind, and `next`, or `null` on the last page.

## remember

Saves a note to the memory. Geniffy reads it and learns the facts in it, each kept with the line it came
from; they can be found as soon as learning finishes. The app is told to save only what you ask it to, and
never passwords, keys or other secrets.

| Input | Type | |
| --- | --- | --- |
| `text` | string, required | What to remember. Up to 20,000 characters |
| `title` | string | A short name for it in the Geniffy app |

The result has the `source` the note became, with its `id` and `status`. In the Geniffy app, it is marked as
added by an AI app.

## correct

For a memory that is wrong. It is marked wrong and never used again, and what is right is saved in its place,
so the change leaves a trail. See [Correct and forget](https://docs.geniffy.com/correct-and-forget).

| Input | Type | |
| --- | --- | --- |
| `id` | string, required | The memory, as `memory:<n>` |
| `text` | string, required | What is right instead. Up to 2,000 characters |

## forget

Forgets one memory, or one source and everything only it taught, for good.

| Input | Type | |
| --- | --- | --- |
| `id` | string, required | `memory:<n>` or `source:<id>` |

## When something goes wrong

A tool that cannot do what was asked answers with `isError` set and a sentence that says why, such as a
missing input or a memory that was already forgotten, so the model can tell you or try again. Only a
malformed request, or a tool that does not exist, is a JSON-RPC error.

Source: https://docs.geniffy.com/mcp/tools
