agentleFS
n24q02mn24q02m/better-email-mcp/AGENTS.md

better-email-mcp

AGENTS.md33 starsChanged 8 months agoApache-2.0View on GitHub

MCP Server for Email (IMAP/SMTP). TypeScript, Node.js >= 24, bun, ESM.

We split this AGENTS.md into the rules it gives an agent

1 rule. About 0 are common, 1 is distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every composite tool exports: 1 async function + 1 interface

    line 111

≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

AGENTS.md - email

MCP Server for Email (IMAP/SMTP). TypeScript, Node.js >= 24, bun, ESM.

Build / Lint / Test Commands

bun install                 # Install dependencies
bun run build               # tsc --build && esbuild CLI bundle
bun run check               # Biome check + tsc --noEmit (CI command)
bun run check:fix           # Auto-fix Biome + type check
bun run test                # vitest --passWithNoTests
bun run test:watch          # vitest watch
bun run test:coverage       # vitest --coverage
bun run lint                # biome check .
bun run format              # biome format --write .
bun run type-check          # tsc --noEmit
bun run dev                 # tsx watch dev server

# Run a single test file
bun vitest run src/tools/helpers/errors.test.ts

# Run a single test by name
bun vitest run -t "test name pattern"

# Mise shortcuts
mise run setup              # Full dev environment setup
mise run lint               # bun run check
mise run test               # bun run test
mise run fix                # bun run check:fix

Environment Variables

# Required: email credentials (App Passwords, NOT regular passwords)
EMAIL_CREDENTIALS=user@gmail.com:abcd-efgh-ijkl-mnop

# Multiple accounts
EMAIL_CREDENTIALS=user1@gmail.com:pass1,user2@outlook.com:pass2

# Custom IMAP host (optional :port, default 993)
EMAIL_CREDENTIALS=user@custom.com:password:imap.custom.com:1993

# Local IMAP proxy ("localhost" is accepted as a host)
EMAIL_CREDENTIALS=user@custom.com:password:localhost:1993

Code Style

Formatting (Biome)

  • Indent: 2 spaces
  • Line width: 120
  • Quotes: Single quotes
  • Semicolons: As needed (omit when possible)
  • Trailing commas: None
  • Arrow parens: Always
  • Bracket spacing: true
  • Line endings: LF

Imports

  1. Type imports use import type (separate statement)
  2. External packages first, then internal imports (relative paths)
  3. Node builtins with node: prefix (node:fs, node:path, node:url)
  4. Always use .js extension in import paths (ESM requirement)
import type { AccountConfig } from '../helpers/config.js'
import { EmailMCPError, withErrorHandling } from '../helpers/errors.js'
import { searchEmails, readEmail } from '../helpers/imap-client.js'

TypeScript

  • strict: true, target: es2021, module: es2022, moduleResolution: Bundler
  • composite: true for incremental builds
  • isolatedModules: true, forceConsistentCasingInFileNames: true

Naming Conventions

ElementConventionExample
Functions/variablescamelCaseregisterTools, loadConfig
InterfacesPascalCaseMessagesInput, AccountConfig
ClassesPascalCaseEmailMCPError
ConstantsUPPER_SNAKE_CASETOOLS, RESOURCES, DOCS_DIR
Files (helpers)kebab-caseinit-server.ts, imap-client.ts
Test filesCo-locatederrors.test.ts next to errors.ts

Error Handling

  • Custom EmailMCPError class: message, code, suggestion, details
  • withErrorHandling() HOF wrapper for all composite tool functions
  • enhanceError() converts raw errors to AI-friendly EmailMCPError
  • suggestFixes() for AI-readable error recovery hints
  • Error details sanitized to prevent secret/password leakage

Biome Lint Rules

  • noExplicitAny: off (email API responses use any)
  • noNonNullAssertion: off (! assertion allowed)
  • noUnusedVariables: warn
  • noUnusedImports: error (via organizeImports)

Architecture Pattern

  • Composite/Mega Tool: Each public domain (messages, folders, attachments, config) is one function. Outbound new/reply/forward actions live under messages and delegate to the internal src/tools/composite/send.ts implementation.
  • Input: { action, ...params }, dispatch via switch(input.action)
  • Every composite tool exports: 1 async function + 1 interface
  • Signature: async function toolName(accounts: AccountConfig[], input: TypedInput): Promise<any>
  • Account resolution: filter by email, id, or partial match

File Organization

src/
  init-server.ts              # Server entry point, env validation
  docs/                       # Markdown docs served as MCP resources
  tools/
    registry.ts               # Tool registration + routing
    composite/                 # Public domains: messages, folders, attachments, config; internal outbound helper: send.ts
    helpers/                   # errors, config, html-utils, imap-client, smtp-client

Documentation

  • /** */ JSDoc on every function
  • File-level block comment describing module purpose
  • No @param/@returns -- rely on TypeScript types

Commits

Conventional Commits: type(scope): message. Enforced via git hooks.

Pre-commit Hooks

  1. biome check --write (lint + format)
  2. tsc --noEmit (type check)
  3. bun run test (run tests)

Download now (ZIP)

  • Other versions1 project uses a version of this.

    Word for word · 1

    1. n24q02m/email★ 33100% same

    Edited · 0

    None found.

    Wrote their own version · 0

    None found.

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repository3 other files it gives its agents.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.