Skip to main content
Glama

convert_record

Convert records between formats like PDF, HTML, markdown, and webarchive while preserving originals. Place converted records in specific groups for organized document management.

Instructions

Convert a record to a different format, creating a new record. The original record is not modified. Supported formats: bookmark, simple, rich, note, markdown, HTML, webarchive, 'PDF document', 'single page PDF document', 'PDF without annotations', 'PDF with annotations burnt in'. Optionally place the converted record in a specific destination group. Returns the properties of the newly created converted record.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
uuidNoUUID of the record to convert
recordIdNoNumeric record ID (requires databaseName)
recordPathNoRecord path within the database (requires databaseName)
destinationGroupUuidNoUUID of the destination group for the converted record (optional)
databaseNameNoDatabase name (required for recordId or recordPath lookups)

Implementation Reference

  • The 'run' function within 'convertRecordTool' executes the JXA script to convert a DEVONthink record.
      run: async (args, executor) => {
        const { uuid, recordId, recordPath, format, destinationGroupUuid, databaseName } = args;
    
        const script = `
          ${JXA_APP}
          var uuid = ${jxaLiteral(uuid ?? null)};
          var recordId = ${jxaLiteral(recordId ?? null)};
          var recordPath = ${jxaLiteral(recordPath ?? null)};
          var recordName = null;
          var dbName = ${jxaLiteral(databaseName ?? null)};
          var targetFormat = ${jxaLiteral(format)};
          var destinationGroupUuid = ${jxaLiteral(destinationGroupUuid ?? null)};
    
          ${JXA_RESOLVE_DB}
          ${JXA_RESOLVE_RECORD}
    
          var convertOpts = {record: record, to: targetFormat};
    
          if (destinationGroupUuid) {
            var destGroup = app.getRecordWithUuid(destinationGroupUuid);
            if (!destGroup || !destGroup.uuid()) throw new Error("Destination group not found for UUID: " + destinationGroupUuid);
            convertOpts.in = destGroup;
          }
    
          var converted = app.convert(convertOpts);
          if (!converted || !converted.uuid()) throw new Error("Convert operation failed");
    
          var record = converted;
          JSON.stringify(${JXA_RECORD_PROPS});
        `;
    
        const result = executor.run(script);
        return JSON.parse(result.stdout);
      },
    });
  • The Zod schema defines the input parameters for the convert_record tool.
    schema: z.object({
      uuid: z.string().optional().describe("UUID of the record to convert"),
      recordId: z.number().int().nonnegative().optional().describe("Numeric record ID (requires databaseName)"),
      recordPath: z.string().optional().describe("Record path within the database (requires databaseName)"),
      format: z.enum(CONVERT_FORMATS).describe(
        "Target format for conversion: bookmark, simple, rich, note, markdown, HTML, webarchive, " +
        "'PDF document', 'single page PDF document', 'PDF without annotations', or 'PDF with annotations burnt in'"
      ),
      destinationGroupUuid: z.string().optional().describe("UUID of the destination group for the converted record (optional)"),
      databaseName: z.string().optional().describe("Database name (required for recordId or recordPath lookups)"),
    }),
  • The 'convertRecordTool' object definition which registers the tool under the name 'convert_record'.
    export const convertRecordTool = defineTool({
      name: "convert_record",
      description:
        "Convert a record to a different format, creating a new record. " +
        "The original record is not modified. " +
        "Supported formats: bookmark, simple, rich, note, markdown, HTML, webarchive, " +
        "'PDF document', 'single page PDF document', 'PDF without annotations', 'PDF with annotations burnt in'. " +
        "Optionally place the converted record in a specific destination group. " +
        "Returns the properties of the newly created converted record.",
      schema: z.object({
        uuid: z.string().optional().describe("UUID of the record to convert"),
        recordId: z.number().int().nonnegative().optional().describe("Numeric record ID (requires databaseName)"),
        recordPath: z.string().optional().describe("Record path within the database (requires databaseName)"),
        format: z.enum(CONVERT_FORMATS).describe(
          "Target format for conversion: bookmark, simple, rich, note, markdown, HTML, webarchive, " +
          "'PDF document', 'single page PDF document', 'PDF without annotations', or 'PDF with annotations burnt in'"
        ),
        destinationGroupUuid: z.string().optional().describe("UUID of the destination group for the converted record (optional)"),
        databaseName: z.string().optional().describe("Database name (required for recordId or recordPath lookups)"),
      }),
      run: async (args, executor) => {
        const { uuid, recordId, recordPath, format, destinationGroupUuid, databaseName } = args;
    
        const script = `
          ${JXA_APP}
          var uuid = ${jxaLiteral(uuid ?? null)};
          var recordId = ${jxaLiteral(recordId ?? null)};
          var recordPath = ${jxaLiteral(recordPath ?? null)};
          var recordName = null;
          var dbName = ${jxaLiteral(databaseName ?? null)};
          var targetFormat = ${jxaLiteral(format)};
          var destinationGroupUuid = ${jxaLiteral(destinationGroupUuid ?? null)};
    
          ${JXA_RESOLVE_DB}
          ${JXA_RESOLVE_RECORD}
    
          var convertOpts = {record: record, to: targetFormat};
    
          if (destinationGroupUuid) {
            var destGroup = app.getRecordWithUuid(destinationGroupUuid);
            if (!destGroup || !destGroup.uuid()) throw new Error("Destination group not found for UUID: " + destinationGroupUuid);
            convertOpts.in = destGroup;
          }
    
          var converted = app.convert(convertOpts);
          if (!converted || !converted.uuid()) throw new Error("Convert operation failed");
    
          var record = converted;
          JSON.stringify(${JXA_RECORD_PROPS});
        `;
    
        const result = executor.run(script);
        return JSON.parse(result.stdout);
      },
    });
Behavior5/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure and succeeds admirably. It discloses the non-destructive nature (original preserved), lists all supported format enumerations, mentions the optional destination placement side effect, and describes the return value ('Returns the properties of the newly created converted record') despite the absence of an output schema.

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 well-structured with the core action front-loaded, followed by immutability guarantees, format options, optional parameters, and return value. The format list is lengthy but justified given the lack of schema enum definition. Minor wordiness ('creating a new record' vs 'creates a new record') prevents a perfect score.

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

Completeness5/5

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

Given the tool's medium complexity (5 parameters, format conversion logic) and the absence of both annotations and an output schema, the description is remarkably complete. It covers the operation's scope, behavioral constraints, input requirements (via format list), side effects, and return value, leaving no critical gaps for an agent to invoke the tool correctly.

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

Parameters4/5

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

While the schema has 100% coverage of its defined properties, the description adds critical semantic value by enumerating the supported format strings (which appears to be a required parameter missing from the schema properties object) and clarifying that the destination group is optional. It could further improve by explaining the mutual exclusivity logic between uuid, recordId, and recordPath.

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

Purpose5/5

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

The description clearly states the core action ('Convert a record to a different format') and explicitly distinguishes this tool from update or duplicate operations by stating it creates a new record while leaving the original unmodified. This specificity helps the agent select it correctly over sibling tools like update_record_content or duplicate_record.

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

Usage Guidelines4/5

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

The description provides clear behavioral context by emphasizing that the original record is preserved and a new record is created, implicitly guiding against using this for in-place edits. However, it does not explicitly name alternative tools (e.g., 'use update_record_content to modify in place') or state explicit prerequisites, stopping short of a perfect score.

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/mnott/Devon'

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