MCP server for lightpaper.org — API-first publishing platform. Enables publishing and managing documents (articles, essays, papers, books) with identity verification, gravity scoring, and audiobook narration.
The server has 22 tools with complete input schemas and descriptions visible in server.py and mcp/server.py. Most tools follow verb_noun naming conventions (publish_lightpaper, get_lightpaper, delete_lightpaper, search_lightpapers, verify_linkedin, etc.). Descriptions are reasonably detailed (avg ~150-200 chars) and explain what each tool does. However, several critical gaps reduce overall quality: (1) No output schemas are documented, tool responses are described textually in descriptions but not formally specified, making it difficult for LLMs to parse complex returns like search results with pagination or gravity info; (2) Security issue, api_key is exposed as a tool parameter on 12+ tools (publish_lightpaper, update_lightpaper, delete_lightpaper, get_lightpaper with optional api_key, list_my_lightpapers, list_my_books, delete_book, get_gravity_info, verify_linkedin, verify_credentials, verify_domain, verify_orcid, narrate_book, export_print), violating pattern:secret-injection. While there is an environment variable LIGHTPAPER_API_KEY, passing it as a parameter risks logging credentials; (3) No error handling guidance, descriptions do not say what errors are retryable, what the LLM should do on 404 vs 401 vs 500; (4) Parameter descriptions lack clarity on mutual exclusivity (e.g., id vs slug in get_lightpaper, start vs check patterns in verify_* tools); (5) No confirmation pattern for destructive operations (delete_lightpaper, delete_book) despite high-risk nature; (6) Pagination not well-documented on search_lightpapers, limit and sort are present but no mention of total count or next_cursor; (7) Some enum values not explicitly constrained in schema (e.g., credential_type, action params in verify_* tools should be strongly typed).
Add a new chapter to an existing published book. Chapter becomes a new document.
Start email-based sign-in or login flow. Ask user for name, email, and handle. Returns session_id to pass to auth_verify.
Start browser-based LinkedIn OAuth login. Returns oauth_url for user to visit. Poll with auth_linkedin_poll.
Poll LinkedIn OAuth login status. Call every 3-5 seconds. Returns api_key when complete.
Verify the 6-digit code sent to email. Returns api_key if successful. Check is_new_account to determine if user is new or returning.
Delete a published book (all chapters).
api_key exposed as tool parameter on 12+ tools. Violates pattern:secret-injection, credentials in parameters are logged and can leak into traces/prompts. Should use environment variable LIGHTPAPER_API_KEY exclusively.
No output schemas documented. Tool descriptions mention return values (e.g., 'Returns URL, quality score, and suggested improvements' for publish_lightpaper; 'Returns all chapters with URLs and quality scores' for get_book) but formal response schemas are not provided. LLMs cannot parse complex nested responses reliably without explicit output schema documentation.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 65 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 28 | - | v1 |
Delete a published document. Requires confirmation.
Export published book as print-ready PDF for Amazon KDP / IngramSpark. action='preview' (free, first 10 pages), action='interior' (full trade paperback), action='cover' (full wrap cover at 300 DPI), action='certificate' (free, Certificate of Publication).
Fetch a published book by ID or slug. Returns all chapters with URLs and quality scores.
Get the authenticated user's current author gravity level, badges, and context-sensitive instructions for reaching the next level.
Fetch a published document by ID or slug. Returns full content, metadata, quality score, and improvement suggestions.
List all books published by the authenticated user.
List all documents published by the authenticated user. Returns IDs, titles, formats, and URLs.
Create or manage audiobook narration for a published book. action='voices' lists narrators, action='estimate' shows pricing, action='create' creates narration, action='status' checks progress.
Publish a multi-chapter book on lightpaper.org. Each chapter is a separate document with prev/next navigation.
Publish a single document (article, essay, or paper) on lightpaper.org. Returns URL, quality score, and suggested improvements.
Search for published documents. Query is optional (can browse without search). Filter by format, author handle, tags, or sort by recent/quality.
Update a published document. Changes create a new version. Can update content, format, authors, tags, description, and license.
Verify author credentials (degrees, certifications, employment). Pass evidence (URLs, screenshots, or text descriptions) to investigate and confirm.
Verify domain ownership via DNS TXT record. Returns DNS record to add, then poll action='check' to confirm.
Start or check LinkedIn identity verification. action='start' returns oauth_url. action='check' polls for completion.
Verify ORCID identifier (no browser needed). Pass ORCID iD, returns verification result.
Destructive operations (delete_lightpaper, delete_book) lack confirmation/dry-run mechanism. Descriptions mention 'requires confirmation' but no parameter or multi-step process is defined. No error recovery guidance for accidental deletes.
No error handling or recovery guidance in tool descriptions. What happens if auth_verify receives wrong code? If publish_lightpaper fails on content validation? If delete_lightpaper attempts to delete a non-existent doc? Descriptions do not indicate which errors are retryable, user-fixable, or fatal.
Conditional parameter requirements not properly documented. In verify_linkedin, session_id is described as 'required for action=check' but schema does not mark it conditionally. In narrate_book, voice_id required only for action='create'; page_count required only for action='cover'. LLMs may omit required params when conditions are only in text.
Mutual exclusivity and alternate parameter formats not clearly documented. get_lightpaper accepts 'id' (doc_*) or 'slug' but does not state which is preferred or whether both can be passed. Similar issue in get_book (book_* vs slug).
Pagination not well-documented on search_lightpapers. limit and sort present, but no mention of total_count, next_cursor, or page metadata. LLM cannot determine if there are more results or how to fetch next page.
Content validation constraints mentioned in descriptions but not formally enforced in schema. publish_lightpaper requires '300+ words with at least one heading'; add_chapter requires '100+ words, at least one heading'. No regex pattern or min/max length in schema; LLMs may not enforce or may misunderstand.