Skip to content

AdirAmsalem/easl

Repository files navigation


easl

Turn agent output into pages worth sharing.

License: MIT Node

One API call turns a CSV into a sortable table, Markdown into styled prose, JSON into an interactive tree.
No accounts, no config, no deploy pipeline — just content in, shareable page out.


curl -X POST https://api.easl.dev/publish \
  -H "Content-Type: application/json" \
  -d '{"content": "# Hello World\nSome **markdown** here.", "contentType": "text/markdown"}'

# → https://warm-dawn.easl.dev

What happens

easl auto-detects your content and renders it with the right interactive viewer:

  • CSV → sortable table with sticky headers and alternating rows
  • Markdown → styled prose with headings, code blocks, and tables
  • JSON → collapsible tree with syntax highlighting
  • Mermaid → rendered diagram (flowcharts, sequence diagrams, etc.)
  • SVG → sanitized, zoomable viewer
  • HTML → served as-is
  • PDF → embedded viewer
  • Images → responsive centered viewer

8 formats. Zero config. All auto-detected.


Quick Start

CLI

curl -fsSL https://easl.dev/install.sh | sh

easl publish report.md
# => https://calm-river.easl.dev

easl publish data.csv --title "Q4 Results" --open
cat logs.json | easl publish --type json
easl publish board-update.md --generate-password   # password-protected; password printed once
easl publish board-update.md --private             # account-private (needs `easl login`)
easl list

MCP Server

Add to your MCP config (Claude Desktop, Cursor, Windsurf, etc.):

{
  "mcpServers": {
    "easl": {
      "command": "npx",
      "args": ["-y", "@easl/mcp"]
    }
  }
}

Then just ask your agent:

"Publish this CSV as a shareable table"

"Turn this markdown into a beautiful page"

Agent Skill

Give your agent built-in knowledge of easl — content types, viewers, best practices:

npx skills add AdirAmsalem/easl

Works with Claude Code, Codex, Cursor, ChatGPT, Gemini CLI, and more.

With curl

curl -X POST https://api.easl.dev/publish \
  -H "Content-Type: application/json" \
  -d '{"content": "Name,Role\nAlice,Engineer\nBob,Designer", "contentType": "text/csv"}'

Supported Formats

Format Extensions Rendered as
CSV .csv Sortable table with sticky headers and alternating rows
Markdown .md Styled prose — headings, code blocks, tables, blockquotes
JSON .json Collapsible tree with syntax highlighting and expand/collapse all
HTML .html Served as-is, no wrapping
SVG .svg Sanitized, zoomable viewer (scripts stripped)
PDF .pdf Embedded iframe viewer
Mermaid .mmd Rendered diagram via Mermaid.js (flowcharts, sequence, etc.)
Images .png .jpg .gif .webp Responsive centered viewer

MCP Server

The MCP server gives AI agents first-class publishing capabilities through the Model Context Protocol.

Available Tools

Tool Description
publish_content Publish raw content (string) → URL to a shareable page. The fastest path.
publish_file Publish a single file from disk with auto-detected rendering.
publish_site Publish a directory as a multi-page site.
create_share_link Mint a signed, time-limited share URL for an account-private site (requires EASL_API_KEY).
list_sites List sites published in the current session.
delete_site Delete a published site by slug.

Environment

Variable Default Description
EASL_API_URL https://api.easl.dev API base URL (override for self-hosted)
EASL_API_KEY Account API key (easl_…); required to publish account-private sites (private: true) and to use create_share_link

Private easls

Pages are public by default. Two independent, composable gates lock one down — set either, both, or neither:

  • Password gatepassword (CLI: --password <pw> or --generate-password). Anonymous-publishable. Visitors enter the password once, then stay unlocked for 30 days via a signed cookie. With --generate-password (API: generatePassword: true) easl mints a strong one, returned once in the publish response.
  • Account gateprivate: true (CLI: --private). Requires easl login (or an API key) and binds the site to your account; only you — or someone holding a signed share link (easl share <slug>) — can view it.
easl publish board-update.md --generate-password
# => https://cool-maze.easl.dev   password: dust-arch-fern-dark-1181

easl login                                               # browser sign-in
easl login --device                                      # headless / remote (no browser callback; approve a code anywhere)
easl publish board-update.md --private                  # account-private
easl publish board-update.md --private --password "pw"   # require BOTH gates

Gated pages are never cached, never indexed, and skip OG-image generation. Toggle visibility or rotate the password later with PATCH /sites/:slug/privacy (owner session/Bearer key or claim token).


REST API

Base URL: https://api.easl.dev

Method Endpoint Description
POST /publish Publish content — single-file shorthand or multi-file array (private + password optional)
GET /sites/:slug Get site metadata
PATCH /sites/:slug/privacy Set the account gate / rotate password (owner session/Bearer key or X-Claim-Token header)
DELETE /sites/:slug Delete a site (owner session/Bearer key or X-Claim-Token header)
POST /feedback Submit feedback programmatically

Full API docs: easl.dev/docs


Architecture

easl runs on Cloudflare's edge network as a single Worker:

  • Hono router handles API requests, landing page, docs, and wildcard subdomain serving
  • R2 stores uploaded files
  • D1 (SQLite) tracks site metadata and version history
  • KV caches rendered HTML shells for fast serving

When a site is requested (e.g. warm-dawn.easl.dev), the Worker detects the file type, generates an HTML shell with the right interactive viewer, and embeds the raw data for client-side hydration.

Monorepo Structure

packages/
  worker/        → Cloudflare Worker (Hono routes, smart rendering, serving)
  cli/           → CLI (npm: @easl/cli)
  mcp-server/    → MCP server (npm: @easl/mcp, stdio transport, 5 tools)

Self-Hosting

Prerequisites: Node.js ≥ 20, a Cloudflare account, and wrangler.

  1. Clone and install

    git clone https://github.com/AdirAmsalem/easl.git
    cd easl
    pnpm install
  2. Create Cloudflare resources

    # Create KV namespace
    wrangler kv namespace create SITES_KV
    
    # Create R2 bucket
    wrangler r2 bucket create easl-content
    
    # Create D1 database
    wrangler d1 create easl-db
  3. Configure — Update packages/worker/wrangler.toml with your resource IDs and domain

  4. Initialize the database

    cd packages/worker
    pnpm db:migrate
  5. Deploy

    pnpm deploy

Development

pnpm install          # Install dependencies
pnpm dev              # Start local dev server (wrangler dev)
pnpm test             # Run tests
pnpm build            # Build all packages

Local dev uses path-based routing instead of subdomains:

  • API endpoints: http://localhost:8787/publish, /sites
  • View sites: http://localhost:8787/s/:slug
  • Docs: http://localhost:8787/docs

Contributing

Contributions are welcome! Whether it's bug fixes, new viewer types, or documentation improvements.

  1. Fork the repo
  2. Create your branch (git checkout -b my-feature)
  3. Make your changes
  4. Run tests (pnpm test)
  5. Open a PR

Looking for a place to start? Check out the good first issues.


License

MIT

About

Instant hosting for AI agents — turn output into pages worth sharing

Topics

Resources

License

Contributing

Stars

23 stars

Watchers

0 watching

Forks

Contributors