Skip to content

Blog

MCP read-only access: enforce and test the boundary

Reading should work and writing should not. That boundary needs a concrete setting and a test you can explain.

Published on · by tracevero · Reading time 4 minutes (678 words)

A read-only setup starts at the data source. If you only need information from one project, choose a role with exactly that access. Then document the tools exposed by the MCP server and the approvals required by your client. The permission planner puts those checks into an order you can follow. This guide covers the boundaries of a reading connection; use the relevant setup guide for the initial connection itself. Keep your first test small enough to inspect the entire result.

Three meanings of read-only

From scope to evidence 1. Scope Name the target. 2. Limit Set permissions. 3. Test Record the result.
Proposed test sequence; carry out the checks in your own environment.
Description and enforcement
TermMeaningAlso check
readOnlyHintTool describes itself as readingTrust in the source and actual effect
Read-only modeServer limits exposed operationsDocumentation and visible tool list
Reader roleData source restricts the accountProject scope and assigned permissions

The MCP specification treats tool annotations as hints. A client cannot rely on a hint from an untrusted server as a permission boundary. In particular, readOnlyHint does not remove privileges from a token. Describe each observation precisely: a tool declares a hint, a server removes write operations, or an account is unable to write. Those observations may work together, but they are not interchangeable. Record the relevant setting at each layer instead of describing the entire connection with one unchecked label.

Example: limit GitHub to reading

The GitHub MCP Server documents a dedicated read-only mode. Its configuration guide lists the X-MCP-Readonly header or a read-only URL path for remote access. Local options include --read-only and GITHUB_READ_ONLY. Take the complete configuration from the current provider instructions for your startup method. Also restrict the account to the required repositories and read permissions. The server mode removes write tools; it does not replace the account setting. Follow the GitHub setup guide for the connection itself.

A small test with explicit boundaries

  1. Create a test record and capture its initial state outside the reading connection being tested.

  2. Inspect the source role, project scope and credential expiration. Enable the documented server mode as an additional restriction.

  3. Reconnect the client and inspect its tool list. Compare available operations with the intended task.

  4. Read the known record. Compare the response with the original and confirm that its content remains unchanged.

  5. If a negative test is necessary, run it only in an authorized, isolated test destination. Inspect the destination independently of any error message.

A rejected write attempt establishes only the tested combination of account, destination and operation. It does not establish the behavior of every other function. Record those boundaries explicitly. When a tool is missing, check server mode and roles before granting more access. The troubleshooting navigator helps distinguish a missing function from a broken connection. Avoid changing several settings at once: otherwise you cannot tell which boundary produced the result.

What read access still allows

A reading connection can retrieve large volumes of confidential data. Restrict the visible dataset as well, for example to a test project instead of the entire account. Check where responses are stored and which other tools receive them. Retrieved text can contain third-party instructions; use the checks in the permission guide for this case. Repeat the affected tests after changing a role, server version or tool selection. Record the date and observed result so an older observation is not mistaken for current evidence.

Does readOnlyHint block access?
No. It is a tool hint. The actual boundary must be enforced by the data source or runtime environment.
Is there a universal read-only switch for every server?
No. Read the specific server documentation and also restrict the account.
Should I run the negative test in production?
Use an isolated and explicitly authorized test destination. An unexpectedly successful call must not change production data.
Can read-only access expose information?
Yes. Reading can return confidential content. Scope, transfer and storage also need limits.

  1. MCP tools and annotations
    Show retrieval commandcurl -s https://modelcontextprotocol.io/specification/2025-11-25/server/tools
  2. GitHub MCP server configuration
    Show retrieval commandcurl -s https://github.com/github/github-mcp-server/blob/main/docs/server-configuration.md
  3. MCP security best practices
    Show retrieval commandcurl -s https://modelcontextprotocol.io/docs/2025-11-25/tutorials/security/security_best_practices

Put it into practice

All posts

tracevero · https://tracevero.com/blog/mcp-read-only-access