Six tools with complete JSON schemas and descriptions. Naming follows verb_noun convention (publish_*, list_*, delete_*, create_*). Descriptions are detailed (150-300 chars) and explain prerequisites (EASL_API_KEY, password gates). However, parameter descriptions are verbose and repetitive across tools, the same password/private/generatePassword logic is copied verbatim into all three publish_* tools, violating DRY. Output schemas are not documented, callers don't know what fields to expect from responses (e.g., does publish_content return {url, password, slug}?). Error handling is absent, no guidance on what happens if EASL_API_KEY is missing, file not found, or quota exceeded. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk levels (WRITE, DESTRUCTIVE).
Create a signed, expiring share link for an account-private easl. Returns an unguessable URL that lets someone without an account view the page until it expires. Owner-only — REQUIRES the server to be logged in (EASL_API_KEY set) and to own the site. If the site is ALSO password-protected, the recipient still needs the password.
Delete a site by slug. Uses the claim token from the session.
List sites published in this session.
Publish raw content (Markdown, CSV, HTML, JSON, SVG, Mermaid) as a shareable page. The fastest way — content goes in, URL comes out. Max 256KB. Pass a `password` (or `generatePassword: true` to have easl mint one, returned once) for a password-protected page (anonymous OK), `private: true` for an account-private page (requires the server to be logged in via EASL_API_KEY), or both to stack the two gates.
Publish a single file from disk — returns a URL to a shareable page. easl auto-detects the file type and renders it with the best viewer. Pass a `password` (or `generatePassword: true` to have easl mint one, returned once) for a password-protected page (anonymous OK), `private: true` for an account-private page (requires the server to be logged in via EASL_API_KEY), or both to stack the two gates.
Output schemas not documented. Callers cannot infer response structure (e.g., does publish_content return {url, password, slug, expiresAt}?). LLMs must guess what fields to extract for downstream tool calls.
Parameter descriptions are repetitive. The password/private/generatePassword logic is copied verbatim into publish_content, publish_file, and publish_site (3× ~400 chars each). Violates DRY and wastes tokens. Consolidate into a shared description or reference.
No error handling guidance. What happens if EASL_API_KEY is missing when private=true? If file path is invalid? If quota exceeded? Responses must tell LLMs what to do next (retry, ask user, abort).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Publish a directory of files as a site. If the directory has an index.html, it's served as-is. Otherwise, easl auto-generates navigation. Pass a `password` (or `generatePassword: true` to have easl mint one, returned once) for a password-protected site (anonymous OK), `private: true` for an account-private site (requires the server to be logged in via EASL_API_KEY), or both to stack the two gates.
No tool annotations. delete_site is destructive and create_share_link is idempotent, but no readOnlyHint/destructiveHint/idempotentHint metadata. Agents cannot infer safety properties.
list_sites description is minimal ('List sites published in this session'). Does not explain what fields are returned, when to call it, or how to use results for downstream operations (e.g., delete_site requires slug, does list_sites return it?).