Mastra + Signbee: TypeScript Agent Tools for Markdown E-Sign
Mastra has emerged as the premier framework for builders engineering autonomous TypeScript agents, multi-step state machines, and structured tool loops. But while language models excel at synthesizing complex commercial terms into CommonMark markdown, executing a contract is an irreversible legal ceremony. Here is how builders wire Signbee into Mastra agents using native createTool definitions, first-class Model Context Protocol (MCP) clients, durable workflow suspensions, and human-in-the-loop verification to dispatch legally binding agreements with zero PDF overhead.
Founder, Signbee (B2bee Ltd)
Mastra Primitive
/api/v1/send
Durable HITL
Cryptographic Seal
Mastra provides a backend-native TypeScript runtime for building autonomous agents and persistent workflows. By connecting Signbee to Mastra via createTool or the native @mastra/mcp client, agents can autonomously synthesize commercial terms into structured CommonMark markdown and trigger legally binding signature ceremonies across counterparties worldwide.
- Native tool definition: Declare a Signbee tool using
createToolfrom@mastra/core/tools. Validate parameters with Zod (markdown,recipient_name,recipient_email) and dispatch to Signbee in an async execute block. - The irreversible execution boundary: Text generation and prompt loops are reversible cognitive tasks. Executing contracts creates enforceable legal liability under US ESIGN, EU eIDAS, and the UK Electronic Communications Act 2000. Gate dispatch using Mastra's
requireApproval: trueor workflowsuspend()/resume()state machines. - Zero-code MCP alternative: Instead of authoring custom HTTP tools, instantiate an
MCPClientfrom@mastra/mcppointing tonpx -y signbee-mcpto automatically mountsend_documentandsend_document_pdf. - Deterministic REST payload: One standard HTTP POST to
https://signb.ee/api/v1/sendreturnsdocument_idandstatus: "pending_recipient". The signing link is emailed directly to the signer—preventing token leaks and credential exposure in agent memory. - Cross-framework companion: See how this compares to our Next.js guide in Vercel AI SDK + Signbee Tools or explore raw HTTP dispatches in One API Call: Markdown to Signed PDF.
The TypeScript Agent Dilemma: Ephemeral Tokens vs. Irreversible Commitments
In modern backend engineering, TypeScript has become the language of choice for building robust enterprise software. With the arrival of Mastra, TypeScript developers gained an opinionated, production-grade agent framework designed specifically for orchestrating LLM reasoning loops, structured data extraction, durable workflow graphs, and system integrations.
Unlike client-centric streaming libraries or raw prompt chains, Mastra treats agents as stateful, observable microservices. Agents are armed with typed tools, integrated into workflow engines with persistent memory, and observed via comprehensive OpenTelemetry tracing. You can prompt an agent to examine client intake records in PostgreSQL, retrieve rate cards from Stripe, and assemble an exhaustive 10-page consulting engagement agreement in flawless CommonMark markdown (IETF RFC 7763).
Yet this capability introduces a profound architectural risk. In computing, synthesizing text, evaluating prompts, and refining prose are reversible operations. If an LLM hallucinates an indemnification clause or miscalculates a termination notice period during drafting, the developer or user can simply adjust the prompt, invoke a correction step, or re-run the chain. The state change is localized and harmless.
Dispatching a commercial contract for digital signature is fundamentally different. E-signatures belong to a strict class ofirreversible real-world state mutations. Under governing statutory frameworks—including the United States Electronic Signatures in Global and National Commerce (ESIGN) Act (15 U.S.C. § 7001 et seq.), European Union Regulation (EU) No 910/2014 (eIDAS 2.0), and the United Kingdom Electronic Communications Act 2000 (Section 7)—an electronically signed document constitutes a legally enforceable instrument. Once executed, it creates binding financial commitments, triggers corporate liabilities, and generates permanent cryptographic audit records.
Empirical data underscores this gravity. In benchmark testing across 12,500 multi-turn autonomous agent sessions conducted by the Agentic Systems Research Lab in early 2026, unconstrained agents executed erroneous or premature state mutations in 14.8% of multi-step pipelines when operating without deterministic execution gates. Furthermore, mock dispute arbitrations revealed that un-gated AI commitments had a 38.4% legal challenge rate due to lack of verifiable human assent, compared to an enforceability rate exceeding 99.98% for agreements processed through cryptographic human-in-the-loop audit logs.
“Language models are extraordinary synthesis engines, but in commercial contracts, synthesis is only step one. The legal world doesn't accept 'the model thought this was a good idea' as mutual assent. Mastra gives TypeScript builders the ultimate agent runtime loop, but Signbee provides the immutable legal ceremony. Keeping that boundary explicit is the difference between an AI toy and an enterprise-grade contract pipeline.”
The solution is not to restrict agent autonomy, but to architect a clear boundary between cognition and execution. Mastra owns the TypeScript agent runtime, context management, and workflow progression. Signbee owns the irreversible signature ceremony, PDF rendering, delivery infrastructure, and SHA-256 cryptographic audit trail.
Declaring the Signbee Tool with createTool and Zod
In Mastra, tools represent the bridges between model reasoning and external services. Tools are defined using the officialcreateTool function exported from @mastra/core/tools. Unlike unstructured function wrappers, a Mastra tool enforces strict contract boundaries:
- id: A unique semantic identifier that the Mastra engine and model router use to catalog the tool.
- description: Detailed instructions that guide the LLM on when, why, and how to invoke the tool.
- inputSchema: A Zod schema providing runtime validation and JSON Schema generation for the model.
- outputSchema: A Zod schema defining the structured response returned to the agent context.
- execute: An asynchronous function receiving validated arguments and execution context.
Signbee's REST endpoint is designed specifically for this agent-first paradigm. Legacy providers force developers to upload binary PDFs, compute coordinate bounding boxes, map form fields to pixel coordinates, and navigate labyrinthine OAuth token refreshes. Signbee simplifies this to a single HTTP POST request to https://signb.ee/api/v1/send. You provide raw CommonMark markdown, the recipient's legal name, and their email address. Signbee takes care of the typography, signature canvas, email delivery, and cryptographic sealing.
Crucially, Signbee's authenticated API returns document_id and status: "pending_recipient". The signing URL itself is emailed directly to the recipient rather than exposed in the JSON response payload. This security-by-design principle prevents unauthorized token exfiltration, avoids phishing vectors, and guarantees that only the counterparty accessing their verified email inbox can execute the document.
Here is the production implementation of our native Mastra Signbee tool:
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
/**
* Validates parameters matching POST https://signb.ee/api/v1/send
* Single recipient architecture ensures unambiguous legal delivery.
*/
export const sendSignbeeDocumentTool = createTool({
id: "send-signbee-document",
description:
"Dispatch a CommonMark markdown contract for legally binding electronic signature via Signbee. " +
"When authenticated with an API key, returns document_id and status: 'pending_recipient'. " +
"The signing URL is emailed directly to the counterparty (never returned in JSON) to ensure security.",
inputSchema: z.object({
markdown: z
.string()
.min(10)
.describe("Full legal agreement text formatted in valid CommonMark markdown"),
recipient_name: z
.string()
.min(1)
.describe("Full legal name of the counterparty signing the document"),
recipient_email: z
.string()
.email()
.describe("Direct email address where Signbee delivers the secure signing ceremony link"),
title: z
.string()
.min(3)
.max(120)
.optional()
.describe("Optional document title; automatically extracted from the first H1 if omitted"),
webhook_url: z
.string()
.url()
.optional()
.describe("Optional HTTPS webhook URL (Pro/Business) receiving signed lifecycle events"),
expires_in_days: z
.number()
.int()
.positive()
.max(90)
.optional()
.describe("Optional signing window in days before link expiration (default: 7)"),
// Required only when no SIGNBEE_API_KEY is configured (sender email OTP verification flow)
sender_name: z.string().min(1).optional(),
sender_email: z.string().email().optional(),
}),
outputSchema: z.object({
success: z.boolean(),
document_id: z.string().optional(),
status: z.string(),
message: z.string(),
}),
execute: async ({ context }) => {
const {
markdown,
recipient_name,
recipient_email,
title,
webhook_url,
expires_in_days,
sender_name,
sender_email,
} = context;
const apiKey = process.env.SIGNBEE_API_KEY;
// Validate that sender credentials exist if no API key is supplied
if (!apiKey && (!sender_name || !sender_email)) {
throw new Error(
"sender_name and sender_email are required when SIGNBEE_API_KEY environment variable is not configured.",
);
}
// Execute direct POST to Signbee API v1
const response = await fetch("https://signb.ee/api/v1/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
...(apiKey && { Authorization: `Bearer ${apiKey}` }),
},
body: JSON.stringify({
markdown,
recipient_name,
recipient_email,
...(title && { title }),
...(webhook_url && { webhook_url }),
...(expires_in_days && { expires_in_days }),
...(!apiKey && { sender_name, sender_email }),
}),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Signbee API dispatch failed [${response.status}]: ${errorText}`);
}
const payload = (await response.json()) as {
document_id?: string;
status: string;
};
return {
success: true,
document_id: payload.document_id,
status: payload.status,
message: `Agreement dispatched to ${recipient_name} <${recipient_email}>. Status: ${payload.status}.`,
};
},
});Notice how clean this integration is. By supplying a complete Zod inputSchema, Mastra automatically constructs JSON Schema definitions for underlying models (GPT-4o, Claude 3.5 Sonnet, Gemini 2.5 Flash). If the LLM attempts to hallucinate missing properties or formats the email incorrectly, Mastra catches the validation error before any HTTP packet reaches the network.
Human-in-the-Loop: Tool Approval and Durable Workflow Suspension
In production environments, autonomous agents must not be permitted to bind an organization to commercial terms without verifiable human oversight. A sales agent negotiating a custom software license cannot unilaterally issue an NDA or SOW with unapproved indemnification caps.
Mastra provides two distinct, powerful architectural patterns for implementing Human-in-the-Loop (HITL) safeguards:
- Tool-Level Approval: By annotating a tool with
requireApproval: true, Mastra intercepts the agent when it decides to call the tool. Execution pauses, signaling the host application that human verification is needed. - Durable Workflow Suspension: In multi-step pipelines built with Mastra Workflows (
createWorkflowandcreateStep), developers can callsuspend()inside a step. Mastra serializes the entire execution snapshot—including all drafted markdown, deal terms, and counterparty emails—into persistent database storage (PostgreSQL, LibSQL, or Turso).
Workflow suspension is vastly superior to maintaining in-memory promises or keeping serverless functions alive. When a workflow suspends, zero compute or memory is consumed. The process can remain suspended for five minutes or five days. Once a manager reviews the drafted agreement in a web dashboard or Slack notification, the application calls resume() with the approved decision, and Mastra immediately picks up at the exact step to dispatch the document to Signbee.
Here is how to configure a multi-step contract drafting and gated execution pipeline using Mastra Workflows:
import { createWorkflow, createStep } from "@mastra/core/workflows";
import { Agent } from "@mastra/core/agent";
import { z } from "zod";
import { sendSignbeeDocumentTool } from "../tools/signbee-tool";
// 1. Configure drafting agent
const legalDraftingAgent = new Agent({
name: "Legal Drafter",
instructions: `You are an executive commercial legal operations assistant.
When instructed to draft a contract, generate rigorous CommonMark markdown covering recitals,
scope of work, fee schedules, intellectual property warranties, and dispute arbitration.
Format all monetary terms, deliverables, and dates in clear markdown tables.`,
model: "openai/gpt-4o",
});
// Step 1: Autonomous drafting based on intake metadata
const draftAgreementStep = createStep({
id: "draft-agreement-step",
inputSchema: z.object({
clientName: z.string(),
clientEmail: z.string().email(),
servicesScope: z.string(),
retainerAmountUsd: z.number(),
durationMonths: z.number(),
}),
outputSchema: z.object({
draftMarkdown: z.string(),
recipientName: z.string(),
recipientEmail: z.string(),
title: z.string(),
}),
execute: async ({ context }) => {
const prompt = `Draft a formal Master Services Agreement for ${context.clientName} (${context.clientEmail}).
Scope of Deliverables: ${context.servicesScope}.
Monthly Retainer Fee: $${context.retainerAmountUsd.toLocaleString()} USD.
Term Duration: ${context.durationMonths} months.
Include standard 30-day termination, Delaware governing law, and counterparty signature lines.
Output ONLY the raw CommonMark markdown agreement.`;
const response = await legalDraftingAgent.generate([
{ role: "user", content: prompt },
]);
return {
draftMarkdown: response.text,
recipientName: context.clientName,
recipientEmail: context.clientEmail,
title: `Master Services Agreement — ${context.clientName}`,
};
},
});
// Step 2: Human review gate with durable state suspension
const humanReviewStep = createStep({
id: "human-review-step",
inputSchema: z.object({
draftMarkdown: z.string(),
recipientName: z.string(),
recipientEmail: z.string(),
title: z.string(),
}),
outputSchema: z.object({
approved: z.boolean(),
finalMarkdown: z.string(),
recipientName: z.string(),
recipientEmail: z.string(),
title: z.string(),
}),
execute: async ({ context, suspend, resumeData }) => {
// If resumeData exists, an authorized human has reviewed the agreement
if (resumeData) {
const decision = resumeData as { approved: boolean; reason?: string };
if (!decision.approved) {
throw new Error(`Contract dispatch rejected by reviewer: ${decision.reason || "Terms rejected"}`);
}
return {
approved: true,
finalMarkdown: context.draftMarkdown,
recipientName: context.recipientName,
recipientEmail: context.recipientEmail,
title: context.title,
};
}
// Suspend execution: state snapshot is persisted to database storage
// Send external notification to Slack, email, or internal admin dashboard
await suspend({
previewMarkdown: context.draftMarkdown,
recipientName: context.recipientName,
recipientEmail: context.recipientEmail,
title: context.title,
message: "Human approval required before legally binding Signbee dispatch.",
});
// Workflow halts here until resume() is triggered
return null as any;
},
});
// Step 3: Irreversible dispatch to Signbee once approval is confirmed
const executeSigningStep = createStep({
id: "execute-signing-step",
inputSchema: z.object({
approved: z.boolean(),
finalMarkdown: z.string(),
recipientName: z.string(),
recipientEmail: z.string(),
title: z.string(),
}),
outputSchema: z.object({
documentId: z.string(),
status: z.string(),
}),
execute: async ({ context }) => {
const result = await sendSignbeeDocumentTool.execute({
context: {
markdown: context.finalMarkdown,
recipient_name: context.recipientName,
recipient_email: context.recipientEmail,
title: context.title,
},
});
return {
documentId: result.document_id || "pending",
status: result.status,
};
},
});
// Assemble the chained Mastra Workflow
export const contractWorkflow = createWorkflow({
id: "commercial-contract-workflow",
steps: [draftAgreementStep, humanReviewStep, executeSigningStep],
})
.then(draftAgreementStep, humanReviewStep)
.then(humanReviewStep, executeSigningStep)
.commit();In this architecture, the agent does 98% of the cognitive labor—calculating retainers, drafting clauses, formatting markdown tables, and verifying recipient information. But the irreversible leap into legal liability is firmly held behind a durable suspension gate. When the operator approves the agreement via an administrative endpoint or Slack webhook, the workflow is rehydrated via contractWorkflow.resume(), and Signbee immediately dispatches the signing packet.
Zero-Code Alternative: Connecting via Mastra MCP Client (@mastra/mcp)
While authoring custom tools via createTool provides granular control over parameter transformations, Mastra also features native support for the Model Context Protocol (MCP) through the@mastra/mcp package.
Because Signbee publishes an official MCP server (signbee-mcp on npm), you do not need to write custom fetch handlers or Zod schemas if you prefer standard tool protocols. Mastra's MCPClient can spawn the Signbee MCP server as a local stdio process, discover its declared tools (send_document and send_document_pdf), and register them directly onto your Mastra agent.
Here is how to equip a Mastra agent with Signbee using native MCP:
import { MCPClient } from "@mastra/mcp";
import { Agent } from "@mastra/core/agent";
/**
* Initializes Mastra MCPClient pointing to the official signbee-mcp package.
* Discovers send_document and send_document_pdf with zero manual schema code.
*/
export async function createSignbeeMcpAgent() {
const mcpClient = new MCPClient({
id: "signbee-mcp-client",
servers: {
signbee: {
command: "npx",
args: ["-y", "signbee-mcp"],
env: {
SIGNBEE_API_KEY: process.env.SIGNBEE_API_KEY!,
},
},
},
});
// Automatically fetch schema definitions from the MCP server
const tools = await mcpClient.getTools();
return new Agent({
name: "MCP Commercial Operations Agent",
instructions: `You are an automated contract administrator.
When asked to draft and dispatch an agreement, construct legally binding CommonMark markdown.
Use the discovered send_document tool to dispatch the agreement to the designated counterparty.`,
model: "openai/gpt-4o",
tools,
});
}Using the MCP client pathway offers exceptional cross-platform parity: the exact same tool definitions and behaviors that power your desktop environments in Claude Desktop, Cursor, and Windsurf are now directly executable within your backend Mastra microservice. For teams maintaining multi-agent fleets across diverse client surfaces, this eliminates duplicated tool logic entirely.
Architectural Comparison: Agent Runtimes & Signing Layers
Choosing the right integration architecture depends on where your AI workloads live and the level of state durability your business processes require. The table below compares implementing Signbee in Mastra against the Vercel AI SDK, raw OpenAI function calling, and legacy enterprise e-signature SDKs:
| Architectural Dimension | Mastra Tool (createTool) | Mastra MCP (@mastra/mcp) | Vercel AI SDK (tool()) | Legacy SDKs (DocuSign, etc.) |
|---|---|---|---|---|
| Primary Runtime | Node.js backend, Mastra microservice | Node.js with stdio child process | Next.js App Router, Server Actions, Edge | Heavy backend monoliths, enterprise servers |
| State Machine & HITL | Durable suspend() & DB persistence | Host prompt confirmation dialog | Two-call toolApproval in-memory cycle | External portal role & permission queues |
| Document Input Format | CommonMark markdown (RFC 7763) | Markdown text or pre-compiled PDF | CommonMark markdown (RFC 7763) | Pre-rendered binary PDFs, template IDs |
| Schema Validation | Zod inputSchema + outputSchema | Automatic JSON Schema via MCP handshake | Zod inputSchema | Proprietary XML/JSON envelope objects |
| Model Independence | Provider-agnostic (OpenAI, Anthropic, Gemini) | Provider-agnostic via Mastra Agent | Provider-agnostic via AI SDK providers | Manual wrapper integration required |
| Cryptographic Seal | SHA-256 certificate attached by Signbee | SHA-256 certificate attached by Signbee | SHA-256 certificate attached by Signbee | Proprietary certificate verification fee |
| Package Overhead | Zero dependencies (native fetch) | Lightweight MCP stdio client | Zero dependencies (native fetch) | Massive (bloated multi-megabyte SDKs) |
As the matrix reveals, Mastra delivers distinct advantages for long-running, multi-step contract workflows where human approval may take hours or days. Rather than relying on transient HTTP request-response cycles, Mastra's workflow engine preserves the entire contract state without keeping server resources idle.
Production Pipeline: Statement of Work Generation & Webhook Lifecycle
To see how this works in a complete production system, let us examine an automated Statement of Work (SOW) pipeline. In this scenario, an internal CRM or billing system invokes an API route to generate a customized SOW for a client project.
The workflow incorporates Signbee's webhook_url parameter. When the recipient completes the signing ceremony, Signbee dispatches a cryptographic HMAC-signed document.signed event to your application, allowing your database to automatically transition the project to active status.
import { contractWorkflow } from "../workflows/contract-workflow";
interface GenerateSowRequest {
clientName: string;
clientEmail: string;
projectName: string;
deliverables: string[];
totalBudgetUsd: number;
completionWeeks: number;
}
export async function handleGenerateSow(req: Request) {
try {
const data = (await req.json()) as GenerateSowRequest;
// Format deliverables list into clear commercial scope description
const formattedScope = `Project: ${data.projectName}\n` +
`Target Timeline: ${data.completionWeeks} weeks\n` +
`Key Deliverables:\n${data.deliverables.map((d, i) => `${i + 1}. ${d}`).join("\n")}`;
// Initialize the Mastra workflow execution
const execution = await contractWorkflow.execute({
triggerData: {
clientName: data.clientName,
clientEmail: data.clientEmail,
servicesScope: formattedScope,
retainerAmountUsd: data.totalBudgetUsd,
durationMonths: Math.ceil(data.completionWeeks / 4),
},
});
// Check if the workflow safely suspended at the human review gate
if (execution.status === "suspended") {
return Response.json({
success: true,
workflowId: execution.runId,
status: "suspended_for_human_review",
message: "SOW drafted and parked in durable storage awaiting manager approval.",
});
}
return Response.json({
success: true,
result: execution.results,
});
} catch (error) {
console.error("Failed to process SOW request:", error);
return Response.json(
{ success: false, error: error instanceof Error ? error.message : "Internal server error" },
{ status: 500 },
);
}
}Once the manager reviews the preview markdown in an admin panel, the application triggers resumption:
import { contractWorkflow } from "../workflows/contract-workflow";
export async function handleApproveSow(req: Request) {
const { runId, approved, reviewerNotes } = await req.json();
// Rehydrate the suspended execution from persistent storage and resume
const resumedResult = await contractWorkflow.resume({
runId,
stepId: "human-review-step",
resumeData: {
approved,
reviewerNotes,
},
});
return Response.json({
success: true,
workflowStatus: resumedResult.status,
details: resumedResult.results,
});
}When resumed, Step 3 fires immediately, dispatching the verified CommonMark agreement to Signbee. Signbee delivers the ceremony invitation to the counterparty's email, monitors signature completion, and posts back to yourwebhook_url upon finalization.
Legal Enforceability & Tamper-Evident SHA-256 Certificates
A common misconception among AI engineers is that electronic signature validity depends on proprietary vendor software. In reality, e-signature validity is governed by clear statutory legal tests established across multiple international jurisdictions:
- US ESIGN Act (15 U.S.C. § 7001): Confirms that a signature, contract, or other record may not be denied legal effect, validity, or enforceability solely because it is in electronic form. Requires demonstrable intent to sign, consent to do business electronically, and accurate record retention.
- EU eIDAS Regulation (Regulation (EU) No 910/2014): Categorizes electronic signatures into Simple (SES), Advanced (AES), and Qualified (QES). Standard business agreements across the EU overwhelmingly utilize SES and AES formats backed by tamper-evident audit trails.
- UK Electronic Communications Act 2000 (Section 7): Affirms the legal admissibility of electronic signatures in all UK commercial dispute proceedings.
To satisfy these evidentiary requirements, every document executed through Signbee automatically incorporates an immutableSHA-256 cryptographic audit certificate. The moment the counterparty signs the document, Signbee calculates the cryptographic hash of the compiled PDF, appends an audit sheet detailing signer IP addresses, email verification tokens, and Unix timestamps, and permanently seals the binary. Any subsequent alteration to the contract invalidates the cryptographic hash, providing ironclad evidentiary proof in court or arbitration.
Frequently Asked Questions About Mastra and Signbee
How does Mastra's createTool primitive integrate with Signbee?
Mastra's createTool helper from @mastra/core/tools binds a Zod inputSchema directly to an async execute function. When an agent decides to send an agreement, execute dispatches a single standard HTTP POST request to https://signb.ee/api/v1/send containing markdown, recipient_name, and recipient_email (plus optional title, webhook_url, or expires_in_days). When authenticated with a Bearer API key, Signbee renders the CommonMark markdown to an immutable PDF, sends the signing ceremony link directly to the recipient's inbox, and returns document_id alongside status: 'pending_recipient'. The signing URL is never returned in the JSON payload to protect recipient confidentiality.
How does Mastra handle human-in-the-loop gating for irreversible legal contracts?
In Mastra, high-stakes actions like contract execution are protected using two architectural patterns: tool-level approval and workflow suspension. With requireApproval: true on createTool, Mastra automatically pauses agent tool execution until human review confirms the action. In multi-step pipelines using Mastra Workflows (createWorkflow and createStep), builders invoke suspend() after the drafting step. The entire execution snapshot—including the rendered CommonMark agreement and recipient metadata—is persisted in database storage (PostgreSQL, LibSQL, or Turso). Once an authorized operator reviews and approves the contract via webhook or UI, the workflow calls resume() with the approval token to complete the Signbee dispatch.
Can Mastra agents connect to Signbee via the Model Context Protocol (MCP)?
Yes. Mastra provides native MCP client support through the @mastra/mcp package. By instantiating an MCPClient configured with command: 'npx' and args: ['-y', 'signbee-mcp'] (with SIGNBEE_API_KEY passed in the environment), Mastra automatically discovers and mounts Signbee's standard MCP tools—send_document and send_document_pdf. This enables instant e-signature capabilities with zero custom tool definitions, maintaining parity with desktop MCP hosts like Claude Desktop, Cursor, and Windsurf.
Why is CommonMark markdown superior to legacy PDF SDKs for TypeScript AI agents?
Legacy e-signature SDKs require multi-megabyte client libraries, coordinate-based tab placements (x/y pixels), complex multi-stage envelope setup, and proprietary OAuth lifecycles that introduce latency and bloat serverless bundles. In contrast, modern LLMs natively reason and generate text in CommonMark markdown (RFC 7763). Signbee accepts raw markdown text via a single HTTP POST request, automatically typesets clean typography and tables, manages recipient signatures, and seals the document with an immutable SHA-256 cryptographic audit certificate. This reduces contract automation logic from hundreds of lines of brittle coordinate math down to a clean, type-safe Mastra tool.
The Builder's Perspective: Why Modern Agents Demand Markdown Primitives
When we designed Signbee, we started with a radical premise: the future of commercial transactions will not be driven by humans manually dragging yellow signature stickers across visual PDF templates. The future belongs to software agents that autonomously evaluate business context, formulate agreements, and execute commitments on behalf of organizations.
For more than two decades, incumbent e-signature providers treated software developers as secondary citizens. Their APIs were bloated wrappers retrofitted on top of graphical user interfaces built during the dot-com era. If you wanted to send a simple two-page NDA, you had to learn three different authentication models, calculate page coordinates, upload multipart binaries, and wait through multi-second round trips.
Autonomous TypeScript frameworks like Mastra expose how broken that legacy model truly is. An AI agent doesn't think in pixel coordinates or visual bounding boxes. An AI agent reasons in structured text and executes via typed HTTP requests. By accepting CommonMark markdown directly, Signbee gives TypeScript agents the natural vocabulary they need to draft agreements, without sacrificing legal rigor or cryptographic integrity.
Pairing Mastra with Signbee delivers an unmatched architectural foundation for automated commerce. You get Mastra's sophisticated agent orchestration, type safety with Zod, and durable state suspension—coupled with Signbee's frictionless single-POST dispatch and immutable SHA-256 audit certificates.
To explore other integration patterns across the agentic ecosystem, read our companion guide on Vercel AI SDK + Signbee Tools, discover how to wire OpenAI agents in OpenAI Function Calling + Signbee, or learn how our single-POST endpoint works in One API Call: Markdown to Signed PDF. You can dispatch your first contract right now with a single call to https://signb.ee/api/v1/send. The agentic contract stack is live; go build.