Make postulo-mcp official: what that means, and what is missing before it can be #1
Labels
No labels
bug
documentation
enhancement
security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Postulo/postulo-mcp#1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Where this actually stands
Not at the beginning. One commit — Serve one Postulo instance to an agent, over the Model
Context Protocol — already contains the whole thing the README describes:
--write, three resources(
postulo://applications/7and friends) and two prompts.Postuloclient overhttpx, address and token from the environment so neither reachesa process list.
ruff checkandpytest, onpython:3.14-slim-bookworm.mcppinned at 2.1.1 inuv.lock.So this issue is not "implement it". It is "finish making it a thing somebody else can
install and trust".
First: "official plugin" is two different things, and only one of them fits
postulo-mcp is deliberately not a Postulo plugin. Its own
pyproject.tomlsays so:And Postulo's
docs/PLAN.mdmakes it a stated position rather than an accident:Postulo's plugin catalogue —
plugins/catalogue.py, an Ed25519-signed index with a checksumper wheel — distributes plugins that are installed into a Postulo instance, and
provenance.officialmeans precisely "its file matches what the official repositorysigned". Publishing postulo-mcp through that would mean installing an MCP server inside
Postulo, which is the thing PLAN.md says never happens.
So "official" here should mean: maintained, versioned, released and documented by the
project — not listed in the plugin catalogue. The rest of this issue assumes that. If the
intention is genuinely to run MCP inside the instance, that is a different issue and it
starts by reversing a line in
PLAN.md, deliberately and in writing.What is missing
1. It has never been released
version = "0.1.0", one commit, no tag, noCHANGELOG.md, and no release workflow — CI runstests and stops. The README tells people to install it:
which installs whatever
mainhappens to be that day. That is fine for trying it and wrongfor something called official: there is no version anybody can name, pin, or report a bug
against.
CHANGELOG.md, kept as Postulo's is.changelog, build the sdist and wheel, create the Forgejo release with the changelog section
as its notes. Postulo's
release.ymlandscripts/release_tools.pyare the pattern.are meant to trust. PyPI, or the Forgejo package registry, or both — pick one and put it in
the README in place of the git URL.
2. The README makes promises nothing tests
These are the promises that make pointing an agent at somebody's entire job search
acceptable, and every one of them currently holds only because the code happens to say so:
Each wants a test that fails if somebody later makes it untrue:
DELETE, and none is named or described as removing anything.A test over the registered tool set rather than over a list somebody remembers to update.
--write, the write tools are not registered at all — not merely refused.--writebut a read-only token, a write fails with something a model can act onrather than a traceback.
A promise in a README with no test is a promise until the next person edits the file.
3. Tools that are missing, and one of them matters
Against the API the instance actually exposes:
/captures,/captures/preview/medocumentsrouterCaptures are the gap worth closing. Postulo's whole front door is "here is a posting,
read it", and an agent that has found a job advert cannot hand it over.
/captures/previewis particularly well suited: it reads a page, stores nothing, notifies nobody, and answers
with what would be captured — so an agent can offer it to the person before anything is
written. That makes it arguably a read tool, not a write one, which is worth deciding
explicitly rather than by accident.
/meis small and useful: an agent's first call can say which scopes the token has, so arefusal later is explainable rather than mysterious.
4. Documentation
pyproject.tomlpoints at The capture API on the wiki — Postulo's API page, not an MCPpage. There is no wiki page for postulo-mcp itself. For something official there should be
one, and it should carry the paragraph the README already gets right:
Suggested order
/me, then captures (§3), each its own commit.v0.1.0.Nothing here needs a decision from Postulo core except the one at the top: that official
means released and documented, not listed in the plugin catalogue.
The version to tag is not
v0.1.0.An official plugin's version tracks the core's, so the first release of this repository is
v0.3.0— the one that pairs with Postulo 0.3.0 — and itsrequires_postulois~=0.3.0. Step 5 of the suggested order should read that way.The rule, the reasoning and what has to change in core are in postulo/postulo#186. Two parts
of it matter here:
to the 0.3 plugin and implies no core release, so this repository can still fix its own
bugs between core releases.
requires_postuloand never checks it, so declaring it is not yetprotection. That is being fixed in core; until it is, the README should say plainly which
Postulo this works with rather than relying on the installer to refuse.
Decided: English only, and no catalogue
postulo-mcp carries no translation catalogue. It is the one official plugin exempt from
the rule every other one follows (postulo/postulo#187), and the exemption is deliberate
rather than deferred work.
Why. Almost everything this repository puts into words is read by a model, not by a
person: sixteen tool descriptions, three resource descriptions, two prompts, and the
server's instructions to the model. Translating those does not help anybody and can hurt —
an agent reasoning over a French tool description while the person it serves writes English
is worse off than one reading the English, and the failure is silent. A catalogue here would
be work with a negative return.
This is not an argument that translation does not matter. It is that these particular
strings have a machine for an audience, and the rest of Postulo's strings do not.
Write it down in the repository. A
locale/directory that does not exist looks like anoversight, and the next person to tidy the official plugins into consistency will add one.
A short section in the README — or a comment where the tool descriptions are declared —
saying that the descriptions are model-facing and stay in English is what stops that.
What would reopen it
Strings a person reads. Today that is the README and whatever the command line prints
when something goes wrong — a bad token, an unreachable instance, a missing scope. There are
few of them and they are seen at the moment somebody is already confused, which is the worst
moment to be reading a second language. If that set grows into anything resembling a setup
flow, this decision is worth revisiting for those strings only; the tool descriptions
stay English regardless.