Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions apps/mcp/src/server/tools/get-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
} from "./output-schemas"
import { textContent, type ToolDeps } from "./types"

// An out-of-space document reports "not found" on purpose, so the id is not an existence oracle.
export function register(deps: ToolDeps) {
const inputSchema = z.object({
documentId: z
Expand All @@ -22,24 +21,15 @@ export function register(deps: ToolDeps) {
{
title: "Get Document",
description:
"Read one stored document by ID, including its summary and available content. Use listDocuments in the intended space to discover document IDs.",
"Read one stored document by ID from any space you can access, including its summary and available content. Use listDocuments to discover document IDs.",
inputSchema,
outputSchema: getDocumentOutputSchema,
annotations: READ_ONLY_TOOL_ANNOTATIONS,
},
async (args) => {
try {
const effectiveTag = await deps.resolveContainerTag()
const client = deps.getClient()
const document = await client.getDocument(args.documentId)
Comment on lines 31 to 32

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve scoped-space authorization for direct reads

For a restricted organization member or an OAuth connection granted only selected spaces, this unqualified direct lookup can return a same-organization document whose containerTags are outside the caller's grant when its ID is retained or otherwise known. The repository models these finer-grained boundaries in SessionInfo.scope.tags and SessionInfo.containerTags, while the stated upstream guarantee is only organization scoping; removing the sole tag check therefore exposes the document's full content rather than merely enabling reads from other authorized spaces. Replace the active-space-only check with validation that at least one document tag is among the spaces visible to this token.

Useful? React with 👍 / 👎.

const docTags = document.containerTags
if (
Array.isArray(docTags) &&
docTags.length > 0 &&
!docTags.includes(effectiveTag)
) {
throw new Error("Document not found")
}
const { content, truncated } = getDocumentContent(document)
const structuredContent: GetDocumentOutput = {
document: {
Expand Down
Loading