Skip to main content
Glama

Create email template

lnkdrp_create_email_template
Idempotent

Creates an email template in the workspace: a name, a format (text or html), a subject and a body with replaceable tags. Tags are written {{entity.field}}, or {{entity.field|fallback}} for text used when the value is empty. Built-in tags, filled by LinkDrop for each recipient: contact.firstName: The first word of the contact's name. (e.g. Ken); contact.name: The contact's name: the name the team gave them, else the name they gave. (e.g. Ken Lee); contact.lastName: Everything after the first word of the contact's name. (e.g. Lee); contact.email: The contact's email address. (e.g. ken@example.com); contact.company: The domain of the contact's address; empty for a webmail address such as gmail.com. (e.g. acme.com); contact.note: The team's note on the contact, as written; it goes into the email exactly as it is. (e.g. Met at the October demo day.); contact.tags: The contact's tags, comma-separated. (e.g. Investor, Seed); contact.firstSeen: When LinkDrop first saw the contact, e.g. October 22, 2026. (e.g. October 22, 2026); contact.lastSeen: When the contact was last seen, e.g. October 22, 2026. (e.g. October 22, 2026); contact.visits: How many times the contact has viewed, as a number. (e.g. 3); link.url: The recipient's own LinkDrop link to the document or project; one link per person, reused on every render. (e.g. https://lnkdrp.com/s/example); link.password: The password of the recipient's own link; empty when the link has none. Filled when the email is sent and for a member signed in to the app; a connected agent sees [password]. (e.g. chris58); document.title: The document's title (document emails only). (e.g. Q3 investor update); project.name: The project's name (project emails only). (e.g. Series A data room); sender.name: The name of the member the email is from. (e.g. Chris); sender.firstName: The first word of the sender's name. (e.g. Chris); sender.email: The sender's LinkDrop account email (not necessarily the Gmail address the email goes out from). (e.g. chris@example.com); workspace.name: The workspace's name. (e.g. LinkDrop). {{link.url}} is one link per recipient: their own LinkDrop link to the one document or project the email is rendered for, reused on every render. A template's links (its own documents and projects) put several in one email, each wherever its {{link.}} is written: every recipient gets their own tracked link to each. A project is the other way: one link to all of its documents. {{link.url}} appears in every template without links; a template with links places at least one of them. Custom tags are {{custom.name}}, each declared in tags with a description of what it stands for, and hold words taken from lnkdrp_render_email's values; a custom tag whose name or description reads as a link (..._link, ..._url, an address) is refused as validation with details.code custom_tag_is_link. An unknown tag, a template without {{link.url}} (or, with links, without any of them), a single-document tag beside two or more links, or an HTML body with scripts, frames, forms or event attributes is refused as validation with details.code (unknown_tag, bad_tag, link_tag_required, link_tag_ambiguous, html_not_allowed, custom_tag_is_link). An HTML body shows images only from this workspace's uploads: an image is uploaded with lnkdrp_upload_email_asset and placed with the imgTag it returns (lnkdrp_list_email_assets lists those already uploaded). Any other image source (another site, data:) is refused as validation with details.code image_not_an_asset, on save, render and send; a javascript: URL or a is details.code html_not_allowed. The text version shows an image as [alt]. Each image is kept under 10 MB on every plan (big images make emails slow to open and more likely to be clipped or land in spam): an uploaded image over it in the body is swapped for a smaller copy on save. One email shows at most 10 images, 20 MB in all: over that, the save makes the images smaller, the largest first, until the email fits (reason email). imagesResized [{ name, from, to, assetId, note, reason }] lists each one. When it cannot fit, the save is refused as validation with details.code too_many_images or images_too_heavy, a sentence saying the limit and what to change, and details.limits. Returns the template with every tag it uses (entity, description, required, example), unusedTags: declared custom tags the text does not use, and warnings: notes as { code, message } on a template that saved as sent. body_self_centred: the html body's outermost element centres itself with auto side margins (margin: 0 auto) while align is left, so the email still shows centred; the body is saved unchanged. link_unused: one of the template's links is not placed in the body, so that document goes out to no one. no_documents: the template has no links of its own, so each drop or email made from it takes its document from its own docId or projectId. A name already used in the workspace is validation with details.code name_taken. At the workspace's cap on active templates it is validation with details.code templates_limit (archived templates are not counted, so archiving one makes room), and past its new templates in 24 hours, created and duplicated alike, it is rate_limited with details.code templates_daily_limit and details.retryAt; both caps are the plan's (capabilities.outreachLimits in lnkdrp_whoami) and details.limit says the one reached. New email templates are private to their owner (the person this connection acts for) unless visibility is team; this is not a document's visibility (lnkdrp_set_doc_visibility). Names are unique across private and team templates.

Input Schema

NameRequiredDescriptionDefault
bodyYesThe body, with tags (up to 50,000 characters); contains {{link.url}} at least once, or, for a template with links, at least one {{link.<key>}}.
nameYesThe template's name, unique in the workspace (1-80 characters).
tagsNoTag declarations: every {{custom.x}} used, with its description; a built-in may be listed to override its description or required.
alignNoWhere an html email sits in the reader's window. left (the default): nothing is added around the body, so it shows flush left. center: the body is placed in a centred column at most 600px wide. The text version is unaffected.
linksNoThe template's documents and projects, each placed in the body by {{link.<key>}} wherever it should appear (as often as wanted). Every recipient gets their own tracked link to each, made with its settings, when the email is rendered; a send or render then needs no docId or projectId. With one, {{link.url}} also means it; with two or more, {{link.url}}, {{link.password}}, {{document.title}} and {{project.name}} are refused (link_tag_ambiguous). On an update the list replaces the template's documents.
formatYestext: a plain-text body (an HTML version is derived from it). html: an HTML body (a text version is derived from it).
subjectYesThe subject line, with tags (one line, up to 200 characters).
visibilityNoprivate: only its owner sees the email template. team: everyone in the workspace sees it. Not a document's visibility (lnkdrp_set_doc_visibility).
descriptionNoWhat the template is for (up to 500 characters).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • changedInput schema / properties / body / description
      Previous value: -"The body, with tags; contains {{link.url}} at least once (up to 50,000 characters)."New value: +"The body, with tags (up to 50,000 characters); contains {{link.url}} at least once, or, for a template with links, at least one {{link.<key>}}."
    • addedInput schema / properties / links
      Added value: +{
      +  "description": "The template's documents and projects, each placed in the body by {{link.<key>}} wherever it should appear (as often as wanted). Every recipient gets their own tracked link to each, made with its settings, when the email is rendered; a send or render then needs no docId or projectId. With one, {{link.url}} also means it; with two or more, {{link.url}}, {{link.password}}, {{document.title}} and {{project.name}} are refused (link_tag_ambiguous). On an update the list replaces the template's documents.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "allowDownload": {
      +        "description": "Readers may download the PDF. Default false.",
      +        "type": "boolean"
      +      },
      +      "allowRevisionHistory": {
      +        "description": "Readers may open recent versions (Pro). Default false.",
      +        "type": "boolean"
      +      },
      +      "contactRole": {
      +        "description": "direct (default): the link is for that person; share: they may pass it on.",
      +        "enum": [
      +          "direct",
      +          "share"
      +        ],
      +        "type": "string"
      +      },
      +      "docId": {
      +        "description": "The document; exactly one of docId or projectId.",
      +        "pattern": "^[a-fA-F0-9]{24}$",
      +        "type": "string"
      +      },
      +      "expiresAfterDays": {
      +        "anyOf": [
      +          {
      +            "maximum": 365,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Days after it is made that each person's link stops working; null or left out: no expiry."
      +      },
      +      "key": {
      +        "description": "The tag that places it in the body: {{link.<key>}}. Not url or password. Left out: made from the document's title.",
      +        "pattern": "^[a-z][a-z0-9_]{0,39}$",
      +        "type": "string"
      +      },
      +      "password": {
      +        "anyOf": [
      +          {
      +            "maxLength": 128,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "A password every person's link to it asks for, the same for everyone; null: none; left out: the one this key already has."
      +      },
      +      "projectId": {
      +        "description": "The project; exactly one of docId or projectId.",
      +        "pattern": "^[a-fA-F0-9]{24}$",
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "maxItems": 10,
      +  "type": "array"
      +}
    • addedInput schema / properties / visibility
      Added value: +{
      +  "description": "private: only its owner sees the email template. team: everyone in the workspace sees it. Not a document's visibility (lnkdrp_set_doc_visibility).",
      +  "enum": [
      +    "private",
      +    "team"
      +  ],
      +  "type": "string"
      +}
  2. Added

TDQS

A4.1/5.0
Behavior5/5

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

Annotations only supply safety hints (readOnlyHint=false, idempotentHint=true, destructiveHint=false); the description goes far beyond them, disclosing image size/count caps with the exact downgrade behaviour and reason codes, template and daily-creation caps with retryAt, default private visibility, name-uniqueness, and a full enumeration of validation/rate-limit detail codes with the conditions that trigger them. It also describes the return payload, which no output schema covers.

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

Conciseness2/5

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

The definition is a single semicolon-chained wall of roughly a thousand words, with tag enumeration, error-code taxonomy and resize rules all crammed into one block. Much of the content is genuinely useful, but it is not front-loaded or segmented, and large portions (every built-in tag with an example, every failure code) would be better placed in a reference or in the schema.

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?

For a 9-parameter mutation with no output schema, the description is complete: it covers the required fields, the optional links/tags structures, the caps that can block a save, and the exact shape of the response (tags used, unusedTags, warnings, imagesResized). An agent has everything needed to call it and interpret the result.

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?

Schema coverage is 100%, so the baseline is 3; the description earns above baseline by explaining the tag grammar ({{entity.field}} and {{entity.field|fallback}}), cataloguing every built-in tag with its value semantics and example, and defining what custom tags are and which are rejected as custom_tag_is_link. It does not touch `align` or `visibility` in prose beyond the private/team sentence, so it is not a full 5.

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

Purpose4/5

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

The opening sentence gives a specific verb and resource with the four required fields named: 'Creates an email template in the workspace: a name, a format (text or html), a subject and a body with replaceable tags.' It is clearly a creation tool, distinguishable from lnkdrp_update_email_template and lnkdrp_duplicate_email_template by the verb, though it never explicitly contrasts itself with those siblings.

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?

It routes the agent to specific siblings in specific situations: images must be uploaded via lnkdrp_upload_email_asset and discovered via lnkdrp_list_email_assets, caps come from lnkdrp_whoami, custom tag values come from lnkdrp_render_email. It also explains what is refused and why. What is missing is the negative case — it never says when to use update/duplicate/preview instead of create.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources