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.
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()
PosixPath('/tmp/amoorion-m1v4ncht')
Which platforms are installed, and what each can do:
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'])}")
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:
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']}",
)
dryrun ok
nowhere failed: no plugin named 'nowhere'
Read it back, and answer it by its id:
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"],
)
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):
from amoorion.methods import InboxMethod
# All that was read so far.
for message in InboxMethod()():
print(
message["platform"],
"|",
message["text"].replace(
"\n",
" / ",
),
)
dryrun | Hello / / first post from amoorion
The same from the command line:
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:
from amoorion.cli import main
# The same through the command line.
exit_code = main(
[
"--json",
"publish",
"--text",
"from the CLI",
"--to",
"dryrun",
]
)
[
{
"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
}
]