Before you begin
- Confirm someone with the Admin role or above has enabled the hosted MCP token policy and allowed the scopes your agents need.
- Confirm your own team role meets the Minimum team role set in that policy.
- Install a coding agent that supports remote MCP servers over HTTP.
- Decide the token’s reach: one workspace, or every workspace in the organization.
- For headless use, prepare a secrets manager to hold a personal access token.
Key concepts
The Minerva MCP server
Minerva publishes two resource URLs on the same hostname:
Prefer the read-only endpoint whenever an agent only needs to look things up. It removes the possibility of an accidental write even if a token is broader than it should be, so it is the right default for an autonomous agent.
You can register both. Most clients allow more than one MCP server, so a common setup is a
minerva entry pointing at the full endpoint for day-to-day work, paired with a minerva-readonly entry for agents you want structurally unable to change anything.
Minerva serves the OAuth 2.1 authorization server on the same hostname, mcp.gominerva.com, so the discovery documents, the authorize and token endpoints, and the signing keys all live alongside the MCP endpoint. If your network policy requires an allowlist, one hostname is enough.
These endpoints are separate from the REST API in the API introduction: an MCP token’s scopes apply to MCP only, and never change what an application API key can do.
Compliant clients discover all of this automatically from
https://mcp.gominerva.com/.well-known/oauth-protected-resource and
https://mcp.gominerva.com/.well-known/oauth-authorization-server. You should
never need to configure an authorization URL, a client ID, or a client secret
by hand: Minerva supports dynamic client registration, so the agent registers
itself on first login.Connect your coding agent
Setup is the same everywhere: register the resource URL, then run the client’s login command and approve the request in the browser. Each harness has its own tab below.Step 1: Register the server
Codex, Claude Code, and opencode each write their own manifest entry from the command line. Kimi has no MCP subcommand, so you add its entry to~/.kimi-code/mcp.json by hand.
codex mcp add just writes ~/.codex/config.toml. If you manage your
configuration in dotfiles, add the equivalent block directly instead:https://mcp.gominerva.com/mcp/readonly as the URL. That endpoint advertises the read-only tool subset only, so an agent wired to it cannot change anything.
Step 2: Sign in
app.gominerva.com, you only have to approve the request.
Step 3: Approve the request
The consent screen names the client that asked, the workspace the token will act in, and every scope requested.mcp:read is preselected and cannot be deselected, because a token without it cannot discover the tools it may call.
Deselect anything the agent does not need. Scopes explains what each one grants. This is the last point at which you choose, and the choice is per connection, so a research agent and a case-management agent can hold very different permissions under the same account.
The figure’s example policy offers optional scopes. Your organization’s policy decides which optional scopes appear. When none are available, mcp:read is the only scope on offer, and a connection carrying only that can call whoami and list_tool_permissions and nothing else. That is a working connection, not a failed one.
After you approve, Minerva confirms the grant and sends the authorization to your client immediately, then tells you to finish the login in your terminal. A CLI login has just opened its listener and is blocking on it, so the authorization arrives while the client is waiting, and the tab hands you back to the client’s own confirmation. The figure below is a Codex login.
The button on that screen is a fallback, not a step. If your client is still waiting, use it to send the authorization again; if your terminal has already printed success, the login is done and the page is left over. A client whose return address cannot be verified gets an error screen instead: Authorization not sent. The client is given no access, so run the login command again.
Personal access tokens
Two kinds of caller need a token rather than a browser sign-in: anything with no browser to open, such as CI jobs, schedulers, and containers, and a developer whose client cannot complete the browser login, which as of July 2026 means Codex on a stable release (see the browser flow’s Step 2: Sign in). In both cases, create a personal access token and send it as a bearer token. It draws on the same scope catalog as a browser sign-in, with one difference that matters: a personal access token cannot carrymcp:write or offline_access, which only browser consent can grant (see Scopes).
Go to Administration > Developers and open Personal access tokens. The same section is on your account page. Application keys sit on that page too; see API keys for those.
Creating a token asks for:
- A name, so the token is identifiable later in the table
- An expiry in days, up to a maximum of 90
- Where this token can act: one workspace, or every workspace in the organization
- The scopes it carries, offered as the intersection of the tenant policy, your team role, and your organization’s entitlements
mcp:read, which is all a default organization policy allows, connects and authenticates normally but can call just two introspection tools, whoami and list_tool_permissions. Running searches needs screening:search, and reading profiles needs screening:read.
The organization in this example has already allowed the screening scopes. In one that has not, this list shows Connect and list available tools on its own.
The plaintext token is shown exactly once. Copy it into your secrets manager before closing the dialog; Minerva stores only a hash and cannot show it again.
Send it as a bearer token on the MCP endpoint. Every client sends the same header, whatever its own configuration looks like:
Step 1: Set the environment variable
Both ways of registering the server below only name the variable, so set it first:Step 2: Register the server with a bearer token
Either use the CLI:~/.codex/config.toml by hand:
MINERVA_MCP_TOKEN and nothing else, so the export above is the part that has to be in place whichever block you use.
Step 3: Verify the connection
codex mcp list then reports the server as enabled with Bearer token as its auth. That describes the configuration and not the credential: it reads the same whether or not MINERVA_MCP_TOKEN is set.
codex mcp add writes bearer_token_env_var, which names the variable rather
than storing the token. Codex also accepts a literal Authorization value
under http_headers, which puts the token in ~/.codex/config.toml, so
prefer the environment variable. Set it from your secrets manager where you
can: typing the export by hand puts the live token in your shell history.
Codex refuses the bearer_token key outright. Setting that key fails with the
message bearer_token is not supported for streamable_http. Whatever client
you use, keep any file that holds a token out of source control.When to prefer a token over the browser flow
Admin enablement
Hosted MCP access is off by default. Before anyone in an organization can connect an agent, someone with the Admin role or above has to turn it on and choose what agent tokens may do. This gate is the most common reason a connection attempt fails. Go to Administration > Configuration > Authentication and open Hosted MCP access. The same page holds the SAML SSO and SCIM settings. Three settings matter:- Allow users to create hosted MCP personal access tokens is the master switch for the organization; the other two settings only matter once it is on.
- Minimum team role is the lowest team role permitted to hold an MCP token. Defaults to Developer.
- What tokens may do is the complete set of scopes any token in this organization may ever carry, grouped by product area, and explained in Scopes. A new policy allows only
mcp:read.
Leaving Minimum team role at Member while allowing administration
scopes does not widen access, because each scope also carries its own role
floor. The panel names any allowed scopes that sit above the policy minimum.
That is informational, not an error.
Scopes
A token carries an explicit list of scopes. Most need a team role, and some also need an organization entitlement. The workspace-scoped ones have one wrinkle, described under the table.
Browser consent only means a client can request the scope during browser sign-in, but it can never be added to a personal access token.
mcp:write does not bypass anything: a write it covers still needs whatever entitlement the specific scope needs, so it reaches risk assessments only in an organization that has the agent risk assessment beta, and identity verification only where ID verification is enabled.
How scopes are narrowed
Minerva advertises the whole catalog above, and most agents request everything a server advertises on first login. That is expected and is not an error. Minerva grants the intersection of:- The scopes the agent requested
- The scopes the tenant token policy allows
- The scopes your team role and your organization’s entitlements permit
risk:read and risk:write if the policy and your role allow them. There is no single workspace to check the beta against when the token is issued, so the check happens on each call instead, against the workspace that call names. The same token therefore succeeds in a workspace that has the beta and is refused in one that does not.
A token pinned to one workspace carries them only if that workspace holds the beta. So pinning does not get you more capability: it gets you less, and more predictably. The reason to pin is blast radius, not reach.
Refused risk calls are therefore about the workspace you are calling into, not about the token. See Troubleshooting.
Troubleshooting
In the browser
Both rate limits key on your source IP, so a shared office or CI egress can trip them without anyone misbehaving. Neither one touches existing tokens, tool calls, discovery, or the authorization step itself: those keep working while new logins are throttled.
A greyed-out Create token button has two different causes, and the message on screen tells you which. This one shows Personal access tokens are disabled for this organization, meaning nobody here has hosted MCP access yet:
And this one shows Personal access tokens require the … role or higher, meaning the organization has enabled it but your own team role sits below the minimum the policy sets, which is a different fix:
And this is the same organization from the admin’s side, where the switch is turned off:
A browser that opens the consent URL without a usable authorization request gets one of two screens, and which one you get tells you what went wrong.
If the request ID is well formed but no longer good (the link expired, or it was already used because the login ran twice), you get the invalid-request screen. Re-run the login command from the client so it starts a fresh request.
If there is no request ID at all, or a malformed one (a hand-typed URL, or a link truncated in a chat message), you get an install landing page instead. It repeats the endpoints and carries copy-paste snippets for some clients, but it cannot complete a login on its own: the commands earlier in this guide are the authoritative set.
From an agent call
The three refusal codes an agent can meet (validation_error, workspace_forbidden and entitlement_required) are authorization outcomes, not transport failures. Minerva returns them as ordinary MCP tool results: HTTP 200 with isError: true, and the code, the message, and a retryable flag in the JSON inside content[0].text. A 401 therefore means authentication failed, while these mean the call was understood and refused. validation_error and entitlement_required are never retryable, and neither is a genuine workspace_forbidden refusal. The one retryable case is the service-problem form of workspace_forbidden, which says so in its message and sets retryable: true.
On opencode, two commands help isolate an authorization problem:
Best practices
- Use
https://mcp.gominerva.com/mcp/readonlyfor any agent that does not need to write, instead of relying on scopes alone - Grant one connection per purpose rather than one broad connection reused everywhere, so revoking an agent does not disturb the others
- Bind tokens to a single workspace unless an automation genuinely spans all of them
- Keep the tenant policy as the ceiling you actually intend, and widen it in response to real workflows rather than in advance
- Prefer the browser login for people, and reserve personal access tokens for automations that truly cannot open a browser
- Store personal access tokens in a secrets manager, never in source control or in an agent configuration file committed to a repository
- Schedule rotation before the 90-day ceiling rather than discovering it when a pipeline fails
- Review the token table periodically and revoke tokens whose last-used timestamp shows they are no longer needed
- Remember that an agent inherits its authorizer’s permissions, so review team roles when someone changes job