Email SDK
Agents

Agent skill

Install the Email SDK skill for coding agents and expose a send_email tool with createEmailAgentTools.

Two ways to put Email SDK in front of an agent: a skill that teaches coding agents (Claude Code and compatible tools) how to integrate the SDK correctly, and a tool factory that lets a runtime agent send email through your configured client.

The email-sdk skill

The repo ships a skill at skills/email-sdk/SKILL.md. Install it with the skills CLI:

npx skills add opencoredev/email-sdk --skill email-sdk

Or copy the skills/email-sdk/ directory into your repo's skills directory (.claude/skills/email-sdk/ for Claude Code). Agents pick it up whenever they add, review, or document an Email SDK integration.

What it enforces

  • Refresh docs first. The skill is deliberately dynamic: before writing code, the agent reads the installed package's README, package.json exports, and TypeScript declarations — so it implements against the version actually installed, not stale training data.
  • Correct imports and secrets. Adapters come from their own entry points (@opencoredev/email-sdk/resend, /smtp, ...), credentials stay in environment variables, and no Nodemailer — the SDK includes its own SMTP transport.
  • Compatible fallbacks. Fallback routes only when the backup adapter supports the same fields, checked against field support. Idempotency keys on externally visible sends that may retry.
  • CLI smoke tests. email-sdk doctor and send --dry-run before any live send, and no real external mail without your approval.
  • Secret-safe observability. Hooks and the observability plugin for redacted events — never API keys, message bodies, or unnecessary recipient data in logs.
  • Narrow validation. The smallest test or typecheck that covers the send path before declaring the work done.

Prompt example

Use the email-sdk skill.
Wire Resend as the primary adapter and SMTP as fallback.
Keep secrets in environment variables.
Add one narrow test around the send path.

Agent tools: send email at runtime

createEmailAgentTools(client) from @opencoredev/email-sdk/agent-tools turns an email client into tool definitions an LLM agent can call:

lib/agent-email.ts
import { createEmailClient } from "@opencoredev/email-sdk";
import { resend } from "@opencoredev/email-sdk/resend";
import { createEmailAgentTools } from "@opencoredev/email-sdk/agent-tools";

const email = createEmailClient({
  adapters: [resend({ apiKey: process.env.RESEND_API_KEY! })],
});

export const { sendEmail } = createEmailAgentTools(email);

It returns one tool, sendEmail, as a plain EmailAgentTool object:

Prop

Type

Because the tool is plain data plus an execute function, it maps onto any agent framework's tool format:

agent.ts
import { sendEmail } from "./lib/agent-email";

// Most frameworks accept a name, a description, and a JSON Schema:
const tools = [
  {
    name: sendEmail.name, // "send_email"
    description: sendEmail.description,
    inputSchema: sendEmail.parameters,
  },
];

// When the model calls the tool, hand its arguments to execute:
async function handleToolCall(name: string, input: unknown) {
  if (name === sendEmail.name) {
    return sendEmail.execute(input as Parameters<typeof sendEmail.execute>[0]);
  }
  throw new Error(`Unknown tool: ${name}`);
}

execute goes through the full client pipeline — validation, retries and fallbacks, plugins, hooks — so an agent send behaves exactly like any other send in your app.

Gate agent sends

The tool description asks the model to confirm before sending, but the model decides whether to comply. For production agents, add your own approval step or sandbox the client with a memory adapter until the flow is trusted.

On this page