MojoPad has a local API, and anything running as you on this Mac can use it. A Shortcut that files a note into today’s journal. A shell script that pulls every page of a kind into a report. A Keyboard Maestro macro that searches your wiki by meaning from any app. Another program you wrote, reading a page by name. None of it needs an AI, an account, or the internet.
Not to be confused with the mojo API, which is a different thing with
a similar name. That one runs inside a page, in scriptlets and plugins, and is
described under Scripting. This one is spoken to from outside MojoPad, over a
connection on your own machine. If you are writing something that is not a MojoPad page, this
is the one you want.
The same door an assistant uses is open to anything else you run. When
Let agents reach the wiki that’s open right now is on, MojoPad answers a small
set of requests on your own machine — so a shell script, a Shortcut, Keyboard Maestro, or
any app you write can read from and add to the wiki you have open. Nothing on the internet
can: the door is on 127.0.0.1, it needs a key, and it refuses anything that
looks like it came from a web page.
Finding it. Each time MojoPad starts it writes
~/.mojopad/bridge.json — the port it is listening on and a fresh key,
readable only by you. A script reads that file and puts the key in an
Authorization: Bearer header. The key changes every launch, so nothing can
hold one from last week.
PORT=$(python3 -c "import json;print(json.load(open('$HOME/.mojopad/bridge.json'))['port'])")
TOK=$(python3 -c "import json;print(json.load(open('$HOME/.mojopad/bridge.json'))['token'])")
curl -s -H "Authorization: Bearer $TOK" http://127.0.0.1:$PORT/info
Everything below is POST with a JSON body, except /info.
ref means a page’s name or its id.
| Ask | Body | Answers with |
|---|---|---|
/info | — | the app version, the contract version, and which wiki is open |
/pages | {"limit": 200, "offset": 0} | every page’s name, id, type and when it changed |
/page | {"ref": "Lend Lease"} | that page’s words, tags and other names |
/props | {"ref": "Lend Lease"} | its typed properties, each with where its value came from |
/search | {"query": "…", "k": 6} | pages ranked by meaning |
/ask | {"question": "…"} | an answer from your local model, with its sources |
/add ✎ | {"title": "…", "content": "…"} | makes a page |
/append ✎ | {"ref": "…", "text": "…"} | adds to the end of a page |
/today ✎ | {"text": "…"} | adds to today’s note |
The three marked ✎ change your wiki, and they are refused unless Allow agents to modify wikis you already have is also on. Reading is never affected by that switch.
Event: or Plugin: page from outside — their words are
the code, and an Event: Open page runs every time the document is opened.The contract has its own version. /info reports api
alongside the app version. The app version moves every release; the api number
moves only when the shape of a request or an answer changes, so a script can tell the
difference between MojoPad being newer and MojoPad being different.