A comment on a whole document is a second chat. “The pricing section is vague” forces the next person to hunt for the sentence you meant, and by the time they find it the section has been rewritten and the comment is about nothing. The interesting problem is not leaving a comment. It is keeping it attached to the right words after the document changes underneath it.
The sentence
Take the diagram from the last post. One line is the one a reviewer should answer:
The agent holds one MCP URL.
That is the whole claim. Highlight it, leave the note, and the thread stays on those words when the boxes around it change.

What an anchor actually is
ShareCube stores two things per thread: the quoted text and its character range in the body. The quote is the identity of the comment. The range is a hint for finding it fast. Over MCP the same thing is create_comment with an anchor. start and end are offsets into the current body, and if the quote appears more than once, occurrenceIndex says which one:
{
"body": "This is the line I would send a reviewer. The comment should stay on this sentence when the diagram around it changes.",
"anchor": {
"quote": "The agent holds one MCP URL.",
"start": 5897,
"end": 5925,
"occurrenceIndex": 0
}
}
I published that diagram to a ShareCube project and left this exact thread on that sentence. The offsets I sent did not match the stored body exactly. The server corrected them to the stored text and kept the quote. That is the point of storing the quote and not only the range: the words are the truth, the numbers are a cache.

Mentions use a person id, not a display name ([@Name](mention://user/…)). Unresolved @text is just text, and it does not notify anyone. That is on purpose. A mention is a notification, and a notification should not fire because a string happened to look like a name.
Orphaned is a signal, not a failure
A thread is open, resolved, or orphaned. Orphaned means the quote no longer matches the body. Most tools handle this by either deleting the comment or silently reattaching it to whatever is now at that offset, and both lose information. The first throws away the review. The second attaches “this claim is wrong” to a sentence nobody made a claim in.
ShareCube keeps the thread and marks it. An orphaned comment is the record that someone edited the words a reviewer had an opinion about, which is exactly the edit you want to look at. Resolve it when the wording is fixed. Reopen it if it was not.
The same logic runs the other way. Each content save creates a new version, and when an agent updates a document it passes the version id it read. If a human saved in between, the write is refused instead of overwriting the human’s edit. Reload, re-apply, save. The comment anchors survive the version, and version history lets you restore an older body, which writes a new current version rather than deleting the ones after it.
Who can do what
Roles are the usual four: Viewer, Commenter, Editor, Owner. Viewers read threads, Commenters write them, Editors publish and can moderate other people’s threads. A public share link can still be view-only, and an admin can cap how public the org is allowed to be. Comments only work in Preview, because Source is for editing and a highlight in raw markdown is not a stable anchor.
Agents have the same surface over MCP: list_comments, create_comment, resolve_comment. The useful case is an agent that publishes a document and then leaves its own review notes on the sentences it is least sure about, so the human opens the link and starts at the right place.
The handoff
The agent returns console_url after it publishes. You review on the sentence, resolve the thread, and send share_url when the visibility is what you want. Access still follows that setting. A share path does not bypass a private artifact.
That is the loop I wanted in June: the file leaves the chat, the comment stays on the words, and the link is the only thing a stranger needs.
Comment anchors, mentions, and resolve are covered in the ShareCube guide.