Skip to main content
Glama
contents-feature-complete.md15.4 kB
# Contents 文件操作功能实现报告 ## 概述 **功能模块**: Contents (文件操作) **实现日期**: 2025-11-23 **工具数量**: 6 个 **API 版本**: Gitea v1.25+ **代码行数**: 409 行(实现 238 行 + 注册 171 行) --- ## 实现背景 ### 战略价值 Contents 模块是 Git 仓库操作的核心功能之一,与 Branch 模块配合,形成完整的文件版本控制能力。在 API 覆盖度分析中,Contents 被标记为 **🔴 Very High 优先级**。 ### 需求来源 1. **API 覆盖度提升**: 从 65% 提升到 70% 2. **完整 Git 工作流**: 补充 Branch + Contents 核心操作 3. **自动化需求**: 配置文件管理、文档生成、代码迁移 4. **用户反馈**: 需要完整的文件 CRUD 能力 --- ## API 研究 ### Gitea v1.25+ API 端点 使用 Gitea swagger.json 研究了 Contents 相关的 API 端点: ```bash curl -s https://demo.gitea.com/api/swagger | jq '.paths | to_entries | map(select(.key | contains("/contents") or contains("/raw") or contains("/archive"))) | .[].key' ``` #### 发现的端点 | 端点 | 方法 | 说明 | 实现状态 | |------|------|------|----------| | `/repos/{owner}/{repo}/contents/{filepath}` | GET | 获取文件/目录内容 | ✅ | | `/repos/{owner}/{repo}/contents/{filepath}` | POST | 创建文件 | ✅ | | `/repos/{owner}/{repo}/contents/{filepath}` | PUT | 更新文件 | ✅ | | `/repos/{owner}/{repo}/contents/{filepath}` | DELETE | 删除文件 | ✅ | | `/repos/{owner}/{repo}/raw/{filepath}` | GET | 获取原始文件内容 | ✅ | | `/repos/{owner}/{repo}/archive/{archive}` | GET | 下载仓库归档 | ✅ | **API 覆盖度**: 6/6 (100%) --- ## 实现详情 ### 1. 核心实现文件 #### src/tools/contents.ts (238 行) **关键接口定义**: ```typescript export interface ContentsToolsContext { client: GiteaClient; contextManager: ContextManager; } export interface Identity { name?: string; email?: string; } export interface ContentsParams { owner?: string; repo?: string; } ``` **6 个核心函数**: 1. **getContents** (24 行) - 获取文件或目录的元数据和内容 - 支持指定 ref(分支/标签/提交) - 返回 base64 编码的文件内容 2. **createFile** (28 行) - 创建新文件 - 支持 base64 编码的内容 - 支持自定义提交信息、作者、分支 3. **updateFile** (29 行) - 更新现有文件 - 支持 SHA 验证(乐观锁) - 支持文件重命名/移动(from_path) 4. **deleteFile** (26 行) - 删除文件 - 必需 SHA 验证 - 支持在新分支上删除 5. **getRawFile** (21 行) - 获取原始文件内容(非 base64) - 适用于快速读取文本文件 - 支持指定 ref 6. **downloadArchive** (15 行) - 下载仓库归档 - 支持多种格式(zip, tar.gz, tar) - 支持任意 ref ### 2. 工具注册文件 #### src/tools-registry/contents-registry.ts (171 行) **Identity Schema 定义**: ```typescript const identitySchema = z.object({ name: z.string().optional().describe('Name of the person'), email: z.string().email().optional().describe('Email of the person'), }); ``` **注册函数示例**: ```typescript export function registerContentsTools(mcpServer: McpServer, ctx: ToolContext) { const toolsContext = { client: ctx.client, contextManager: ctx.contextManager }; // 1. Get contents mcpServer.registerTool( 'gitea_contents_get', { title: '获取文件或目录内容', description: 'Get the metadata and contents (if a file) of an entry in a repository, or a list of entries if a directory', inputSchema: z.object({ owner: z.string().optional().describe('Repository owner. Uses context if not provided'), repo: z.string().optional().describe('Repository name. Uses context if not provided'), filepath: z.string().min(1).describe('Path of the file or directory'), ref: z.string().optional().describe('The name of the commit/branch/tag. Defaults to the default branch'), }), }, async (args) => { try { const result = await ContentsTools.getContents(toolsContext, args as any); return { content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }] }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [{ type: 'text' as const, text: `Error: ${errorMessage}` }], isError: true }; } } ); // ... 其他 5 个工具注册 } ``` --- ## 技术亮点 ### 1. Base64 编码处理 **问题**: Gitea API 要求文件内容使用 base64 编码 **解决方案**: - 在工具描述中明确说明编码要求 - 在文档中提供编码/解码示例 - 支持原始文件 API 作为替代方案 ```typescript // 创建文件时要求 base64 编码 export interface CreateFileParams extends ContentsParams { filepath: string; content: string; // base64 encoded content // ... } // 原始文件 API 返回未编码内容 export async function getRawFile( ctx: ContentsToolsContext, params: GetRawFileParams ): Promise<unknown> { // 返回原始二进制数据 return response.data; } ``` ### 2. Identity Schema 设计 **问题**: Git 提交需要作者和提交者信息 **解决方案**: - 定义可复用的 Identity schema - 支持可选的 name 和 email - Email 使用 Zod 验证格式 ```typescript const identitySchema = z.object({ name: z.string().optional().describe('Name of the person'), email: z.string().email().optional().describe('Email of the person'), }); // 在多个工具中复用 inputSchema: z.object({ // ... author: identitySchema.optional().describe('Author identity'), committer: identitySchema.optional().describe('Committer identity'), }) ``` ### 3. URL 编码处理 **问题**: 文件路径可能包含特殊字符(空格、中文、符号) **解决方案**: - 使用 `encodeURIComponent()` 编码文件路径 - 在所有路径参数上应用 ```typescript const response = await ctx.client.request({ method: 'GET', path: `/repos/${owner}/${repo}/contents/${encodeURIComponent(params.filepath)}`, params: queryParams, }); ``` ### 4. 动态字段构建 **问题**: 大量可选参数,只应发送提供的字段 **解决方案**: - 使用条件语句动态构建请求体 - 避免发送 undefined 值 ```typescript const body: any = { content: params.content, }; if (params.message) body.message = params.message; if (params.branch) body.branch = params.branch; if (params.new_branch) body.new_branch = params.new_branch; if (params.author) body.author = params.author; if (params.committer) body.committer = params.committer; if (params.signoff !== undefined) body.signoff = params.signoff; if (params.force_push !== undefined) body.force_push = params.force_push; ``` ### 5. 文件移动/重命名支持 **问题**: Git 中的文件重命名实际是删除旧文件 + 创建新文件 **解决方案**: - 在 `updateFile` 中支持 `from_path` 参数 - Gitea API 自动处理为 Git 重命名操作 ```typescript export interface UpdateFileParams extends ContentsParams { filepath: string; content: string; sha?: string; from_path?: string; // For rename/move operations // ... } ``` --- ## 构建和测试 ### 编译结果 ```bash $ npm run build ✅ ESM dist/index.js 234.59 KB (+12.60 KB) ✅ ESM dist/index.js.map 520.77 KB (+17.68 KB) ✅ DTS dist/index.d.ts 4.30 KB ⚡️ Build success in 157ms ``` **代码增量**: - +12.60 KB (从 221.99 KB 增加到 234.59 KB) - +5.68% 相对增长 ### 质量保证 - ✅ **TypeScript 编译**: 0 错误,0 警告 - ✅ **类型安全**: 所有函数都有完整的类型定义 - ✅ **Schema 验证**: 使用 Zod 进行运行时验证 - ✅ **错误处理**: 统一的 try-catch 模式 --- ## 功能对比 ### 与 GitHub CLI 对比 | 功能 | GitHub CLI | Gitea MCP (当前) | 说明 | |------|-----------|-----------------|------| | 获取文件内容 | `gh api repos/{owner}/{repo}/contents/{path}` | ✅ `gitea_contents_get` | 完全一致 | | 创建文件 | API only | ✅ `gitea_contents_create` | Gitea 提供更友好 | | 更新文件 | API only | ✅ `gitea_contents_update` | 支持 SHA 验证 | | 删除文件 | API only | ✅ `gitea_contents_delete` | 必需 SHA | | 原始内容 | `gh api repos/{owner}/{repo}/contents/{path} --jq '.content' \| base64 -d` | ✅ `gitea_contents_raw` | 更简洁 | | 下载归档 | `gh api repos/{owner}/{repo}/tarball/{ref}` | ✅ `gitea_repo_archive` | 支持多格式 | ### 与 GitLab CLI 对比 | 功能 | GitLab CLI | Gitea MCP (当前) | 说明 | |------|-----------|-----------------|------| | 获取文件 | `glab api projects/{id}/repository/files/{path}` | ✅ `gitea_contents_get` | 类似 | | 创建文件 | `glab api projects/{id}/repository/files/{path}` | ✅ `gitea_contents_create` | 完全对等 | | 更新文件 | `glab api projects/{id}/repository/files/{path}` | ✅ `gitea_contents_update` | 完全对等 | | 删除文件 | `glab api projects/{id}/repository/files/{path}` | ✅ `gitea_contents_delete` | 完全对等 | | 原始内容 | `glab api projects/{id}/repository/files/{path}/raw` | ✅ `gitea_contents_raw` | 完全对等 | | 归档下载 | `glab api projects/{id}/repository/archive` | ✅ `gitea_repo_archive` | 完全对等 | **结论**: Gitea MCP 在 Contents 模块达到与 GitHub/GitLab CLI 相同的功能水平。 --- ## 实际应用场景 ### 1. CI/CD 自动化 ```typescript // 在 CI 流程中自动更新版本号 const packageJson = await gitea_contents_get({ filepath: "package.json" }); const pkg = JSON.parse(atob(packageJson.content)); pkg.version = process.env.NEW_VERSION; await gitea_contents_update({ filepath: "package.json", content: btoa(JSON.stringify(pkg, null, 2)), sha: packageJson.sha, message: `ci: Bump version to ${process.env.NEW_VERSION}`, author: { name: "CI Bot", email: "ci@example.com" } }); ``` ### 2. 文档自动生成 ```typescript // 从代码注释生成 API 文档 const apiDocs = await generateAPIDocumentation(); await gitea_contents_create({ filepath: "docs/api.md", content: btoa(apiDocs), message: "docs: Auto-generate API documentation", branch: "main", new_branch: "docs/auto-update" }); ``` ### 3. 配置管理 ```typescript // 批量部署配置文件到多个环境 const environments = ["dev", "staging", "production"]; for (const env of environments) { const config = generateConfig(env); await gitea_contents_create({ filepath: `config/${env}.yaml`, content: btoa(config), message: `config: Add ${env} configuration` }); } ``` ### 4. 代码迁移 ```typescript // 从旧仓库迁移文件到新仓库 const sourceFiles = await gitea_contents_get({ owner: "old-org", repo: "old-repo", filepath: "src" }); for (const file of sourceFiles) { if (file.type === 'file') { const content = await gitea_contents_get({ owner: "old-org", repo: "old-repo", filepath: file.path }); await gitea_contents_create({ owner: "new-org", repo: "new-repo", filepath: file.path, content: content.content, message: `Migrate ${file.path}` }); } } ``` --- ## 文档输出 ### 1. 用户指南 **文件**: `docs/contents-tools.md` (580+ 行) **章节**: - 工具列表:6 个工具的详细说明 - 实际使用场景:5 个完整示例 - 高级用法:base64 编码、文件移动、分支策略、身份配置 - 最佳实践:检查、SHA 验证、批量操作、错误处理 - 工具集成:与 Branch、PR、Release 工具配合 - 常见问题:5 个 Q&A - 性能优化:3 条建议 ### 2. API 覆盖度更新 **文件**: `docs/api-coverage-summary.md` **更新内容**: - 总工具数:105 → 111 (+6) - API 覆盖度:65% → 70% (+5%) - 完全覆盖模块:11 → 12 个 - Repository 模块覆盖度:70% → 80% - 从"未覆盖"移除 Contents ### 3. 迁移报告更新 **文件**: `docs/migration-complete.md` **更新内容**: - Contents (文件操作) | 6 | ✅ 新增 (2025-11-23) - 总计:105 → 111 工具 --- ## 项目影响 ### 统计数据 | 指标 | 实施前 | 实施后 | 变化 | |------|--------|--------|------| | 工具总数 | 105 | 111 | +6 (+5.7%) | | API 覆盖度 | 65% | 70% | +5% | | 完全覆盖模块 | 11 | 12 | +1 | | 代码库大小 | 221.99 KB | 234.59 KB | +12.60 KB | | Registry 模块 | 14 | 15 | +1 | ### 战略意义 1. **核心功能完整性**: Branch + Contents = 完整 Git 文件版本控制 2. **Repository 模块提升**: 从 70% 提升到 80% 覆盖度 3. **API 覆盖里程碑**: 达到 70%,距离 85% 目标更近 4. **用户体验改善**: 支持完整的文件 CRUD 操作 --- ## 经验总结 ### 成功因素 1. **API 研究充分**: 通过 swagger.json 全面了解 API 能力 2. **架构一致性**: 遵循现有的 tools + registry 模式 3. **类型安全**: TypeScript + Zod 双重保障 4. **文档完整**: 提供详细的用户指南和示例 ### 技术挑战 1. **Base64 编码**: 需要在文档中明确说明编码要求 2. **URL 编码**: 处理特殊字符的文件路径 3. **Identity Schema**: 设计可复用的 Git 身份验证结构 4. **文件移动**: 理解 Git 重命名的底层机制 ### 改进建议 1. **批量操作**: 考虑添加批量文件操作工具 2. **文件大小限制**: 文档中说明 API 限制 3. **二进制文件**: 提供二进制文件处理示例 4. **冲突处理**: 添加更多冲突解决策略 --- ## 后续计划 ### 立即行动 根据 API 覆盖度分析,下一步优先级: 1. **Commit 管理** (5 工具) - 🟠 High Priority - List commits, get commit, compare commits - 与 Contents 配合,形成完整提交历史 2. **Tag 管理** (4 工具) - 🟠 High Priority - Create, list, get, delete tags - 与 Release 配合,完善版本管理 ### 中期目标 3. **Notification** (5 工具) 4. **Collaborator** (4 工具) **目标**: 在 2 周内达到 83% API 覆盖度(129 工具) --- ## 总结 Contents 模块的实现: - ✅ **6 个工具**,100% API 覆盖 - ✅ **409 行代码**,模块化架构 - ✅ **0 错误**,编译通过 - ✅ **完整文档**,包含示例和最佳实践 - ✅ **实际应用场景**,覆盖 CI/CD、文档生成、配置管理、代码迁移 Contents 与 Branch 模块配合,形成了 Gitea MCP 的 **Git 核心操作能力**,为项目的 70% API 覆盖度做出了重要贡献。 --- ## 附录 ### 工具清单 1. `gitea_contents_get` - 获取文件或目录内容 2. `gitea_contents_create` - 创建文件 3. `gitea_contents_update` - 更新文件 4. `gitea_contents_delete` - 删除文件 5. `gitea_contents_raw` - 获取原始文件内容 6. `gitea_repo_archive` - 下载仓库归档 ### 相关文件 - `src/tools/contents.ts` (238 行) - `src/tools-registry/contents-registry.ts` (171 行) - `docs/contents-tools.md` (用户指南) - `docs/contents-feature-complete.md` (本文档) - `docs/api-coverage-summary.md` (已更新) - `docs/migration-complete.md` (已更新) ### 参考资料 - [Gitea API Documentation - Repository Contents](https://docs.gitea.com/api/1.25/#tag/repository) - [GitHub REST API - Repository Contents](https://docs.github.com/en/rest/repos/contents) - [GitLab API - Repository Files](https://docs.gitlab.com/ee/api/repository_files.html)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SupenBysz/gitea-mcp-tool'

If you have feedback or need assistance with the MCP directory API, please join our Discord server