# First steps

amoorion posts once to many platforms, reads them and answers from one
place. Everything it can do is a **method**; the CLI, the HTTP API and the
MCP server are only ways to call them. This notebook calls them from Python,
on `dryrun`, a platform that sends nothing and only remembers.

```ipython3
from amoorion import Amoorion

# A sandbox for this whole notebook: secrets only from variables, the inbox and
# the dataset in a temporary folder. Nothing here can touch your real setup.
Amoorion.init()
```

Which platforms are installed, and what each can do:

```ipython3
from amoorion.methods import Plugins

# Methods can also be used directly, without an `Amoorion`.
for plugin in Plugins()():
    print(f"{plugin['name']:16} {', '.join(plugin['capabilities'])}")
```

```myst-ansi
blogger          post
bluesky          delete, post, read, reply
discord          delete, post, read, reply
discord-webhook  delete, post
dryrun           delete, post, read, reply
email            post, read, reply
facebook         delete, post, read, reply
mastodon         delete, post, read, reply
matrix           delete, post, read, reply
ntfy             post, read
telegram         delete, post, read, reply
tumblr           delete, post, read
x                delete, post, read, reply
```

Publish one post. `to` names the platforms; each gives its own result,
and one failing doesn’t stop the others:

```ipython3
from amoorion.methods import Publish

# One platform doesn't exist: the other still gets its post.
results = Publish()(
    title="Hello",
    text="first post from amoorion",
    tags=["amoorion"],
    to=[
        "dryrun",
        "nowhere",
    ],
)

for result in results:
    print(
        result["platform"],
        "ok" if result["ok"] else f"failed: {result['error']}",
    )
```

```myst-ansi
dryrun ok
nowhere failed: no plugin named 'nowhere'
```

Read it back, and answer it by its id:

```ipython3
from amoorion.methods import Read, Reply

# The newest message.
[latest] = Read()(
    platform="dryrun",
    limit=1,
)

print(latest["text"])

# An answer to it, by its id.
answer = Reply()(
    platform="dryrun",
    to=latest["id"],
    text="and a reply",
)

print(
    "reply to",
    answer["reply_to"],
)
```

```myst-ansi
Hello

first post from amoorion
reply to 1
```

What `read` fetched is kept in the **inbox**, across platforms (a SQLite
file, `AMOORION_INBOX` in `.env`):

```ipython3
from amoorion.methods import InboxMethod

# All that was read so far.
for message in InboxMethod()():
    print(
        message["platform"],
        "|",
        message["text"].replace(
            "\n",
            " / ",
        ),
    )
```

```myst-ansi
dryrun | Hello /  / first post from amoorion
```

The same from the command line:

```sh
uv run amoorion publish --text "hello" --to dryrun
uv run amoorion --json read --platform dryrun
uv run amoorion inbox
```

The CLI’s `main` takes the same arguments:

```ipython3
from amoorion.cli import main

# The same through the command line.
exit_code = main(
    [
        "--json",
        "publish",
        "--text",
        "from the CLI",
        "--to",
        "dryrun",
    ]
)
```

```myst-ansi
[
  {
    "platform": "dryrun",
    "ok": true,
    "message": {
      "platform": "dryrun",
      "text": "from the CLI",
      "id": "3",
      "url": null,
      "author": null,
      "reply_to": null,
      "created_at": "2026-10-31T07:55:15.551149Z"
    },
    "error": null
  }
]
```
