OAuth is the way to connect a client without giving it your password. You approve a specific set of permissions on a consent screen, the client gets a token limited to those, and you can revoke it later without touching your WordPress account.
The alternative, an application password, is one long secret that can do whatever your account can do. It works, and for a single client you control it is fine. OAuth exists for everything else: connections you want to limit, connections you want to see, and connections you want to be able to take back.
Point a client at your NIBWP endpoint. It sends you to a consent screen listing exactly what it is asking for. Approve the parts you want, and revoke the token later from the same place.
Approve what you meant to approve
The point of the consent screen is that the decision is visible and reversible:
- No password shared — The client never sees your credentials, only a token you issued.
- Permissions itemised — You see each scope, in plain words, before anything is granted.
- Dangerous parts separated — Deleting, files and code are shown apart and are never implied by anything else.
- Revocable — Take a token back without changing your password or affecting other clients.
- Per client — Each connection has its own token, so one can be revoked without the rest.
- Logged — Every call carries the token, so the audit log knows which client made it.
The scopes you are asked for
Five scopes, and the consent screen shows them in this order. The last three are marked as dangerous and start unticked:
| Ability | Type | What it does |
|---|---|---|
mcp:read | read | View posts, pages, media, settings and site information. Changes nothing. |
mcp:write | write | Add and update posts, pages, products and settings. Cannot delete. |
mcp:manage | manage | Delete posts, pages, users and media, and run bulk changes. Not reversible from here. |
mcp:files | manage | Open and save files on the server: theme and plugin files, uploads, configuration. |
mcp:code | manage | Write and run PHP in the sandbox. It is the widest permission here. |
Read and write are offered by default. The three dangerous scopes are shown separately and have to be ticked deliberately, because handing them over by accident is the mistake worth designing against.
What a refusal looks like
A call outside the granted scopes fails clearly, naming the scope it needed:
nibwp/wp-delete-post (run)
✗ refused · this token holds mcp:read, mcp:write
This call needs mcp:manageYou are never left wondering whether something silently succeeded with the wrong permission.
What you can build
A few ways to use it:
Read-only first
Connect with read alone and watch what the client can see before granting more.
One token per client
Give each tool its own connection so you can revoke one without the others.
Contractor access
Issue a scoped token for the length of an engagement and revoke it at the end.
Least privilege
Grant write without manage, so a mistake cannot delete anything.
How it stays safe
- Nothing is implied — A dangerous scope is only ever granted because you ticked it.
- Revoke at any time — A revoked token stops working on its next call.
- Tokens expire — They are time-limited and refresh under rotation, so a leaked one has a short life.
- Bound to your account — A token can only do what your WordPress role allows, whatever it was granted.
Getting started
- Enable your account — Access comes first. See User Access.
- Point the client at NIBWP — Give it your MCP endpoint. It will discover the rest and send you to consent.
- Read the screen — Grant read and write to begin with. Leave the dangerous three alone.
- Check the audit log — Confirm the calls arriving are the ones you expected.