@shelv/mcp 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server.ts","../../src/config.ts","../../src/errors.ts","../../src/http-client.ts","../../src/tools/create-shelf.ts","../../src/tools/common.ts","../../src/tools/get-shelf-tree.ts","../../src/tools/hydrate-shelf.ts","../../src/tools/list-shelves.ts","../../src/tools/read-shelf-file.ts","../../src/tools/search-shelf.ts","../../src/tools/index.ts","../../src/transports/http.ts","../../src/transports/stdio.ts","../../src/bin/shelv-mcp.ts"],"sourcesContent":["import { createShelvClient } from \"@shelv/adapters\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { loadConfig, type McpConfig } from \"./config\";\nimport { McpToolError } from \"./errors\";\nimport { ShelvHttpClient } from \"./http-client\";\nimport { registerShelvTools } from \"./tools\";\nimport type { ToolContext, ToolExtra } from \"./tools/context\";\n\nexport interface ShelvMcpRuntime {\n server: McpServer;\n config: McpConfig;\n}\n\nfunction validateApiKey(token: string): string {\n const trimmed = token.trim();\n if (!trimmed.startsWith(\"sk_\")) {\n throw new McpToolError({\n code: \"AUTH_ERROR\",\n message: \"Shelv API key must use sk_ prefix\",\n status: 401,\n retryable: false,\n });\n }\n\n return trimmed;\n}\n\nfunction createContext(config: McpConfig): ToolContext {\n return {\n config,\n getApiKey(extra?: ToolExtra) {\n const authToken = extra?.authInfo?.token;\n if (typeof authToken === \"string\" && authToken.trim().length > 0) {\n return validateApiKey(authToken);\n }\n\n if (config.apiKey) {\n return validateApiKey(config.apiKey);\n }\n\n throw new McpToolError({\n code: \"AUTH_ERROR\",\n message:\n \"Missing Shelv API key. Set SHELV_API_KEY or provide Authorization bearer token.\",\n status: 401,\n retryable: false,\n });\n },\n createShelvClient(apiKey: string) {\n return createShelvClient({\n apiKey,\n apiBaseUrl: config.apiBaseUrl,\n });\n },\n createHttpClient(apiKey: string) {\n return new ShelvHttpClient({\n apiKey,\n apiBaseUrl: config.apiBaseUrl,\n });\n },\n };\n}\n\nexport function createShelvMcpRuntime(env: NodeJS.ProcessEnv = process.env): ShelvMcpRuntime {\n const config = loadConfig(env);\n const context = createContext(config);\n\n const server = new McpServer(\n {\n name: \"shelv-mcp\",\n version: \"0.1.0\",\n },\n {\n instructions:\n \"Shelv MCP server for creating, listing, reading, searching, and hydrating document shelves.\",\n },\n );\n\n registerShelvTools(server, context);\n\n return { server, config };\n}\n","const API_BASE_URL = \"https://api.shelv.dev\";\n\nexport type TransportMode = \"stdio\" | \"http\";\n\nexport interface McpConfig {\n apiBaseUrl: string;\n apiKey?: string;\n transport: TransportMode;\n httpHost: string;\n httpPort: number;\n enableWriteTools: boolean;\n searchMaxFiles: number;\n searchMaxBytes: number;\n searchMaxMatches: number;\n readMaxBytes: number;\n}\n\nfunction parseBoolean(value: string | undefined, fallback: boolean): boolean {\n if (value === undefined) return fallback;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"true\" || normalized === \"1\" || normalized === \"yes\") {\n return true;\n }\n if (normalized === \"false\" || normalized === \"0\" || normalized === \"no\") {\n return false;\n }\n throw new Error(`Invalid boolean value: ${value}`);\n}\n\nfunction parseInteger(\n value: string | undefined,\n fallback: number,\n label: string,\n): number {\n if (value === undefined || value.trim() === \"\") {\n return fallback;\n }\n\n const parsed = Number.parseInt(value, 10);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new Error(`${label} must be a positive integer`);\n }\n\n return parsed;\n}\n\nfunction parseTransport(value: string | undefined): TransportMode {\n if (!value || value.trim() === \"\") {\n return \"stdio\";\n }\n\n if (value === \"stdio\" || value === \"http\") {\n return value;\n }\n\n throw new Error(\"SHELV_MCP_TRANSPORT must be either 'stdio' or 'http'\");\n}\n\nexport function loadConfig(env: NodeJS.ProcessEnv = process.env): McpConfig {\n return {\n apiBaseUrl: API_BASE_URL,\n apiKey: env.SHELV_API_KEY?.trim() || undefined,\n transport: parseTransport(env.SHELV_MCP_TRANSPORT),\n httpHost: env.SHELV_MCP_HTTP_HOST?.trim() || \"127.0.0.1\",\n httpPort: parseInteger(env.SHELV_MCP_HTTP_PORT, 3334, \"SHELV_MCP_HTTP_PORT\"),\n enableWriteTools: parseBoolean(env.SHELV_MCP_ENABLE_WRITE_TOOLS, false),\n searchMaxFiles: parseInteger(\n env.SHELV_MCP_SEARCH_MAX_FILES,\n 500,\n \"SHELV_MCP_SEARCH_MAX_FILES\",\n ),\n searchMaxBytes: parseInteger(\n env.SHELV_MCP_SEARCH_MAX_BYTES,\n 5_000_000,\n \"SHELV_MCP_SEARCH_MAX_BYTES\",\n ),\n searchMaxMatches: parseInteger(\n env.SHELV_MCP_SEARCH_MAX_MATCHES,\n 200,\n \"SHELV_MCP_SEARCH_MAX_MATCHES\",\n ),\n readMaxBytes: parseInteger(\n env.SHELV_MCP_READ_MAX_BYTES,\n 250_000,\n \"SHELV_MCP_READ_MAX_BYTES\",\n ),\n };\n}\n","import { AdapterError } from \"@shelv/adapters\";\n\nexport type McpErrorCode =\n | \"INPUT_ERROR\"\n | \"AUTH_ERROR\"\n | \"BILLING_REQUIRED\"\n | \"NOT_FOUND\"\n | \"NOT_READY\"\n | \"RATE_LIMITED\"\n | \"UPSTREAM_ERROR\"\n | \"LOCAL_IO_ERROR\";\n\nexport interface McpToolErrorData {\n code: McpErrorCode;\n message: string;\n status?: number;\n details?: unknown;\n retryable?: boolean;\n}\n\nexport class McpToolError extends Error {\n readonly code: McpErrorCode;\n readonly status?: number;\n readonly details?: unknown;\n readonly retryable?: boolean;\n\n constructor(data: McpToolErrorData, options?: { cause?: unknown }) {\n super(data.message, options);\n this.name = \"McpToolError\";\n this.code = data.code;\n this.status = data.status;\n this.details = data.details;\n this.retryable = data.retryable;\n }\n}\n\nexport class ApiRequestError extends Error {\n readonly method: string;\n readonly path: string;\n readonly status: number;\n readonly body: unknown;\n\n constructor(\n method: string,\n path: string,\n status: number,\n body: unknown,\n options?: { cause?: unknown },\n ) {\n const message =\n typeof body === \"object\" &&\n body !== null &&\n \"message\" in body &&\n typeof (body as { message: unknown }).message === \"string\"\n ? (body as { message: string }).message\n : `Shelv API request failed (${status})`;\n\n super(message, options);\n this.name = \"ApiRequestError\";\n this.method = method;\n this.path = path;\n this.status = status;\n this.body = body;\n }\n}\n\nfunction statusToCode(status: number): McpErrorCode {\n if (status === 400) return \"INPUT_ERROR\";\n if (status === 401 || status === 403) return \"AUTH_ERROR\";\n if (status === 402) return \"BILLING_REQUIRED\";\n if (status === 404) return \"NOT_FOUND\";\n if (status === 409) return \"NOT_READY\";\n if (status === 429) return \"RATE_LIMITED\";\n return \"UPSTREAM_ERROR\";\n}\n\nfunction extractStatusFromMessage(message: string): number | undefined {\n const match = message.match(/\\((\\d{3})\\)/);\n if (!match) return undefined;\n const status = Number.parseInt(match[1] ?? \"\", 10);\n return Number.isFinite(status) ? status : undefined;\n}\n\nexport function toMcpToolError(\n error: unknown,\n fallbackMessage = \"Request failed\",\n): McpToolError {\n if (error instanceof McpToolError) {\n return error;\n }\n\n if (error instanceof ApiRequestError) {\n return new McpToolError(\n {\n code: statusToCode(error.status),\n status: error.status,\n message: error.message,\n details: error.body,\n retryable: error.status >= 500 || error.status === 429,\n },\n { cause: error },\n );\n }\n\n if (error instanceof AdapterError) {\n if (error.code === \"TREE_FETCH_FAILED\") {\n const status = extractStatusFromMessage(error.message);\n return new McpToolError(\n {\n code: status ? statusToCode(status) : \"UPSTREAM_ERROR\",\n status,\n message: error.message,\n retryable: status ? status >= 500 || status === 429 : false,\n },\n { cause: error },\n );\n }\n\n if (error.code === \"ARCHIVE_TIMEOUT\") {\n return new McpToolError(\n {\n code: \"UPSTREAM_ERROR\",\n message: error.message,\n retryable: true,\n },\n { cause: error },\n );\n }\n\n if (error.code === \"ARCHIVE_PARSE_FAILED\") {\n return new McpToolError(\n {\n code: \"UPSTREAM_ERROR\",\n message: error.message,\n retryable: false,\n },\n { cause: error },\n );\n }\n\n return new McpToolError(\n {\n code: \"UPSTREAM_ERROR\",\n message: error.message,\n retryable: false,\n },\n { cause: error },\n );\n }\n\n if (error instanceof Error) {\n return new McpToolError(\n {\n code: \"UPSTREAM_ERROR\",\n message: error.message || fallbackMessage,\n retryable: false,\n },\n { cause: error },\n );\n }\n\n return new McpToolError({\n code: \"UPSTREAM_ERROR\",\n message: fallbackMessage,\n details: error,\n retryable: false,\n });\n}\n\nexport function serializeToolError(error: McpToolError): {\n code: McpErrorCode;\n status?: number;\n details?: unknown;\n retryable?: boolean;\n message: string;\n} {\n return {\n code: error.code,\n status: error.status,\n details: error.details,\n retryable: error.retryable,\n message: error.message,\n };\n}\n","import { ApiRequestError } from \"./errors\";\n\nexport interface ShelfSummary {\n publicId: string;\n name: string;\n status: string;\n template: string | null;\n pageCount: number | null;\n reviewMode: boolean;\n createdAt: string;\n updatedAt: string;\n [key: string]: unknown;\n}\n\nexport interface ListShelvesResponse {\n data: ShelfSummary[];\n pagination: {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n };\n}\n\nexport interface CreateShelfInput {\n pdfBytes: Uint8Array;\n fileName: string;\n name?: string;\n template?: \"book\" | \"legal-contract\" | \"academic-paper\";\n review?: boolean;\n}\n\nexport interface ShelvHttpClientConfig {\n apiKey: string;\n apiBaseUrl: string;\n fetchImplementation?: typeof fetch;\n}\n\nexport class ShelvHttpClient {\n private readonly apiKey: string;\n private readonly apiBaseUrl: string;\n private readonly fetchImplementation: typeof fetch;\n\n constructor(config: ShelvHttpClientConfig) {\n this.apiKey = config.apiKey;\n this.apiBaseUrl = config.apiBaseUrl.replace(/\\/$/, \"\");\n this.fetchImplementation = config.fetchImplementation ?? fetch;\n }\n\n async listShelves(params?: {\n page?: number;\n limit?: number;\n }): Promise<ListShelvesResponse> {\n const search = new URLSearchParams();\n if (params?.page) search.set(\"page\", String(params.page));\n if (params?.limit) search.set(\"limit\", String(params.limit));\n\n const path =\n search.size > 0 ? `/v1/shelves?${search.toString()}` : \"/v1/shelves\";\n\n return this.requestJson<ListShelvesResponse>(\"GET\", path);\n }\n\n async createShelf(input: CreateShelfInput): Promise<ShelfSummary> {\n const formData = new FormData();\n formData.append(\n \"file\",\n new Blob([Buffer.from(input.pdfBytes)], { type: \"application/pdf\" }),\n input.fileName,\n );\n\n if (input.name) formData.append(\"name\", input.name);\n if (input.template) formData.append(\"template\", input.template);\n if (typeof input.review === \"boolean\") {\n formData.append(\"review\", input.review ? \"true\" : \"false\");\n }\n\n return this.requestJson<ShelfSummary>(\"POST\", \"/v1/shelves\", {\n body: formData,\n });\n }\n\n private async requestJson<T>(\n method: \"GET\" | \"POST\",\n path: string,\n options?: { body?: BodyInit },\n ): Promise<T> {\n const response = await this.fetchImplementation(`${this.apiBaseUrl}${path}`, {\n method,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: options?.body,\n });\n\n if (!response.ok) {\n throw new ApiRequestError(\n method,\n path,\n response.status,\n await this.parseErrorBody(response),\n );\n }\n\n return (await response.json()) as T;\n }\n\n private async parseErrorBody(response: Response): Promise<unknown> {\n const contentType = response.headers.get(\"content-type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n try {\n return await response.json();\n } catch {\n return { message: \"Failed to parse API error body\" };\n }\n }\n\n try {\n return await response.text();\n } catch {\n return null;\n }\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { McpToolError } from \"../errors\";\nimport { errorResult, successResult } from \"./common\";\nimport type { ToolContext } from \"./context\";\n\nconst MAX_PDF_BYTES = 300 * 1024 * 1024;\n\nconst inputSchema = {\n pdf_path: z.string().min(1),\n name: z.string().min(1).max(100).optional(),\n template: z.enum([\"book\", \"legal-contract\", \"academic-paper\"]).optional(),\n review: z.boolean().optional(),\n};\n\nconst outputSchema = {\n shelf: z.object({\n publicId: z.string(),\n name: z.string(),\n status: z.string(),\n template: z.string().nullable(),\n pageCount: z.number().nullable(),\n reviewMode: z.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n }),\n};\n\nasync function assertPdfFile(filePath: string): Promise<void> {\n const stats = await fs.stat(filePath).catch(() => null);\n if (!stats || !stats.isFile()) {\n throw new McpToolError({\n code: \"INPUT_ERROR\",\n message: \"pdf_path must point to an existing file\",\n status: 400,\n retryable: false,\n });\n }\n\n if (stats.size > MAX_PDF_BYTES) {\n throw new McpToolError({\n code: \"INPUT_ERROR\",\n message: \"PDF exceeds 300 MB limit\",\n status: 400,\n retryable: false,\n });\n }\n\n if (path.extname(filePath).toLowerCase() !== \".pdf\") {\n throw new McpToolError({\n code: \"INPUT_ERROR\",\n message: \"Only .pdf files are supported\",\n status: 400,\n retryable: false,\n });\n }\n\n const handle = await fs.open(filePath, \"r\");\n try {\n const header = Buffer.alloc(5);\n await handle.read(header, 0, 5, 0);\n if (header.toString(\"utf8\") !== \"%PDF-\") {\n throw new McpToolError({\n code: \"INPUT_ERROR\",\n message: \"File does not appear to be a valid PDF\",\n status: 400,\n retryable: false,\n });\n }\n } finally {\n await handle.close();\n }\n}\n\nexport function registerCreateShelfTool(\n server: McpServer,\n context: ToolContext,\n): void {\n server.registerTool(\n \"create_shelf\",\n {\n title: \"Create Shelf\",\n description: \"Upload a local PDF and create a shelf\",\n inputSchema,\n outputSchema,\n annotations: { readOnlyHint: false },\n },\n async (input, extra) => {\n try {\n const absolutePath = path.resolve(input.pdf_path);\n await assertPdfFile(absolutePath);\n\n const fileBytes = new Uint8Array(await fs.readFile(absolutePath));\n const apiKey = context.getApiKey(extra);\n const client = context.createHttpClient(apiKey);\n const shelf = await client.createShelf({\n pdfBytes: fileBytes,\n fileName: path.basename(absolutePath),\n name: input.name,\n template: input.template,\n review: input.review,\n });\n\n return successResult(`Created shelf ${shelf.publicId}`, { shelf });\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n","import path from \"node:path\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { McpToolError, serializeToolError, toMcpToolError } from \"../errors\";\n\nexport function successResult(\n text: string,\n structuredContent: Record<string, unknown>,\n): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n structuredContent,\n };\n}\n\nexport function errorResult(error: unknown): CallToolResult {\n const normalized = toMcpToolError(error, \"Tool execution failed\");\n\n return {\n isError: true,\n content: [{ type: \"text\", text: normalized.message }],\n structuredContent: {\n error: serializeToolError(normalized),\n },\n };\n}\n\nexport function ensureRelativePath(inputPath: string): string {\n const trimmed = inputPath.trim();\n\n if (!trimmed) {\n throw new McpToolError({\n code: \"INPUT_ERROR\",\n message: \"Path is required\",\n status: 400,\n retryable: false,\n });\n }\n\n if (trimmed.includes(\"\\\\\") || trimmed.includes(\"\\0\")) {\n throw new McpToolError({\n code: \"INPUT_ERROR\",\n message: \"Path contains unsupported characters\",\n status: 400,\n retryable: false,\n });\n }\n\n const normalized = path.posix.normalize(trimmed);\n if (normalized === \".\" || normalized === \"\") {\n throw new McpToolError({\n code: \"INPUT_ERROR\",\n message: \"Path must reference a file under the shelf root\",\n status: 400,\n retryable: false,\n });\n }\n\n if (\n normalized === \"..\" ||\n normalized.startsWith(\"../\") ||\n normalized.startsWith(\"/\")\n ) {\n throw new McpToolError({\n code: \"INPUT_ERROR\",\n message: \"Path traversal is not allowed\",\n status: 400,\n retryable: false,\n });\n }\n\n return normalized;\n}\n\nexport function safeJoin(baseDir: string, relativePath: string): string {\n const resolvedBase = path.resolve(baseDir);\n const candidate = path.resolve(resolvedBase, relativePath);\n\n if (\n candidate !== resolvedBase &&\n !candidate.startsWith(`${resolvedBase}${path.sep}`)\n ) {\n throw new McpToolError({\n code: \"LOCAL_IO_ERROR\",\n message: `Unsafe output path: ${relativePath}`,\n retryable: false,\n });\n }\n\n return candidate;\n}\n\nexport function truncateUtf8(\n content: string,\n maxBytes: number,\n): { value: string; truncated: boolean; bytes: number } {\n const totalBytes = Buffer.byteLength(content, \"utf8\");\n if (totalBytes <= maxBytes) {\n return { value: content, truncated: false, bytes: totalBytes };\n }\n\n let low = 0;\n let high = content.length;\n while (low < high) {\n const mid = Math.ceil((low + high) / 2);\n const candidateBytes = Buffer.byteLength(content.slice(0, mid), \"utf8\");\n if (candidateBytes <= maxBytes) {\n low = mid;\n } else {\n high = mid - 1;\n }\n }\n\n const value = content.slice(0, low);\n return {\n value,\n truncated: true,\n bytes: Buffer.byteLength(value, \"utf8\"),\n };\n}\n\nexport function inferContentType(filePath: string): string {\n const ext = path.extname(filePath).toLowerCase();\n\n if (ext === \".md\") return \"text/markdown\";\n if (ext === \".json\") return \"application/json\";\n if (ext === \".txt\") return \"text/plain\";\n\n return \"text/plain\";\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { errorResult, successResult } from \"./common\";\nimport type { ToolContext } from \"./context\";\n\nconst inputSchema = {\n shelf_id: z.string().min(1),\n};\n\nconst outputSchema = {\n shelf_id: z.string(),\n name: z.string(),\n file_count: z.number(),\n files: z.record(z.string()),\n};\n\nexport function registerGetShelfTreeTool(\n server: McpServer,\n context: ToolContext,\n): void {\n server.registerTool(\n \"get_shelf_tree\",\n {\n title: \"Get Shelf Tree\",\n description: \"Get the full file tree and file contents for a shelf\",\n inputSchema,\n outputSchema,\n annotations: { readOnlyHint: true },\n },\n async (input, extra) => {\n try {\n const apiKey = context.getApiKey(extra);\n const client = context.createShelvClient(apiKey);\n const tree = await client.getTree(input.shelf_id);\n\n return successResult(\n `Loaded ${tree.fileCount} files for shelf ${tree.shelfPublicId}`,\n {\n shelf_id: tree.shelfPublicId,\n name: tree.name,\n file_count: tree.fileCount,\n files: tree.files,\n },\n );\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { resolveShelfSource } from \"@shelv/adapters\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { McpToolError } from \"../errors\";\nimport { ensureRelativePath, errorResult, safeJoin, successResult } from \"./common\";\nimport type { ToolContext } from \"./context\";\n\nconst inputSchema = {\n shelf_id: z.string().min(1),\n target_dir: z.string().min(1),\n overwrite: z.boolean().optional(),\n};\n\nconst outputSchema = {\n shelf_id: z.string(),\n source_kind: z.enum([\"archive\", \"tree\"]),\n target_dir: z.string(),\n files_written: z.number(),\n bytes_written: z.number(),\n archive_version: z.string().nullable(),\n};\n\nexport function registerHydrateShelfTool(\n server: McpServer,\n context: ToolContext,\n): void {\n server.registerTool(\n \"hydrate_shelf\",\n {\n title: \"Hydrate Shelf\",\n description: \"Download and write shelf files into a local directory\",\n inputSchema,\n outputSchema,\n annotations: { readOnlyHint: false },\n },\n async (input, extra) => {\n try {\n const apiKey = context.getApiKey(extra);\n const source = await resolveShelfSource({\n client: context.createShelvClient(apiKey),\n shelfPublicId: input.shelf_id,\n mode: \"archive-first\",\n });\n\n const overwrite = input.overwrite ?? false;\n const targetDir = path.resolve(input.target_dir);\n\n await fs.mkdir(targetDir, { recursive: true });\n\n let filesWritten = 0;\n let bytesWritten = 0;\n\n for (const [relativePath, content] of Object.entries(source.files)) {\n const normalized = ensureRelativePath(relativePath);\n const fullPath = safeJoin(targetDir, normalized);\n\n if (!overwrite) {\n const exists = await fs\n .access(fullPath)\n .then(() => true)\n .catch(() => false);\n\n if (exists) {\n throw new McpToolError({\n code: \"LOCAL_IO_ERROR\",\n message: `Refusing to overwrite existing file: ${normalized}`,\n retryable: false,\n });\n }\n }\n\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, content, \"utf8\");\n\n filesWritten += 1;\n bytesWritten += Buffer.byteLength(content, \"utf8\");\n }\n\n return successResult(\n `Hydrated ${filesWritten} files to ${targetDir}`,\n {\n shelf_id: input.shelf_id,\n source_kind: source.kind,\n target_dir: targetDir,\n files_written: filesWritten,\n bytes_written: bytesWritten,\n archive_version: source.kind === \"archive\" ? source.archiveVersion : null,\n },\n );\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { errorResult, successResult } from \"./common\";\nimport type { ToolContext } from \"./context\";\n\nconst inputSchema = {\n page: z.number().int().min(1).optional(),\n limit: z.number().int().min(1).max(100).optional(),\n};\n\nconst outputSchema = {\n shelves: z.array(\n z.object({\n publicId: z.string(),\n name: z.string(),\n status: z.string(),\n template: z.string().nullable(),\n pageCount: z.number().nullable(),\n reviewMode: z.boolean(),\n createdAt: z.string(),\n updatedAt: z.string(),\n }),\n ),\n pagination: z.object({\n page: z.number(),\n limit: z.number(),\n total: z.number(),\n totalPages: z.number(),\n }),\n};\n\nexport function registerListShelvesTool(\n server: McpServer,\n context: ToolContext,\n): void {\n server.registerTool(\n \"list_shelves\",\n {\n title: \"List Shelves\",\n description: \"List shelves available to the authenticated user\",\n inputSchema,\n outputSchema,\n annotations: { readOnlyHint: true },\n },\n async (input, extra) => {\n try {\n const apiKey = context.getApiKey(extra);\n const client = context.createHttpClient(apiKey);\n const result = await client.listShelves({\n page: input.page,\n limit: input.limit,\n });\n\n return successResult(\n `Loaded ${result.data.length} shelves (page ${result.pagination.page}/${result.pagination.totalPages})`,\n {\n shelves: result.data,\n pagination: result.pagination,\n },\n );\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { ensureRelativePath, errorResult, inferContentType, successResult, truncateUtf8 } from \"./common\";\nimport type { ToolContext } from \"./context\";\n\nconst inputSchema = {\n shelf_id: z.string().min(1),\n path: z.string().min(1),\n};\n\nconst outputSchema = {\n shelf_id: z.string(),\n path: z.string(),\n content_type: z.string(),\n content: z.string(),\n bytes: z.number(),\n truncated: z.boolean(),\n};\n\nexport function registerReadShelfFileTool(\n server: McpServer,\n context: ToolContext,\n): void {\n server.registerTool(\n \"read_shelf_file\",\n {\n title: \"Read Shelf File\",\n description: \"Read a single file from a shelf\",\n inputSchema,\n outputSchema,\n annotations: { readOnlyHint: true },\n },\n async (input, extra) => {\n try {\n const normalizedPath = ensureRelativePath(input.path);\n const apiKey = context.getApiKey(extra);\n const client = context.createShelvClient(apiKey);\n const raw = await client.getFile(input.shelf_id, normalizedPath);\n\n const truncated = truncateUtf8(raw, context.config.readMaxBytes);\n\n return successResult(\n truncated.truncated\n ? `Read ${normalizedPath} (truncated to ${truncated.bytes} bytes)`\n : `Read ${normalizedPath}`,\n {\n shelf_id: input.shelf_id,\n path: normalizedPath,\n content_type: inferContentType(normalizedPath),\n content: truncated.value,\n bytes: truncated.bytes,\n truncated: truncated.truncated,\n },\n );\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n","import { resolveShelfSource } from \"@shelv/adapters\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { McpToolError } from \"../errors\";\nimport { errorResult, successResult } from \"./common\";\nimport type { ToolContext } from \"./context\";\n\nconst inputSchema = {\n shelf_id: z.string().min(1),\n query: z.string().min(1),\n mode: z.enum([\"substring\", \"regex\"]).optional(),\n case_sensitive: z.boolean().optional(),\n max_matches: z.number().int().min(1).optional(),\n};\n\nconst outputSchema = {\n shelf_id: z.string(),\n query: z.string(),\n mode: z.enum([\"substring\", \"regex\"]),\n case_sensitive: z.boolean(),\n matches: z.array(\n z.object({\n path: z.string(),\n line: z.string(),\n line_number: z.number(),\n snippet: z.string(),\n }),\n ),\n scanned_files: z.number(),\n scanned_bytes: z.number(),\n truncated: z.boolean(),\n};\n\nfunction buildMatcher(\n query: string,\n mode: \"substring\" | \"regex\",\n caseSensitive: boolean,\n): (line: string) => boolean {\n if (mode === \"regex\") {\n let regex: RegExp;\n try {\n regex = new RegExp(query, caseSensitive ? \"\" : \"i\");\n } catch {\n throw new McpToolError({\n code: \"INPUT_ERROR\",\n message: \"Invalid regular expression\",\n status: 400,\n retryable: false,\n });\n }\n\n return (line: string) => regex.test(line);\n }\n\n const needle = caseSensitive ? query : query.toLowerCase();\n return (line: string) => {\n const haystack = caseSensitive ? line : line.toLowerCase();\n return haystack.includes(needle);\n };\n}\n\nexport function registerSearchShelfTool(\n server: McpServer,\n context: ToolContext,\n): void {\n server.registerTool(\n \"search_shelf\",\n {\n title: \"Search Shelf\",\n description: \"Search for text across files in a shelf\",\n inputSchema,\n outputSchema,\n annotations: { readOnlyHint: true },\n },\n async (input, extra) => {\n try {\n const mode = input.mode ?? \"substring\";\n const caseSensitive = input.case_sensitive ?? false;\n\n const apiKey = context.getApiKey(extra);\n const source = await resolveShelfSource({\n client: context.createShelvClient(apiKey),\n shelfPublicId: input.shelf_id,\n mode: \"archive-first\",\n });\n\n const matcher = buildMatcher(input.query, mode, caseSensitive);\n const maxMatches = Math.min(\n input.max_matches ?? context.config.searchMaxMatches,\n context.config.searchMaxMatches,\n );\n\n const matches: Array<{\n path: string;\n line: string;\n line_number: number;\n snippet: string;\n }> = [];\n\n let scannedFiles = 0;\n let scannedBytes = 0;\n let truncated = false;\n\n for (const [filePath, content] of Object.entries(source.files)) {\n if (scannedFiles >= context.config.searchMaxFiles) {\n truncated = true;\n break;\n }\n\n const bytes = Buffer.byteLength(content, \"utf8\");\n if (scannedBytes + bytes > context.config.searchMaxBytes) {\n truncated = true;\n break;\n }\n\n scannedFiles += 1;\n scannedBytes += bytes;\n\n const lines = content.split(/\\r?\\n/);\n for (let index = 0; index < lines.length; index += 1) {\n const line = lines[index] || \"\";\n if (!matcher(line)) continue;\n\n matches.push({\n path: filePath,\n line,\n line_number: index + 1,\n snippet: line.slice(0, 300),\n });\n\n if (matches.length >= maxMatches) {\n truncated = true;\n break;\n }\n }\n\n if (truncated) break;\n }\n\n return successResult(\n `Found ${matches.length} matches across ${scannedFiles} files`,\n {\n shelf_id: input.shelf_id,\n query: input.query,\n mode,\n case_sensitive: caseSensitive,\n matches,\n scanned_files: scannedFiles,\n scanned_bytes: scannedBytes,\n truncated,\n },\n );\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ToolContext } from \"./context\";\nimport { registerCreateShelfTool } from \"./create-shelf\";\nimport { registerGetShelfTreeTool } from \"./get-shelf-tree\";\nimport { registerHydrateShelfTool } from \"./hydrate-shelf\";\nimport { registerListShelvesTool } from \"./list-shelves\";\nimport { registerReadShelfFileTool } from \"./read-shelf-file\";\nimport { registerSearchShelfTool } from \"./search-shelf\";\n\nexport function registerShelvTools(server: McpServer, context: ToolContext): void {\n registerListShelvesTool(server, context);\n registerGetShelfTreeTool(server, context);\n registerReadShelfFileTool(server, context);\n registerSearchShelfTool(server, context);\n\n if (context.config.enableWriteTools) {\n registerCreateShelfTool(server, context);\n registerHydrateShelfTool(server, context);\n }\n}\n","import { createServer, type IncomingMessage, type Server as HttpServer, type ServerResponse } from \"node:http\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport type { McpConfig } from \"../config\";\n\nconst MCP_PATH = \"/mcp\";\ntype IncomingAuthenticatedRequest = IncomingMessage & { auth?: AuthInfo };\n\nfunction stripPort(value: string): string {\n const trimmed = value.trim();\n if (trimmed.startsWith(\"[\")) {\n const end = trimmed.indexOf(\"]\");\n if (end >= 0) return trimmed.slice(1, end).toLowerCase();\n }\n\n const [host] = trimmed.split(\":\");\n return (host || \"\").toLowerCase();\n}\n\nfunction getAllowedHosts(config: McpConfig): Set<string> {\n const configuredHost = stripPort(config.httpHost);\n const hosts = new Set([\"localhost\", \"127.0.0.1\", \"::1\", configuredHost]);\n return hosts;\n}\n\nfunction readJsonBody(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n\n req.on(\"data\", (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n req.on(\"error\", reject);\n\n req.on(\"end\", () => {\n if (chunks.length === 0) {\n resolve(undefined);\n return;\n }\n\n const raw = Buffer.concat(chunks).toString(\"utf8\");\n try {\n resolve(JSON.parse(raw));\n } catch {\n reject(new Error(\"Invalid JSON request body\"));\n }\n });\n });\n}\n\nfunction respondJson(\n res: ServerResponse,\n status: number,\n payload: Record<string, unknown>,\n): void {\n if (res.writableEnded) return;\n\n const body = JSON.stringify(payload);\n res.statusCode = status;\n res.setHeader(\"content-type\", \"application/json\");\n res.end(body);\n}\n\nfunction validateHostAndOrigin(\n req: IncomingMessage,\n config: McpConfig,\n): { ok: true } | { ok: false; reason: string } {\n const allowedHosts = getAllowedHosts(config);\n\n const hostHeader = req.headers.host;\n if (hostHeader) {\n const host = stripPort(hostHeader);\n if (!allowedHosts.has(host)) {\n return { ok: false, reason: \"Host header is not allowed\" };\n }\n }\n\n const origin = req.headers.origin;\n if (origin) {\n try {\n const originHost = stripPort(new URL(origin).host);\n if (!allowedHosts.has(originHost)) {\n return { ok: false, reason: \"Origin is not allowed\" };\n }\n } catch {\n return { ok: false, reason: \"Invalid Origin header\" };\n }\n }\n\n return { ok: true };\n}\n\nfunction parseAuth(\n req: IncomingMessage,\n config: McpConfig,\n): { ok: true; auth?: AuthInfo } | { ok: false; reason: string } {\n const header = req.headers.authorization;\n if (header === undefined || header.trim() === \"\") {\n if (config.apiKey) {\n return {\n ok: true,\n auth: {\n token: config.apiKey,\n clientId: \"env-fallback\",\n scopes: [],\n expiresAt: undefined,\n },\n };\n }\n\n return {\n ok: false,\n reason: \"Missing Authorization header\",\n };\n }\n\n if (!header.startsWith(\"Bearer \")) {\n return {\n ok: false,\n reason: \"Authorization must use Bearer token\",\n };\n }\n\n const token = header.slice(\"Bearer \".length).trim();\n if (!token.startsWith(\"sk_\")) {\n return {\n ok: false,\n reason: \"Shelv API key must use sk_ prefix\",\n };\n }\n\n return {\n ok: true,\n auth: {\n token,\n clientId: \"request-bearer\",\n scopes: [],\n expiresAt: undefined,\n },\n };\n}\n\nexport interface HttpTransportHandle {\n server: HttpServer;\n url: string;\n close(): Promise<void>;\n}\n\nexport async function runHttpTransport(\n server: McpServer,\n config: McpConfig,\n): Promise<HttpTransportHandle> {\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n });\n\n await server.connect(transport);\n\n const httpServer = createServer(async (req, res) => {\n try {\n const requestPath = req.url ? new URL(req.url, \"http://localhost\").pathname : \"/\";\n if (requestPath !== MCP_PATH) {\n respondJson(res, 404, { error: \"Not found\" });\n return;\n }\n\n const method = req.method || \"GET\";\n if (![\"GET\", \"POST\", \"DELETE\"].includes(method)) {\n respondJson(res, 405, { error: \"Method not allowed\" });\n return;\n }\n\n const security = validateHostAndOrigin(req, config);\n if (!security.ok) {\n respondJson(res, 403, { error: security.reason });\n return;\n }\n\n const auth = parseAuth(req, config);\n if (!auth.ok) {\n respondJson(res, 401, { error: auth.reason });\n return;\n }\n\n const authenticatedRequest = req as IncomingAuthenticatedRequest;\n authenticatedRequest.auth = auth.auth;\n\n const body = method === \"POST\" ? await readJsonBody(req) : undefined;\n await transport.handleRequest(authenticatedRequest, res, body);\n } catch (error) {\n respondJson(res, 500, {\n error: error instanceof Error ? error.message : \"Internal server error\",\n });\n }\n });\n\n await new Promise<void>((resolve, reject) => {\n httpServer.once(\"error\", reject);\n httpServer.listen(config.httpPort, config.httpHost, () => {\n httpServer.off(\"error\", reject);\n resolve();\n });\n });\n\n const host = config.httpHost.includes(\":\") ? `[${config.httpHost}]` : config.httpHost;\n const url = `http://${host}:${config.httpPort}${MCP_PATH}`;\n\n return {\n server: httpServer,\n url,\n close() {\n return new Promise((resolve, reject) => {\n httpServer.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n },\n };\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n\nexport async function runStdioTransport(server: McpServer): Promise<void> {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","#!/usr/bin/env node\nimport { createShelvMcpRuntime } from \"../server\";\nimport { runHttpTransport } from \"../transports/http\";\nimport { runStdioTransport } from \"../transports/stdio\";\n\nasync function main(): Promise<void> {\n const runtime = createShelvMcpRuntime();\n\n if (runtime.config.transport === \"stdio\") {\n if (!runtime.config.apiKey) {\n throw new Error(\"SHELV_API_KEY is required in stdio mode\");\n }\n\n await runStdioTransport(runtime.server);\n return;\n }\n\n const http = await runHttpTransport(runtime.server, runtime.config);\n console.error(`shelv-mcp listening at ${http.url}`);\n console.error(\n runtime.config.enableWriteTools\n ? \"write tools enabled\"\n : \"write tools disabled (set SHELV_MCP_ENABLE_WRITE_TOOLS=true to enable)\",\n );\n}\n\nmain().catch((error) => {\n console.error(\n error instanceof Error ? error.message : \"Failed to start shelv-mcp\",\n );\n process.exit(1);\n});\n"],"mappings":"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","names":["path","path","path","path","z","inputSchema","z","outputSchema","fs","path","z","inputSchema","z","outputSchema","path","fs","z","inputSchema","z","outputSchema","z","inputSchema","z","outputSchema","resolveShelfSource","z","inputSchema","z","outputSchema","resolveShelfSource"]}
@@ -0,0 +1,24 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+
3
+ type TransportMode = "stdio" | "http";
4
+ interface McpConfig {
5
+ apiBaseUrl: string;
6
+ apiKey?: string;
7
+ transport: TransportMode;
8
+ httpHost: string;
9
+ httpPort: number;
10
+ enableWriteTools: boolean;
11
+ searchMaxFiles: number;
12
+ searchMaxBytes: number;
13
+ searchMaxMatches: number;
14
+ readMaxBytes: number;
15
+ }
16
+ declare function loadConfig(env?: NodeJS.ProcessEnv): McpConfig;
17
+
18
+ interface ShelvMcpRuntime {
19
+ server: McpServer;
20
+ config: McpConfig;
21
+ }
22
+ declare function createShelvMcpRuntime(env?: NodeJS.ProcessEnv): ShelvMcpRuntime;
23
+
24
+ export { type McpConfig, type TransportMode, createShelvMcpRuntime, loadConfig };