Skip to main content
Glama

export_draft

Export video drafts as editable JianYing (CapCut) project files to local directories for further editing and production.

Instructions

导出草稿为剪映项目,导出到本地剪映的草稿路径下

Args: draft_id: 草稿ID,必须是已存在的草稿 jianying_draft_path: 导出路径

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
draft_idYes
jianying_draft_pathNo/app/output

Implementation Reference

  • Primary MCP tool handler for 'export_draft'. Registered via @mcp.tool() decorator. Validates draft existence, instantiates ExportDraft, performs export, processes logs, and returns structured ToolResponse with success status and details.
    @mcp.tool()
    def export_draft(draft_id: str, jianying_draft_path: str = OUTPUT_PATH) -> ToolResponse:
        """
        导出草稿为剪映项目,导出到本地剪映的草稿路径下
    
        Args:
            draft_id: 草稿ID,必须是已存在的草稿
            jianying_draft_path: 导出路径
        """
        try:
            # 验证草稿是否存在
            draft_data_path = os.path.join(SAVE_PATH, draft_id)
            if not os.path.exists(draft_data_path):
                return ToolResponse(
                    success=False,
                    message=f"草稿不存在: {draft_id}"
                )
    
            # 验证草稿数据文件是否存在
            draft_json_path = os.path.join(draft_data_path, "draft.json")
            if not os.path.exists(draft_json_path):
                return ToolResponse(
                    success=False,
                    message=f"草稿数据文件不存在: {draft_id}/draft.json"
                )
    
            # 创建导出器
            exporter = ExportDraft(jianying_draft_path)
    
            # 执行导出
            export_result = exporter.export(draft_id)
    
            if export_result and isinstance(export_result, dict):
                return ToolResponse(
                    success=True,
                    message="草稿导出成功",
                    data={
                        "draft_id": draft_id,
                        "output_path": export_result.get("output") + f"/{export_result.get("draft_name")}",
                        "draft_name": export_result.get("draft_name"),
                        "export_logs": export_result.get("export_logs", []),
                        "summary": export_result.get("summary", {}),
                        "processing_details": {
                            "total_operations": len(export_result.get("export_logs", [])),
                            "successful_operations": len(
                                [log for log in export_result.get("export_logs", []) if log.get("level") == "info"]),
                            "warnings": len(
                                [log for log in export_result.get("export_logs", []) if log.get("level") == "warning"]),
                            "errors": len(
                                [log for log in export_result.get("export_logs", []) if log.get("level") == "error"])
                        }
                    }
                )
            else:
                return ToolResponse(
                    success=False,
                    message="草稿导出失败,请检查草稿数据完整性"
                )
    
        except FileNotFoundError as e:
            return ToolResponse(
                success=False,
                message=f"文件不存在: {str(e)}"
            )
        except Exception as e:
            return ToolResponse(
                success=False,
                message=f"导出失败: {str(e)}"
            )
  • Core helper method ExportDraft.export() that implements the draft export logic: reads JSON data (draft/track/video/text/audio), creates pyJianYingDraft script and segments, copies material files, adds tracks and segments, and saves the Jianying draft folder structure.
    def export(self, draft_id: str) -> dict:
        """
        导出草稿
        
        Args:
            draft_id: 草稿ID
            
        Returns:
            bool: 导出是否成功
        """
        try:
            self._log(f"开始导出草稿: {draft_id}")
    
            # 验证草稿数据是否存在
            draft_data_path = f"{SAVE_PATH}/{draft_id}"
            if not os.path.exists(draft_data_path):
                raise FileNotFoundError(f"草稿数据不存在: {draft_data_path}")
    
            # 验证导出路径是否存在
            if not os.path.exists(self.output_path):
                raise FileNotFoundError(f"导出路径不存在: {self.output_path}")
    
            # 1. 读取所有数据
            draft_info = self._load_draft_data(draft_id)
            track_data = self._load_track_data(draft_id)
            video_data = self._load_video_data(draft_id)
            text_data = self._load_text_data(draft_id)
            audio_data = self._load_audio_data(draft_id)
    
            if not draft_info:
                raise FileNotFoundError(f"未找到草稿信息文件: {draft_id}/draft.json")
    
            # 2. 验证目标草稿是否已存在
            draft_name = draft_info.get("draft_name", f"Draft_{draft_id}")
            # 3. 创建草稿
            width = draft_info.get("width", 1920)
            height = draft_info.get("height", 1080)
            if os.path.exists(os.path.join(self.output_path, draft_name)):
                # 删除文件夹
                shutil.rmtree(os.path.join(self.output_path, draft_name))
            script = self.draft_folder.create_draft(draft_name, width, height)
    
            # 3. 复制素材文件
            self._copy_material_files(draft_id, draft_name)
    
            # 4. 添加轨道
            self._create_tracks(script, track_data)
    
            # 5. 处理视频片段
            video_segments = self._process_video_segments(video_data, draft_name)
    
            # 6. 处理文本片段
            text_segments = self._process_text_segments(text_data)
    
            # 7. 处理音频片段
            audio_segments = self._process_audio_segments(audio_data, draft_name)
    
            # 8. 添加视频片段到轨道
            self._add_video_segments_to_tracks(script, video_segments)
    
            # 为文本片段分配轨道
            self._add_text_segments_to_tracks(script, text_segments)
    
            # 为音频片段分配轨道
            self._add_audio_segments_to_tracks(script, audio_segments)
    
            # 9. 保存草稿
            script.save()
    
            data = {
                "output": self.output_path,
                "draft_name": draft_name,
                "export_logs": self.export_logs,
                "summary": {
                    "total_logs": len(self.export_logs),
                    "info_count": len([log for log in self.export_logs if log["level"] == "info"]),
                    "warning_count": len([log for log in self.export_logs if log["level"] == "warning"]),
                    "error_count": len([log for log in self.export_logs if log["level"] == "error"])
                }
            }
            return data
    
        except Exception as e:
            self._log(f"导出草稿失败: {e}", "error")
            import traceback
            traceback.print_exc()
            return {
                "output": self.output_path,
                "draft_name": draft_name,
                "export_logs": self.export_logs,
                "summary": {
                    "total_logs": len(self.export_logs),
                    "info_count": len([log for log in self.export_logs if log["level"] == "info"]),
                    "warning_count": len([log for log in self.export_logs if log["level"] == "warning"]),
                    "error_count": len([])
                }
            }
  • Wrapper method in Draft class for exporting draft, which delegates to ExportDraft.export().
    def export_draft(self, draft_id: str, output_path: str = ''):
        """
        导出草稿
    
        Args:
            draft_id: str, 草稿ID
            output_path: str, 导出路径,可选,默认"./output"
    
        Returns:
            str: 导出结果信息
        """
        export_manager = ExportDraft(output_path)
        return export_manager.export(draft_id)
  • The draft_tools function that sets up the MCP server and registers all draft-related tools including export_draft.
    def draft_tools(mcp: FastMCP):

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/hey-jian-wei/jianying-mcp'

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