# Use hosted storage

> Store the notebook on slivingdoc.dev instead of a bucket, by browser login or by token, and what a full or limited space looks like.

Canonical URL: https://www.slivingdoc.dev/docs/guides/hosted/ · Version: 1.0 · Updated: 2026-09-29

Full site index: https://www.slivingdoc.dev/llms.txt

Hosted storage keeps the notebook on slivingdoc.dev, so there is no
bucket to run and no cloud keys to hold. The commands, the MCP tools and
the publication protocol are the same as with a bucket. You
[sign in](/login) with GitHub or Google, and the free plan needs no card:
10 MiB, 250,000 requests a month and one space. [Pricing](/pricing/)
lists the limits and what more costs.

A space is one notebook. Names are 1 to 63 lowercase letters, digits and
inner hyphens. There are two ways to connect, and the browser
login needs slivingdoc 0.2.4 or newer; a token alone works from 0.2.2.

## Connect with a browser login

This is the route for a person on their own machine.

```text
npx -y slivingdoc login
```

The command prints a page address with a one-time code in it and opens
your browser. Approve the login there. The code lives 10 minutes. Use
`--no-browser` to print the address without opening it, `--read-only` to
ask for a login that can only pull, and `--space <name>` to choose the
default space.

Afterwards the command prints who approved it, and on a terminal asks
`Store this login? [y/N]`. Only `y` or `yes`, in any case, stores it;
any other answer revokes the key again. Without a terminal nothing is
asked and the key is stored, so read the "Approved by" line yourself; if
another account's login is already stored, `--force` is needed to replace
it. A
stored login is an account key, valid 90 days, in `credentials.json`
under your user configuration directory (`~/.config/slivingdoc/` on
Linux), mode 0600. You can list and revoke it on the site's Tokens page.

With a login stored, `serve`, `pull` and `commit` need no token. Each
one trades the key for a token that reaches one space and lasts one
hour. Minted tokens live in memory only, and `serve` renews them. The key
goes only to the site that issued it.

```text
npx -y slivingdoc space            # list the spaces the login reaches
npx -y slivingdoc space notes      # make "notes" the default
npx -y slivingdoc pull notes-dir
```

`space` marks the default in the list. On a terminal it offers a picker.
A name the login does not reach changes nothing. `slivingdoc logout`
revokes the key, and with it every token minted from it, and removes the
file entry.

Restart a running MCP server after a new login or a new default space:
it reads them at startup.

## Connect with a token

A token is for CI and for MCP host configuration. Create one on your
[account](/account/) page. It reaches one space, is read-write or
read-only, and expires (90 days by default).

```text
export SLIVINGDOC_TOKEN=<your-api-token>
npx -y slivingdoc pull notes
```

There is no flag for it: it is read from the environment only, so it
belongs in the host's environment block:

```text
claude mcp add slivingdoc \
  --env SLIVINGDOC_TOKEN=<your-api-token> \
  -- npx -y slivingdoc serve
```

With a token set, `serve` needs no space name: it asks the server which
space the token reaches. A `--space` or `SLIVINGDOC_SPACE` that names a
different space is refused. A token wins over a stored login, and a
process with a token never reads `credentials.json`. Other hosts and the
read-only entry are in [Connect an MCP host](/docs/guides/mcp-hosts/).

## Which space, which storage

The space comes from `--space` (alias `--bucket`), then `SLIVINGDOC_SPACE`
(alias `SLIVINGDOC_BUCKET`). With neither, a token supplies its own space
and a stored login supplies its default. With neither of those, startup
is refused and names `slivingdoc space <name>`.

`--storage` (`SLIVINGDOC_STORAGE`) chooses the backend:

- `auto` (the default) picks hosted when `SLIVINGDOC_TOKEN` is set, and
  when a login is stored unless S3 is configured on purpose (below). With
  neither it picks S3.
- `hosted` requires a token or a login, and ignores S3 settings.
- `s3` uses the AWS chain only and never reads a token or the login.

Under `auto`, two mixtures are refused instead of guessed. A token beside
`--endpoint`, `AWS_ENDPOINT_URL` or `AWS_ENDPOINT_URL_S3` is refused, and
so is a stored login with an explicit space beside any S3 setting
(credentials, profile, region, `~/.aws`). Pass `--storage hosted` or
`--storage s3` to say which you mean. The other side of the same rule: a
stored login with a bucket setting and no S3 setting at all is taken as
hosted, and the bucket is read as a space name. Ambient credentials such
as an instance role or an SSO session count as no S3 setting, so a
machine that ever ran `login` and then sets `SLIVINGDOC_BUCKET` for a
real bucket needs `--storage s3` (`SLIVINGDOC_STORAGE=s3`). Several stored logins need
`--endpoint`. An expired login is refused with a hint to run
`slivingdoc login` again.

The endpoint defaults to `https://api.slivingdoc.dev`; it must be https
unless it is a loopback address. `--region` and `AWS_REGION` do nothing
in hosted mode.

## A full or limited space

Hosted refusals arrive as a `STORAGE_FAILURE` with one of these reasons.
[Errors](/docs/reference/errors/) has the full list.

| Reason             | Meaning                                                                    | Retry |
| ------------------ | -------------------------------------------------------------------------- | ----- |
| `STORAGE_FULL`     | The owning account is out of storage. Pulls still work                     | no    |
| `REQUEST_LIMIT`    | The month's requests are used up; resets on the 1st                        | no    |
| `RATE_LIMITED`     | Too many requests at once, or reads after the month's requests are used up | yes   |
| `ACCESS_DENIED`    | Token missing, revoked, expired, read-only, or wrong                       | no    |
| `OBJECT_TOO_LARGE` | One publication exceeds the gateway's size limit                           | no    |

Before it reports `STORAGE_FULL`, slivingdoc tries to compact the
notebook, so deleting notes and committing again can make room. Beyond
that the owner adds storage on the site, or deletes notes.
`ACCESS_DENIED` also covers a space that does not exist or an endpoint
that is not the storage API.

At startup the same refusals are not a result. The access check fails
with one line on standard error, `error: app: hosted storage refused the
token: …`, and an endpoint that is not compatible with the storage API
prints `INCOMPATIBLE_STORE: hosted storage check failed`. Neither reaches
a client.

## Security

A token reaches one space. A login's account key reaches every space of
the account, so keep `credentials.json` private: slivingdoc refuses to
read it when it is a symlink, has another owner, or is readable by group
or others. Use tokens, not a login, for CI and shared machines, and
`logout` when you are done on a borrowed one.

## Or run your own storage

Hosted storage is optional. The same CLI and server work against your
own S3-compatible bucket: see [Set up a bucket](/docs/guides/bucket/).

## Next

- [Connect an MCP host](/docs/guides/mcp-hosts/)
- [Configuration](/docs/reference/configuration/)
- [Errors](/docs/reference/errors/)
