Skip to main content
Glama

createDocToPdfJob

Convert documents to PDF format for standardized sharing and archiving by submitting processing jobs to cloud storage.

Instructions

创建文档转 pdf 处理任务

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
objectKeyYes对象在存储桶里的路径

Implementation Reference

  • src/server.ts:532-550 (registration)
    Registers the 'createDocToPdfJob' tool in the MCP server, including input schema and a thin handler that delegates to CIDocService.createDocToPdfJobs.
    server.tool(
      'createDocToPdfJob',
      '创建文档转 pdf 处理任务',
      {
        objectKey: z.string().describe('对象在存储桶里的路径'),
      },
      async ({ objectKey }) => {
        const res = await CIDocInstance.createDocToPdfJobs(objectKey);
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(res.data, null, 2),
            },
          ],
          isError: !res.isSuccess,
        };
      },
    );
  • Input schema for the tool: requires 'objectKey' as string, describing the path of the object in the bucket.
      objectKey: z.string().describe('对象在存储桶里的路径'),
    },
  • Core handler implementing document to PDF conversion job creation using Tencent Cloud COS CI DocProcess API. Constructs XML request, submits job, and polls for completion using describeDocProcessJob.
    async createDocToPdfJobs(objectKey: string) {
      try {
        var host = this.bucket + '.ci.' + this.region + '.myqcloud.com/doc_jobs';
        var url = 'https://' + host;
        const lastDotIndex = objectKey.lastIndexOf('.');
        const base =
          lastDotIndex === -1 ? objectKey : objectKey.substring(0, lastDotIndex);
    
        const now = new Date();
        const formattedDate = [
          now.getFullYear(),
          String(now.getMonth() + 1).padStart(2, '0'), // 月份补零
          String(now.getDate()).padStart(2, '0'), // 日期补零
        ].join('');
    
        const outPutObject = `${formattedDate}_\${SheetID}/${base}_pdf_${generateCode(6)}.pdf`;
        var body = COS.util.json2xml({
          Request: {
            Tag: 'DocProcess',
            Input: {
              Object: objectKey, // 存在cos里的路径
            },
            Operation: {
              DocProcess: {
                TgtType: 'pdf',
              },
              Output: {
                Bucket: this.bucket,
                Region: this.region,
                Object: outPutObject, // 转码后存到cos的路径
              },
            },
          },
        });
    
        const createResult = await new Promise((resolve, reject) => {
          this.cos.request(
            {
              Key: 'doc_jobs',
              Method: 'POST', // 固定值
              Url: url,
              Body: body,
              ContentType: 'application/xml',
            },
            (error, data) => (error ? reject(error) : resolve(data)),
          );
        });
    
        try {
          const jobsDetail = (createResult as any).Response.JobsDetail;
          const initialCode = jobsDetail.Code;
          const initialState = jobsDetail.State;
    
          if (initialCode == 'Failed') {
            return {
              isSuccess: false,
              message: '文档转pdf失败',
              data: createResult,
            };
          }
          if (initialState == 'Success') {
            return {
              isSuccess: true,
              message: '文档转pdf成功',
              data: createResult,
            };
          } else {
            const jobId = jobsDetail.JobId;
    
            // 开始轮询
            let pollResult: any;
            const maxAttempts = 10;
            const interval = 2000;
            for (let attempt = 0; attempt < maxAttempts; attempt++) {
              // 首次立即执行,后续等待间隔
              if (attempt > 0) await new Promise((r) => setTimeout(r, interval));
              try {
                // 查询任务状态
                const { data: getResult } =
                  await this.describeDocProcessJob(jobId);
                const describeJobsDetail = (getResult as any).Response.JobsDetail;
                const describeJobCode = describeJobsDetail.Code;
                const describeJobState = describeJobsDetail.State;
                // 处理终态
                if (
                  describeJobCode === 'Success' &&
                  describeJobState == 'Success'
                ) {
                  pollResult = getResult;
                  break;
                } else if (describeJobCode === 'Failed') {
                  return {
                    isSuccess: false,
                    message: '文档转换失败',
                    data: getResult,
                  };
                }
              } catch (err) {
                // lastError = err as Error; // 记录错误继续重试
              }
            }
            if (!pollResult) {
              return {
                isSuccess: false,
                message: `轮询超时(${maxAttempts}次未完成)`,
                data: createResult,
              };
            }
            return {
              isSuccess: true,
              message: '文档转码成功',
              data: pollResult,
            };
          }
        } catch (error) {
          return {
            isSuccess: false,
            message: '文档转pdf失败',
            data: error,
          };
        }
      } catch (error) {
        return {
          isSuccess: false,
          message: '文档转pdf失败',
          data: error,
        };
      }
    }
  • Helper method used by the handler to poll and query the status of the document processing job.
    async describeDocProcessJob(jobId: string) {
      try {
        let host = this.bucket + '.ci.' + this.region + '.myqcloud.com';
        let url = 'https://' + host + '/doc_jobs/' + jobId;
        const result = await new Promise((resolve, reject) => {
          this.cos.request(
            {
              Bucket: this.bucket, // Bucket 格式:test-1250000000
              Region: this.region,
              Method: 'GET',
              Key: 'doc_jobs/' + jobId,
              Url: url,
            },
            function (error, data) {
              if (error) {
                // 处理请求失败
                reject(error);
              } else {
                // 处理请求成功
                resolve(data);
                //获取返回的jobid, 去调查询任务接口, 返回具体信息
              }
            },
          );
        });
    
        return {
          isSuccess: true,
          message: '文档转pdf成功',
          data: result,
        };
      } catch (error) {
        return {
          isSuccess: false,
          message: '文档转pdf失败',
          data: error,
        };
      }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the tool creates a processing job but doesn't explain what happens after creation (e.g., asynchronous processing, job status tracking, error handling, or output location). For a job creation tool with zero annotation coverage, this leaves critical behavioral traits unspecified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence in Chinese that directly states the tool's purpose without unnecessary words. It's appropriately concise for a simple tool, though it could be more informative without sacrificing brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool creates a processing job (implying asynchronous behavior) with no annotations and no output schema, the description is incomplete. It doesn't cover what the job entails, how to track it, what the output is (e.g., a PDF file location), or error conditions. For a job creation tool, this leaves significant gaps in understanding its full context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, with the single parameter 'objectKey' clearly documented as '对象在存储桶里的路径' (path of the object in the storage bucket). The description doesn't add any meaning beyond this, such as explaining what types of documents are supported or format requirements. Baseline 3 is appropriate since the schema adequately covers the parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description '创建文档转 pdf 处理任务' (Create document to PDF processing job) clearly states the verb ('create') and resource ('document to PDF processing job'), making the purpose understandable. However, it doesn't distinguish this tool from potential alternatives or explain what type of document conversion it performs beyond the basic concept.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'describeDocProcessJob' (which might check job status) or other document processing tools. It lacks context about prerequisites, such as needing a document already stored in the bucket, or when this tool is appropriate compared to direct PDF creation methods.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/xiaomizhoubaobei/MCP'

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