Sasha MCP reference

readDoc

Read a knowledge document

Read the content of one document. Either give the project id and a path within it (this is the form listDocs returns, whose paths are relative to the project), or give one combined path of the form "<project>/<path>", which is the form searchKnowledge returns. Large documents are paged: if truncated is true, call again with offset = nextOffset. For a document in your own home the result also carries an opaque version identifying the bytes you read: pass it to writeDoc or editDoc as expectedVersion to make the change conditional on nothing else having changed the file, and pass it back here as version to keep paging bound to the same bytes.

Arguments

ArgumentTypeRequiredDescription
projectstringoptionalProject id from listProjects; omit if path already starts with it
pathstringrequiredDocument path, e.g. "acme/rate-card.md", or "rate-card.md" when project is given (the latter is what listDocs returns)
offsetintegeroptionalByte offset to start from (for paging)
maxBytesintegeroptionalMax bytes to return (default 50000)
versionstringoptionalThe version from an earlier readDoc of this document, to pin later pages to the same bytes. The read is refused as a conflict if the file has changed since. There is no history, so the earlier bytes cannot be returned.
expectedVersionstringoptionalNot used here. Pass version instead. Supplying this is an error rather than a silent no-op.

Scopes

knowledge:read

Annotations

  • Read only: yes
  • Destructive: no

When to use

Use readDoc to read the full text of a document that listDocs or searchKnowledge found. Always read the current document before you state a fact from it or change it.

The tool needs the knowledge:read scope. There are two ways to name the document:

  • project and path, where path is relative to the project. This is the form that listDocs returns.
  • path alone, in the form <project>/<path>. This is the form that searchKnowledge returns.

Paging:

  • One call returns at most maxBytes bytes. The default and the maximum is 50,000.
  • When truncated is true, call again with offset set to nextOffset. nextOffset is present only when truncated is true.
  • Page edges never split a character, so bytesReturned can be a little less than maxBytes. Join the pages in order to get the document.

The version field:

  • A member's connection gets a version when this instance has document writing turned on for that kind of project. Admin and staff connections never get one. There is also no version when the path is one that the write tools cannot take, for example a file type they do not support.
  • Pass version to writeDoc or editDoc as expectedVersion, so that the change fails if someone else changed the file.
  • Pass it back to readDoc as version when you read the next page. The read then fails if the file changed between pages. There is no history, so the earlier bytes cannot be returned.
  • Do not send expectedVersion to readDoc. It is refused. The argument here is version.

A member can read their own home and each ordinary project where they hold a grant. Admin and staff can read every active ordinary project, but no member home. Paths whose first segment is skills or prompts, and paths with a segment that starts with ., are never readable.

Example

The first page of a document, read by a member's connection on an instance with shared-project writing turned on:

{ "project": "northwind-advisory", "path": "pricing-policy.md", "maxBytes": 400 }
{
  "path": "northwind-advisory/pricing-policy.md",
  "content": "# Pricing policy\n\nOwner: Commercial lead. Last reviewed: March 2026.\n\nThis policy sets how Northwind Advisory prices client work. It applies to every proposal, statement of work and change request. A partner must approve any departure from it in writing.\n\n## Day rates\n\nWe price most work on a day rate. The standard rates are:\n\n- Partner: £1,450 per day\n- Senior consultant: £1,050 per day\n- Consu",
  "totalBytes": 1730,
  "offset": 0,
  "bytesReturned": 400,
  "truncated": true,
  "nextOffset": 400,
  "version": "AQ-example-opaque-version"
}

The next page, pinned to the same bytes:

{ "path": "northwind-advisory/pricing-policy.md", "offset": 400, "maxBytes": 400, "version": "AQ-example-opaque-version" }

Refusals and what to do

  • Error in readDoc: Not found: the project does not exist or this person cannot see it, or the path is not allowed (a first segment skills or prompts, a segment that starts with ., an empty segment, or a segment that contains %). Call listProjects and listDocs and use a project and path from their results.
  • Error in readDoc: Document not found: the project is visible, but the document is not there. Check the path with listDocs or searchKnowledge.
  • Error in readDoc: version_conflict:stale_version: you passed version, and the file changed after that read. Call readDoc again from offset 0 without version, and use the new text.
  • Error in readDoc: handle_invalid:handle_unverifiable: this connection cannot check a version for this document, for example because it is an admin or staff connection, or writing is off for this kind of project. Read again without version.
  • Error in readDoc: handle_invalid:handle_malformed or handle_invalid:handle_rejected: the version is not one that this instance issued for this document. Use the exact version from an earlier readDoc of the same document.
  • Error in readDoc: invalid_input:use_version_not_expected_version: you sent expectedVersion. Send version instead.
  • If the connection does not hold knowledge:read, the tool is not in your tool list, and a call to it returns MCP error -32602: Tool readDoc not found. Read the permissions section of getDocs. A scope is never added to an existing connection: the person must reconnect, or mint a new token, with knowledge:read.

Related

  • searchKnowledge and listDocs find the path to read.
  • listProjects gives the project ids.
  • The member-home-write family (writeDoc and editDoc) takes the version from this tool as expectedVersion.
made with bernard

Cookie settings