OpenAPI 3.1

akaushik.org portfolio API

Read-only access to portfolio content through Markdown, JSON, and MCP.

The portfolio exposes its content for agent consumption via five surfaces: (1) the full-corpus Markdown at /llms-full.txt, (2) per-page Markdown alternates at /work/<slug>.md and /writing/<slug>.md, (3) JSON listings at /api/writing and /api/case-studies, (4) HTTP content negotiation on /work/<slug> and /writing/<slug> via `Accept: text/markdown`, and (5) a stateless read-only MCP endpoint at /api/mcp.

MCP tools

https://akaushik.org/api/mcp is a stateless Streamable HTTP endpoint whose current revision is 2025-11-25. It also supports 2025-11-25, 2025-06-18, 2025-03-26 for this bounded tool subset; initialize echoes a supported requested revision and otherwise negotiates the current one. A later request without MCP-Protocol-Version is handled as 2025-03-26, whose batches are capped at 32 calls.

Every POST must use Content-Type: application/json and an Accept header listing both application/json and text/event-stream; request bodies are capped at 1 MiB before parsing. Responses with bodies use JSON. Every no-id call is dispatched as a notification without a response: a single notification or all-notification batch receives 202. This server issues no MCP-Session-Id; GET, HEAD, PUT, PATCH, DELETE, and other unsupported methods return 405, and OPTIONS returns 204.

JSON-RPC errors are -32700 parse error, -32600 invalid request, -32601 method not found, -32602 invalid params, and -32603 internal error. Numeric request IDs must be integers. The /.well-known/mcp.json document is site/scanner-specific discovery metadata, not an MCP protocol-standard server card.

lookup_case_study

Return one published portfolio case study as structured data and Markdown.

  • slug (required) · string
  • slug · string
  • title · string
  • dek · string
  • role · string
  • year · string
  • stack · array
  • url · string
  • markdown · string

Annotations: read-only, idempotent, non-destructive, closed-world.

get_availability

Return current public project availability and contact details.

No arguments.

  • status · string
  • capacity · string
  • contactUrl · string
  • email · string

Annotations: read-only, idempotent, non-destructive, closed-world.

Paths

/llms.txt

GET · Short-form site digest (llmstxt.org format)

  • 200 · Markdown digest (text/markdown)

/llms-full.txt

GET · Full portfolio corpus, concatenated

  • 200 · Markdown corpus (text/markdown)

/api/writing

GET · List writing posts

  • 200 · Newest-first list of writing posts (application/json)

/api/case-studies

GET · List case studies

  • 200 · Curated order list of case studies (application/json)

/api/mcp

POST · Call the stateless MCP server over Streamable HTTP

Accepts one JSON-RPC 2.0 request or notification for 2025-11-25 and 2025-06-18. The 2025-03-26 compatibility path also accepts batches of 1–32 calls. Every POST uses Content-Type application/json, is capped at 1 MiB before parsing, and negotiates the transport by listing both application/json and text/event-stream in Accept; responses use application/json when a body is present. Initialize echoes a supported requested revision and otherwise negotiates 2025-11-25. Later requests without MCP-Protocol-Version are handled as 2025-03-26. The server is stateless and never issues MCP-Session-Id.

  • MCP-Protocol-Version · header · string · Required by clients after initialization. Explicit values must be supported; when omitted, this stateless server applies the 2025-03-26 compatibility fallback.
  • Origin · header · string · May be omitted by server clients. When present, it must be the canonical origin.

Required · application/json

  • 200 · JSON-RPC response for initialize, ping, tools/list, or tools/call (application/json)
  • 202 · Single notification or notification-only compatibility batch accepted; no response body
  • 400 · Malformed JSON (-32700), invalid JSON-RPC envelope (-32600), or unsupported explicit protocol version (-32602) (application/json)
  • 403 · Origin is present and does not match the canonical origin (application/json)
  • 406 · Accept does not list both application/json and text/event-stream (-32600) (application/json)
  • 413 · Request body exceeds the 1 MiB transport limit (application/json)
  • 415 · Content-Type is not application/json (application/json)

GET · Streaming GET is not supported

This stateless server does not expose a server-initiated SSE stream, so GET always returns HTTP 405.

  • 400 · Unsupported explicit MCP protocol version (application/json)
  • 403 · Origin is present and does not match the canonical origin (application/json)
  • 405 · Method not allowed (application/json)

DELETE · Session deletion is not supported

The MCP server is stateless and never issues session identifiers.

  • 400 · Unsupported explicit MCP protocol version (application/json)
  • 403 · Origin is present and does not match the canonical origin (application/json)
  • 405 · Method not allowed (application/json)

OPTIONS · Describe same-origin HTTP capabilities

  • 204 · Capability response with no body
  • 400 · Unsupported explicit MCP protocol version (application/json)
  • 403 · Origin is present and does not match the canonical origin (application/json)

/writing/{slug}.md

GET · Writing post as Markdown

Pattern B (suffix). Equivalent to GET /writing/{slug} with Accept: text/markdown (Pattern A, RFC 7231 content negotiation).

  • slug · path · string (required)
  • 200 · Post Markdown (text/markdown)
  • 404 · Slug not found

/work/{slug}.md

GET · Case study as Markdown

Pattern B (suffix). Equivalent to GET /work/{slug} with Accept: text/markdown (Pattern A, RFC 7231 content negotiation).

  • slug · path · string (required)
  • 200 · Case study Markdown (text/markdown)
  • 404 · Slug not found

/

GET · Home page

HTML by default. With Accept: text/markdown the server rewrites to /llms.txt (short-form digest).

  • 200 · HTML home page or Markdown digest (content-negotiated) (text/html, text/markdown)

Schemas

WritingPost

  • slug (required) · string
  • title (required) · string
  • dek (required) · string
  • date (required) · string · format: date
  • readingTime · string
  • url (required) · string · format: uri
  • markdown (required) · string · format: uri

WritingList

  • count (required) · integer
  • posts (required) · array

CaseStudy

  • slug (required) · string
  • title (required) · string
  • dek (required) · string
  • index · string
  • tag · string
  • year (required) · string
  • role (required) · string
  • stack (required) · array
  • evidenceOf · string
  • url (required) · string · format: uri
  • markdown (required) · string · format: uri

CaseStudyList

  • count (required) · integer
  • caseStudies (required) · array

McpJsonRpcRequest

  • jsonrpc (required) · string
  • id · object
  • method (required) · string
  • params · object

McpJsonRpcResponse

    McpJsonRpcSuccessResponse

    • jsonrpc (required) · string
    • id (required) · object
    • result (required) · object

    McpJsonRpcErrorResponse

    • jsonrpc (required) · string
    • id (required) · object
    • error (required) · object

    McpToolResult

    • content (required) · array
    • structuredContent · object
    • isError (required) · boolean