MCP security for a wiki: OAuth, tokens and page permissions
· Sergii Kravtsov · Folio
It can be safe to give an AI agent access to a company wiki if the agent works with one person's rights, not the wiki's, and if you can see and revoke what it did. That is the design Folio uses over MCP: a token or an OAuth grant acts as its owner, narrowed to read or write, hidden pages stay hidden, and writes are logged. This post covers what the MCP specification asks for, the risks, and what Folio does and does not do.
What the specification says was read in its 2025-06-18 revision on 2 November 2026; the protocol is revised often, so check the current text. What Folio does comes from its code and documentation.
What does the MCP specification say about authorization?
Authorization is optional in MCP. When an HTTP server uses it, the specification says the server is an OAuth 2.1 resource server and the client acts for a user. The rules that matter for a wiki:
- Discovery. The server must publish protected resource metadata (RFC 9728) and, on a 401, point to it in a
WWW-Authenticateheader. That is how a client finds the sign-in without being configured by hand. - PKCE and exact redirects. Clients must use PKCE. The authorization server must match redirect URIs exactly against what was registered, and they must be HTTPS or localhost.
- Audience binding. Clients must send the
resourceparameter (RFC 8707), and the server must accept only tokens issued for itself. - No token passthrough. A server must not accept tokens meant for another service, and must not forward the token it received to an upstream API.
- Short-lived tokens. Authorization servers should issue short-lived access tokens, and for public clients must rotate refresh tokens.
- Tokens in the header. The access token goes in the
Authorization: Bearerheader on every request and never in the URL. - Not for local servers. An STDIO server should not use this flow and takes credentials from its environment.
The same site has a security best practices page that explains why token passthrough and confused-deputy attacks are forbidden.
What are the risks of giving an agent wiki access?
- An agent that can see too much. If the server uses one service account, anyone who can talk to the agent can read what the account can read.
- A leaked token. A token that is copied, logged or kept in a config file works for whoever holds it until someone revokes it.
- A token for the wrong place. A token issued for one service that is accepted by another, or passed on to a third.
- Text that steers the agent. A page is written by people. Someone can plant text that tries to instruct the agent that reads it. No wiki can fully prevent that; it can only limit what the agent is able to do afterwards.
- Writes nobody can trace. An agent that edits pages without leaving a record of who and when.
Which credentials does Folio accept on /mcp?
Two kinds, and nothing else. A browser session cookie is never accepted on the MCP endpoint.
- Personal access token. You create it under the user menu, API tokens. It starts with
folio_pat_, is shown once and has the scope read or write. Folio stores only its SHA-256 hash. The token list shows its name, scopes, creation time and last use; it has no expiry date, so you revoke it by hand. - OAuth access token. Used by claude.ai, Claude Desktop and ChatGPT. It starts with
folio_oat_and lasts one hour. A refresh token lasts 30 days from the last use, because each refresh issues a new one. These tokens are also stored as hashes.
In both cases the agent acts as the person who made the token or approved the connection. Setup for a token is on the Claude Code page, and for OAuth on the Claude page; the hub lists the other clients.
How does Folio's OAuth for MCP work?
Folio is its own authorization server and the only resource server, which is the arrangement the specification describes. In the code, this is what it does:
- Discovery. A request without valid credentials gets a 401 with a
WWW-Authenticateheader pointing at the protected resource metadata, so the client starts the flow itself. Folio also serves the authorization server metadata (RFC 8414). - Client registration. Clients register dynamically (RFC 7591), or identify themselves with a Client ID Metadata Document. They are public clients, with no client secret.
- PKCE S256 only. The plain method does not exist. Redirect URIs must be HTTPS or loopback and must match exactly what was registered.
- Consent by the person. Connecting shows a consent screen where you choose read, or read and write. Only a signed-in browser session can approve it: a token cannot approve a new connection.
- Audience-bound tokens. Access tokens are issued for the
/mcpaddress of that Folio (RFC 8707) and are checked against it. The REST API does not accept them at all, and a token for another host is refused. - Rotation and revocation. Refresh tokens rotate on every use. If an already-used refresh token is shown again, which means two parties hold it, Folio revokes the whole grant. The revocation endpoint (RFC 7009) works, and you can disconnect an app under API tokens, Connected apps.
When a person is deactivated, their sessions, personal tokens and OAuth connections all stop working at once.
Does MCP respect page-level permissions in Folio?
Yes. Every MCP tool runs the same role checks as the web app: the person's role in the space, the restrictions on the page and on its parents, and for writes the token scope. A read token cannot write even when its owner is a space admin, and a write token cannot do more than its owner can.
A page the person cannot open is left out of the tree, search, backlinks, the link graph, tag counts and the rows of a base. A link to such a page looks like a link to nowhere. The built-in assistant works the same way, with the signed-in person's rights. So the answer to "what can my agent see?" is "what I can see", and the practical advice follows from it: give an agent its own user, make that user a member only of the spaces it needs, and use the editor role only where it should write.
What can an agent not do through MCP?
- Change who has access. Page, space and instance permissions, invitations and users can be changed only from a signed-in browser session. A token cannot reach the admin routes with any scope.
- Create or read public share links. A share link is a credential, so no API token can see, create, change or revoke one.
- Rename or delete a space, or create the home page of a folder.
- Approve its own access. An OAuth grant is approved by a person in the browser, as above.
A public site is readable by anyone in a browser, but the MCP endpoint of the same Folio still needs a token or an OAuth grant.
Can I see what an agent did?
Partly. An instance admin can open the audit log (the user menu, Audit log), filter it by person, action, target and date, and export it to CSV. It records creating and revoking tokens, OAuth consent, denial, disconnecting and revocation, and a reused refresh token. The MCP write tools we checked record the action with the source mcp and the tool name. Page edits are also in the page's Git history under the owner's name, and you can revert them like any commit.
What the log does not do: it does not record reads, so you cannot ask it which pages an agent opened. It is not signed, is written on a best-effort basis, and old entries are not deleted automatically. Not every action that changes a page is in it. Folio also does not show the instance admin the pages of spaces they are not a member of.
What does Folio not do?
- No scope narrower than read or write. There is no token limited to one space, one folder or a list of tools. You narrow an agent by giving its user fewer memberships.
- No prompt-injection filter. Page text is passed to the agent as data, and the tool descriptions tell the model to treat it that way, but a model can still be steered. Start with read access and review what a write-enabled agent changes.
- No expiry on personal tokens. Rotate and revoke them yourself; OAuth connections expire by themselves.
- No review queue. An agent with write access changes pages directly; the safety net is Git history and the audit log.
- Not a certification. This post describes how the code behaves. It is not a security audit or a compliance statement.
A short checklist before you connect an agent
- Create a separate user for the agent and add it only to the spaces it needs.
- Start with a read token or a read-only OAuth consent.
- Serve Folio over HTTPS, so tokens never cross the network in the clear.
- Keep tokens in an environment variable or a secret store, not in a repository.
- Check the audit log and the page history after the first week.
The background on why a Git-based wiki is a good fit for agents is in LLM wiki for a team, and the comparison with the vendor-hosted servers of Confluence and Notion is in our post on wiki MCP servers.
Frequently asked questions
Is it safe to give an AI agent access to a company wiki?
It can be, if the agent acts with one person's rights, starts with read access and leaves a trace. In Folio a token or OAuth grant acts as its owner, narrowed to read or write; writes go to Git history and, for the MCP tools checked, to the audit log. Page text can still try to steer a model, so keep write access narrow.
Does MCP respect page-level permissions?
In Folio, yes: every MCP tool applies the same role and page-restriction checks as the web app. Pages the token's owner cannot open are left out of the tree, search, backlinks and the link graph.
What does the MCP specification say about OAuth?
In the 2025-06-18 revision, authorization is optional. For HTTP servers it asks for OAuth 2.1 with PKCE, protected resource metadata (RFC 9728), the resource parameter (RFC 8707) and tokens checked for the right audience, and it forbids token passthrough. A server using STDIO should take credentials from its environment instead.
Can an MCP agent change page permissions in Folio?
No. Changing who has access, inviting users, public share links and renaming or deleting spaces are possible only from a signed-in browser session, never with a token.
How long do Folio MCP tokens last?
An OAuth access token lasts one hour and the refresh token 30 days from last use, with rotation. A personal access token has no expiry date; revoke it under API tokens.
See it in a running Folio
Open the live demo and click through a real Folio instance, or install it and move one space over. Folio is open source and stores everything in Git.
Related
More from the blog
- Folio 0.4.4: notifications, review of agent edits, page owners and team skills
- Folio 0.4.3: a calmer interface, redesigned after your feedback
- Obsidian Bases outside Obsidian: open and edit .base files in a browser
- Obsidian MCP: ways to give an AI agent your vault
- Notion vs Obsidian for a team: what each one gives you, and when neither fits
- Mermaid vs PlantUML: which to use for docs in Git
- Side-by-side comparison of wiki pages and versions: see what changed
- Publish a Cursor canvas to your team wiki: dashboards that outlive the chat
- Publish a Claude artifact to your team wiki: interactive pages that live in Git
- Make any page a template: custom templates for your Folio space
- Export Confluence to Markdown and keep it in Git
- Mermaid diagrams in a team wiki: keep them as code
- See how your team's knowledge connects: graph, Canvas and Bases in Folio 0.4
- Open an Obsidian vault as a team wiki, without changing a file
- Publish a wiki space as a public website, and let visitors ask it questions
- Docs-as-code without the IDE: edit your repository's docs in a browser
- New hires ask the wiki, and the wiki learns what it lacks
- Folio boards: built on Excalidraw, made for teams