This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
pnpm workspace monorepo,包含三个包:
packages/ui- React 前端应用packages/server- FastAPI 后端服务 (Python)packages/pdf-reader-mcp- MCP PDF 阅读器服务 (Python)
- claude-agent-sdk-python: 项目核心依赖(本地开发时需克隆到与本项目同级目录)
- 提供 Claude SDK 和 MCP 工具注册能力
- 需要时常参考源码以了解 API 使用方式和最新特性
- 关键模块:
@tool装饰器、create_sdk_mcp_server、Session 管理
# 同时启动 UI 和 Server
pnpm dev
# 单独启动 UI(端口 5173)
pnpm --filter @increa-reader/ui dev
# 单独启动 Server(端口 3000)
pnpm --filter @increa-reader/server dev
# 或者直接运行 Python 服务器
cd packages/server && python server.pypnpm build # 构建所有包
pnpm --filter @increa-reader/ui typecheck # UI 类型检查
pnpm --filter @increa-reader/ui lint # UI 代码检查
pnpm --filter @increa-reader/ui format # UI 代码格式化
# 安装 Python 依赖
cd packages/server && pip install -r requirements.txtpnpm test # 运行所有测试(目前尚未实现)
# MCP 包测试
pnpm --filter @increa/pdf-reader-mcp test # 运行测试
pnpm --filter @increa/pdf-reader-mcp test:cov # 运行测试(含覆盖率)- 技术栈: React 19, React Router, Vite (rolldown-vite), TypeScript
- 样式: Tailwind CSS v4 (使用 @tailwindcss/vite 插件), shadcn/ui (new-york 风格)
- 编译器: React Compiler (babel-plugin-react-compiler)
- 布局: 三栏可调整大小的面板布局(使用 react-resizable-panels)
- 左侧:文件树(LeftPanel → FileTree)
- 中间:主内容区(通过 React Router Outlet 渲染)
- 右侧:待实现功能区
- 路由:
/- 首页/views/:repoName/*- 文件查看器
- API 调用: 使用
/api前缀,Vite 代理到http://localhost:3000
- 技术栈: FastAPI, PyMuPDF, Claude SDK, MCP (Model Context Protocol)
- 核心功能:
- 递归构建文件树,支持排除模式(默认排除
node_modules/,.*) - 自动检测文本/二进制文件
- PDF 处理和搜索功能(通过 MCP 工具)
- AI 聊天功能(集成 Claude SDK)
- 流式响应支持
- 递归构建文件树,支持排除模式(默认排除
- API 路由:
/api/workspace/tree- 获取文件树/api/views/{repo}/{path}- 获取文件内容/api/preview- 获取文件预览/api/chat/query- AI 聊天接口(流式,SSE 格式)/api/pdf/page- 获取 PDF 页面 Markdown 内容/api/pdf/page-render- 渲染 PDF 页面为 SVG/api/temp-image/{filepath:path}- 提供临时图片访问(用于 PDF 提取的图片)
- MCP 工具:
open_pdf,page_count,extract_text,render_page_png,search_text,close_pdf- 所有工具通过
claude-agent-sdk注册,前缀为mcp__pdf-reader__ - MCP 服务独立包:
packages/pdf-reader-mcp(可单独部署到 Claude Desktop/Code)
- Server 启动时从
INCREA_REPO环境变量读取仓库路径(用:分隔多个路径) - UI 通过
/api/workspace/tree获取所有仓库的文件树 - 用户点击文件时,通过
/api/views/{repo}/{path}获取文件内容 - UI 根据文件类型(text/binary)决定如何显示
- 用户打开 PDF 文件,进入
/views/:repo/:path路由 - PDF Viewer 使用虚拟滚动加载可见页面
- 每页支持两种视图模式:
- SVG 模式:通过
/api/pdf/page-render获取矢量图 - Markdown 模式:通过
/api/pdf/page获取提取的文本/表格/图片(使用 pymupdf4llm)
- SVG 模式:通过
- 提取的图片保存到临时目录,通过
/api/temp-image/{filename}访问
- 用户在右侧面板输入问题,选择目标 repo 作为上下文
- 前端通过
/api/chat/query发送 POST 请求(SSE 流式响应) - Server 使用
claude-agent-sdk调用 Claude API,提供以下能力:- 文件读取(Read, Grep, Glob 工具)
- PDF 操作(MCP 工具:open_pdf, render_page_png 等)
- 代码分析和问答
- LLM 响应流式返回,前端实时渲染 Markdown 内容(含图片)
- Session 持久化到 localStorage,支持对话历史
- 添加组件:
npx shadcn@latest add <component-name> - 重要: shadcn 会在项目根目录创建
@/components/ui/,需手动移到packages/ui/src/components/ui/ - Path alias:
@/→packages/ui/src/(在 tsconfig.app.json 和 vite.config.ts 配置)
- 配置文件:
packages/ui/src/style.css,只需@import "tailwindcss"; - 不需要手动定义 CSS 变量
- 推荐使用虚拟环境:
python -m venv .venv && source .venv/bin/activate - Server 包依赖管理:
cd packages/server && pip install -r requirements.txt - MCP 包依赖管理:
cd packages/pdf-reader-mcp && pip install -e ".[dev]" - 服务器启动:
python server.py
- 格式化:使用 black(line-length: 88)和 isort(black profile)
- 文件长度:建议 <200 行,但优先考虑内聚性而非机械限制
- 内聚的类(如 PDFPageProcessor)可以更长
- 信息量过载的文件(多种不相关功能)应拆分
- 函数长度:建议 <40 行,复杂但单一职责的函数可适当放宽
- Shebang:只在入口脚本(server.py)使用,模块文件不使用
- 核心原则:模块规模的本质是信息量,而非行数
问题:LLM 通过 MCP 工具截图时,需要将本地文件路径转换为浏览器可访问的 HTTP URL
解决方案:
- 临时图片存储:所有 PDF 提取/截图的图片保存到
tempfile.gettempdir() - API 访问端点:
/api/temp-image/{filepath:path}提供临时图片访问(views.py:186)- 支持路径安全检查,防止目录遍历攻击
- 自动识别子目录(如
pymupdf4llm_images/xxx.png)
- MCP 工具返回格式:
render_page_png返回 Markdown 格式:- PDF 处理器(pymupdf4llm)提取的图片路径自动替换为 API URL
- 前端渲染:
- Message 组件使用
react-markdown渲染 Markdown(含图片) - 图片通过 HTTP 请求加载,浏览器可正常访问
- Message 组件使用
- 会话管理:使用
claude-agent-sdk的 session 机制,支持对话历史和上下文保持 - 流式响应:SSE (Server-Sent Events) 实时返回 LLM 输出
- 权限控制:
permissionMode: "bypassPermissions"允许工具自动执行 - 上下文切换:用户通过
/cd <repo>命令切换工作目录 - Frontend Tools:必须使用
@tool装饰器定义,与 PDF tools 保持一致- 函数签名统一为
async def func(args: dict[str, Any]) - 通过
create_sdk_mcp_server(tools=FRONTEND_TOOLS)注册
- 函数签名统一为
- 使用
useExternalLinksHook 统一处理外部链接(hooks/use-external-links.ts) - 通过事件冒泡拦截链接点击,外部链接自动在新窗口打开
- 已应用于:聊天消息(message.tsx)、文件查看器(file-viewer.tsx)
INCREA_REPO: 仓库路径,多个路径用:分隔(例如:/path/to/repo1:/path/to/repo2)PORT: Server 端口(默认 3000)ANTHROPIC_API_KEY: Claude API 密钥ANTHROPIC_BASE_URL: Claude API 基础URL(可选)CHAT_LOGS_DIR: 聊天记录保存目录(默认:chat-logs,支持~展开)