A ready-to-use template for building OAuth-protected MCP servers with session support for user-specific data
This Ktor OAuth MCP server demonstrates moderate definition quality with some solid patterns but notable gaps. All 5 tools have descriptions and basic schemas, which is better than many community servers. However, descriptions are terse (10-50 chars), parameter validation is minimal, and output schemas are completely undocumented. The server properly uses enums for constrained inputs (my_contact_info format, update_contact field) and declares WRITE vs READ_ONLY risk classifications, showing awareness of tool semantics. The OAuth provision flow and session-based authentication are well-architected, but tool definitions themselves lack the depth needed for confident LLM selection and reliable error recovery.
Returns a personalized greeting using your stored name
Returns all your stored contact information
Simulates sending a test email to your stored email address
Update a field in your contact information
Returns your mom's name (from encrypted claim)
All tool descriptions are under 50 characters, insufficient context for LLM selection. Best practice is 50-200 chars. E.g., 'Returns a personalized greeting using your stored name' (54 chars) lacks WHEN to call vs similar tools and doesn't describe failure modes.
Output schemas are completely undocumented. Code shows tools call call.respondText() with free-form strings, but LLMs have no schema to parse responses. Pattern requires documented return types for all tools.
No error guidance. send_test_email throws 'Error: No email address stored' if session.email is null, but provides no recovery path. Pattern requires error responses to guide next steps: 'Email not found. Call update_contact to set email first.'
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 64 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 50 | - | v1 |
Parameter descriptions missing from schema for send_test_email. 'subject' is declared but no description explains format, length limits, or whether it's optional. Pattern requires every parameter to have a description.
Tool 'your_moms_name' is poorly named for agent discovery. Name does not start with an action verb (get_, list_, retrieve_). Should be 'get_moms_name' or 'retrieve_moms_name' so LLM can infer intent from the name alone.
No idempotence documentation. update_contact and send_test_email are WRITE operations but lack guidance on whether they are safe to retry. Pattern requires clear marking of idempotent vs non-idempotent operations so agents can handle transient failures correctly.