Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions content/docs/(reference)/folder-sync-status.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The file sits beside the folder registry, `folders.json`:
"processes": [
{
"pid": 4821,
"build_version": "0.0.56",
"started_at": "2026-10-15T09:00:00.000Z",
"heartbeat_at": "2026-10-15T09:20:35.120Z",
"heartbeat_interval_seconds": 5,
Expand Down Expand Up @@ -55,6 +56,7 @@ The file sits beside the folder registry, `folders.json`:
| Field | Type | Description |
| --- | --- | --- |
| `pid` | `number` | The watch process. |
| `build_version` | `string` or absent | The version of the CLI build that runs the watch, as `marfa --version` prints it. One that differs from the installed CLI's still runs an earlier build. A build too old to write the field drops it from every entry when it writes the file. |
| `started_at` | `string` | When the process started. |
| `heartbeat_at` | `string` | When the process last wrote its entry. |
| `heartbeat_interval_seconds` | `number` | How often a running process writes: at least this often. |
Expand Down
6 changes: 4 additions & 2 deletions content/docs/(start)/connectors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ title: Connectors
description: How a connector brings records from another service into Marfa, and what the instance keeps so it can stop and resume safely.
---

Much of your data starts somewhere else: tasks in Todoist, issues on GitHub, articles in an RSS feed. A **connector** is a program that reads such a service, its vendor, and writes what it finds to your instance as items. It can also carry changes made in Marfa back to the vendor.
Much of your data starts somewhere else: tasks in Todoist, issues on GitHub, articles in an RSS feed. A **connector** is a program outside the server that **registers with your instance**, most often to read such a service, its vendor, and write what it finds as items. It can also carry changes made in Marfa back to the vendor.

The registration is what makes a program a connector. An app or a script that reads and writes with a key, or through a sign-in, but never registers isn't one, and needs nothing on this page.

A Todoist connector, for example, runs where you choose and reaches your instance with a key of its own. The instance keeps what the connector needs to resume, and Todoist can also post webhooks to an inbound endpoint on the instance.

Expand All @@ -13,7 +15,7 @@ A Todoist connector, for example, runs where you choose and reaches your instanc

The server never runs a connector or calls a vendor. A connector is an ordinary program you run wherever suits you, on a schedule or all the time, and it uses the same API as any app. That keeps the server small, and your vendor credentials out of it.

A connector runs with a key made for it alone. The key's [source](/items-and-types#where-an-item-came-from) labels everything the connector writes, and with each record's `source_id`, its ID at the vendor, lets the connector update a record rather than write it twice.
A connector registers under a key made for it alone. The key's [source](/items-and-types#where-an-item-came-from) labels everything the connector writes, and with each record's `source_id`, its ID at the vendor, lets the connector update a record rather than write it twice.

What a connector brings in belongs in the [feed](/items-and-types#library-and-feed). A connector names `feed` on each write, or its key makes `feed` its default; otherwise its records land in the library. A connector names the library only for a file that belongs to an item already there, such as a picture saved for an entry a person kept.

Expand Down
2 changes: 1 addition & 1 deletion content/docs/(start)/devices.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A device chooses the **slice** it keeps: a list of types, a tier and the edge ty

The device fills its copy once, by a **hydration** that reads every item in the slice, then keeps it current from the instance's [event stream](/events). Reads, [saved views](/build/read-a-view#read-a-view-from-a-working-copy) included, need no connection.

**While the copy fills, the device answers from what has arrived**, marking a list or search `partial`. A saved view's items, any edge read or write, and a read or write of an item that hasn't arrived are refused `hydration_incomplete`. Other writes wait in the queue until the copy is whole.
**While the copy fills, the device answers from what has arrived**, marking a list or search `partial`. A saved view's items, groups and search, any edge read or write, and a read or write of an item that hasn't arrived are refused `hydration_incomplete`. Other writes wait in the queue until the copy is whole.

**A fill that stops partway resumes where it stopped**, unless something such as the slice has changed.

Expand Down
2 changes: 1 addition & 1 deletion content/docs/(start)/how-marfa-works.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ Every program that uses Marfa runs outside it and sends requests to its HTTP API
- **The Swift SDK and the CLI** embed the **core**, a Rust engine that sends their requests and can keep a working copy of the data they need. A program that keeps a working copy is a **device**: it reads offline and sends its writes when it can reach the instance, as [Devices](/devices) explains. The Swift SDK also sends the operations only the instance can do, such as registering a type, straight to the API.
- **The TypeScript SDK** sends each request straight to the API, and keeps no copy.
- **AI agents**, such as Claude Code or ChatGPT, connect to the instance's **MCP server** at `/mcp`, or run the CLI with a key of their own, as [Agents, the CLI and MCP](/agents-cli-and-mcp) explains.
- **Connectors** are programs you run that bring in records from another service, such as Todoist, as [Connectors](/connectors) explains.
- **Connectors** are programs you run that register with the instance and bring in records from another service, such as Todoist, as [Connectors](/connectors) explains.

<WhatReachesIt />
4 changes: 2 additions & 2 deletions content/docs/build/connector-pull.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: Write a vendor's records into Marfa as items, write only what chang

A connector pulls: it reads the vendor and writes what it finds as items. A two-way connector also carries changes made in Marfa back, as [Carry changes back](/build/connector-push) shows, and a one-way connector says which types it holds read only.

The operations below come in the order a run uses them, for a connector built directly on the API. [The connector kit](/build/connector) does all of this for you but [declaring read-only types](#declare-the-types-you-dont-carry-back).
The operations below come in the order a run uses them, for a connector built directly on the API. [The connector kit](/build/connector) does all of this for you, [read-only types](#declare-the-types-you-dont-carry-back) included.

The examples follow a task manager connector with a key of its own under the source `tasks`, which writes the type `tasks.task`. In the TypeScript examples, `marfa` is a [TypeScript SDK](/typescript-sdk) client made with that key.

Expand Down Expand Up @@ -134,7 +134,7 @@ await marfa.POST("/connectors", {
});
```

- **Each registration replaces the list**, and one without it clears the list. Build it on every start from what the connector carries back with the settings it runs on.
- **Each registration replaces the list**, and one without it clears the list. Build it on every start from what the connector carries back with the settings it runs on. **The kit does this for you**: it lists every type the connector writes and doesn't carry back, so a settings change reaches the list when the connector restarts.
- **An item reads `true` only while every connector** whose live key owns or claims its source lists its type and may write it. Once that stops, its next read says `false`.
- **Marfa doesn't refuse an edit** to a read-only item. The flag says what the connector will do.
- **The list is per type.** Leave a type out when you carry back any of its fields or items.
Expand Down
4 changes: 4 additions & 0 deletions content/docs/catalog/(types)/(core)/highlight.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ identifier: core.highlight

<include cwd>src/generated/catalog/core.highlight.md</include>

## Name

A highlight's passage is its text, never its name. A highlight with no `title` is named after the item it's an [`excerpt-of`](/catalog/edges#excerpt-of), such as "Excerpt from Thinking, Fast and Slow", so several highlights from one book share a name. With no such item, the server names it `Untitled`. [Names and previews](/catalog/display-hints#names-and-previews) has the rule.

## Example

```json
Expand Down
4 changes: 2 additions & 2 deletions content/docs/catalog/(types)/(core)/media.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ identifier: core.media

## Progress and rating

Every media type, games included, inherits two fields for what the owner thinks of a work:
Every media type, games included, inherits two fields for where you are with a work and what you think of it:

- **`progress`** is where the owner is with it, a [status field](/catalog/field-kinds#status-words) whose group a `status_group` filter reads on any media type. A series also holds `status`, a separate field that says whether it's still producing episodes.
- **`progress`** is a [status field](/catalog/field-kinds#status-words) whose group a `status_group` filter reads on any media type. A series also holds `status`, a separate field that says whether it's still producing episodes.
- **`rating`** is a whole number from 1 to 5. A fraction, or a number outside the range, is refused `400 invalid_properties`.

Marfa doesn't compare a game's `min_players` with its `max_players`.
Expand Down
4 changes: 2 additions & 2 deletions content/docs/catalog/connectors/readwise-reader.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Each run reads what changed since the last, with a five-minute overlap, and a fu
| `readwise.highlight` | [Highlight](/catalog/highlight) | A highlight with its annotation and tags |
| `readwise.file` | [File](/catalog/file) | Kept content, attached to its document or highlight |

The Readwise connector writes the same types, so one item can hold what both connectors know. An item Reader manages carries a Reader link, `<account>:reader-document:<ID>` or `<account>:reader-highlight:<ID>`, in `canonical_key`. A highlight connects to its document through `references`, and a file connects to what it belongs to through `attached-to`.
The Readwise connector writes the same types, so one item can hold what both connectors know. An item Reader manages carries a Reader link, `<account>:reader-document:<ID>` or `<account>:reader-highlight:<ID>`, in `canonical_key`. A highlight connects to its document through [`excerpt-of`](/catalog/edges#excerpt-of), and a file connects to what it belongs to through `attached-to`, so moving a document or highlight to the bin takes its files with it, and restoring it brings them back.

## What goes back

Expand Down Expand Up @@ -88,4 +88,4 @@ Each run fetches at most 100 pictures and 200 MiB, from at most 25 documents, an

## Run it

[Run a connector](/run/run-a-connector) runs any connector. This one's key holds write on `readwise.source`, `readwise.highlight` and `readwise.file`, and on the `references` and `attached-to` edges, and its [README](https://github.com/withmarfa/marfa-connectors/blob/main/connectors/readwise-reader/README.md) lists what the key needs. Saving pictures needs no other permission.
[Run a connector](/run/run-a-connector) runs any connector. This one's key holds write on `readwise.source`, `readwise.highlight` and `readwise.file`, and on the `excerpt-of` and `attached-to` edges, and its [README](https://github.com/withmarfa/marfa-connectors/blob/main/connectors/readwise-reader/README.md) lists what the key needs. The connector refuses a key without write on `excerpt-of`, such as one that holds `references` in its place. Saving pictures needs no other permission.
4 changes: 2 additions & 2 deletions content/docs/catalog/connectors/readwise.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The first run exports everything. Later runs ask for what changed since the last
| `readwise.highlight` | [Highlight](/catalog/highlight) | A highlight with its annotation and tags |
| `readwise.file` | [File](/catalog/file) | Content kept for a document that Readwise Reader manages |

Each highlight connects to its source through `references`. An item's `source_id` is `<account>:source:<ID>` or `<account>:highlight:<ID>`, where the account is your `READWISE_ACCOUNT`. Readwise's original timestamps, location kinds and colors are kept as properties.
Each highlight connects to its source through [`excerpt-of`](/catalog/edges#excerpt-of), and a file to what it belongs to through `attached-to`, so moving a source or highlight to the bin takes its files with it. An item's `source_id` is `<account>:source:<ID>` or `<account>:highlight:<ID>`, where the account is your `READWISE_ACCOUNT`. Readwise's original timestamps, location kinds and colors are kept as properties.

Each highlight has a `title` and a `body`, which apps show as its title and text. The title is the passage's first paragraph as plain text, cut at a word boundary to at most 80 characters. A blank line ends a paragraph and a heading is a paragraph of its own, so lines with a single line break between them are joined. The title leaves out list and quotation markers at its start, a heading's permalink mark, and closes up the gap before a closing punctuation mark. A passage that holds only a picture is titled after its source, as in "Picture from Deep Work". The body is the whole passage as Markdown, pictures included.

Expand Down Expand Up @@ -48,4 +48,4 @@ Nothing. The connector sends no write to Readwise, and moving an item to the bin

## Run it

[Run a connector](/run/run-a-connector) runs any connector. This one's key holds write on `readwise.source`, `readwise.highlight` and `readwise.file`, and on the `references` and `attached-to` edges, and its [README](https://github.com/withmarfa/marfa-connectors/blob/main/connectors/readwise/README.md) has the `marfa keys create` command.
[Run a connector](/run/run-a-connector) runs any connector. This one's key holds write on `readwise.source`, `readwise.highlight` and `readwise.file`, and on the `excerpt-of` and `attached-to` edges, and its [README](https://github.com/withmarfa/marfa-connectors/blob/main/connectors/readwise/README.md) has the `marfa keys create` command. The connector refuses a key without write on `excerpt-of`, such as one that holds `references` in its place.
2 changes: 1 addition & 1 deletion content/docs/catalog/connectors/rss.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Each run fetches at most 100 pictures and 200 MiB, and starts no fetch after 10

### When an entry leaves

When an entry is archived, in the bin or purged, the next run archives its pictures. When the entry is active again, the run after brings back those its text still points to. It brings back only pictures it archived, and never puts a picture in the bin or purges one.
**A picture goes to the bin with its entry**, and comes back when the entry is restored. When an entry is archived, or is gone, the next run archives its pictures. When the entry is active again, the run after brings back those its text still points to. It brings back only pictures it archived, and never puts a picture in the bin or purges one.

A picture a person moved to the bin or purged is never saved again for that entry. A picture the text stops mentioning is kept.

Expand Down
Loading
Loading