Developer portal
The machine surface of this site: what an agent can fetch, what it gets back, and what it has to do to get it. Everything here is a real, public, static document — this is not a product with a sign-up form, and the page does not pretend otherwise.
Quickstart
Three fetches from cold, in the order that wastes the least of an agent's context. No key, no registration, no wait.
curl -sS https://ravicha2.github.io/openapi.jsonThe spec. Enumerate every operation from here; each one carries an operationId and a description, so a function-calling client can build its tool list without reading this page.
curl -sS https://ravicha2.github.io/agents.mdWhen to use this material and when not to. Read before deciding the site is relevant — it is the one page written to lose a reader for the right reason.
curl -sS https://ravicha2.github.io/index.mdThe homepage as markdown. Appending .md to any content route returns that page as text/markdown, so an agent never has to strip HTML to read a case study.
Authentication
One sentence, because this is the whole of it.
Public and read-only. See /auth.md for the walkthrough. There is no key to request, no token to refresh, and no scope to select; a request with no Authorization header is answered in full. The long form, written to the WorkOS auth.md shape, is at /auth.md.
API keys
Stated plainly rather than staged. A fake sign-up form is worse than none: it costs an agent a turn and teaches it to distrust the domain.
No API keys are issued, and none are needed. The origin is a set of static files on GitHub Pages; there is nothing to rate-limit, nothing to meter, and nothing a key could gate. If a keyed surface is ever published, it will be announced in /llms.txt and described here with its issuer and scopes before it goes live.
Sandbox
The whole surface is a sandbox: every operation is a GET of a public document.
There is no production data to damage, so there is no separate test mode and no fixture server pretending to be one. Read anything, as often as you like. If you want an isolated copy, mirror the documents in /openapi.json — they are static and version-pinned by URL.
Rate limits
What is true, rather than what sounds like an API.
None are imposed in software, because the documents are static and cached at the edge. GitHub Pages applies its own fair-use limits to the origin and may answer an unusual burst with an HTML error page. Be considerate and there is nothing else to know.
Errors
The gap here is real and is named rather than papered over.
The 404 documented on each operation is the text/html document GitHub Pages serves for an unmatched path; the request also lands in the SPA, which renders the same message for a browser. RFC 9457 application/problem+json is described by components.schemas.Problem but is not served, and cannot be on static hosting: the origin cannot set a response content type or vary a body by Accept. ADR 0004 records the decision to accept this and state it.
The application/problem+json envelope is described in the spec as components.schemas.Problem and is not served: this origin cannot set a response content type or vary a body by Accept. That is a decision rather than an oversight — it is recorded in docs/adr/0004-accept-html-404s-on-static-hosting.md.
Endpoints (15)
Every operation the spec declares. The table is generated from the same list the spec is, so the two cannot drift.
| Path | operationId | Returns | Content type |
|---|---|---|---|
| /openapi.json | getOpenApiDocument | This document, as JSON. | application/json |
| /.well-known/mcp/server-card.json | getMcpServerCard | A Server Card. | application/json |
| /.well-known/agent-skills/index.json | getAgentSkillsIndex | The skills index. | application/json |
| /.well-known/agent-card.json | getAgentCard | The agent card. | application/json |
| /.well-known/api-catalog | getApiCatalog | A linkset with one item per service description. | application/octet-stream |
| /.well-known/oauth-protected-resource | getProtectedResourceMetadata | Protected resource metadata. | application/octet-stream |
| /.well-known/ard.json | getArdCatalog | The ARD catalog. | application/json |
| /llms.txt | getLlmsTxt | A plain-text markdown index. | text/plain |
| /llms-full.txt | getLlmsFullTxt | A plain-text markdown dossier. | text/plain |
| /agents.md | getAgentsMd | A markdown guide. | text/markdown |
| /auth.md | getAuthMd | A markdown walkthrough. | text/markdown |
| /index.md | getMarkdownHome | A markdown rendering of the homepage. | text/markdown |
| /.well-known/agent-skills/portfolio/SKILL.md | getPortfolioSkill | A markdown skill document. | text/markdown |
| /sitemap.xml | getSitemap | A sitemap. | application/xml |
| /cv.pdf | getCurriculumVitae | A PDF. | application/pdf |
MCP server
A first-party Model Context Protocol server is published with the lit-review-council project.
Its Server Card — the transport, with no tool list, because agents read tools from the server itself — is at /.well-known/mcp/server-card.json, and the bare namespace path /.well-known/mcp redirects to it. The Python distribution that carries it is lit-review-council on PyPI, and the card names that package, so an agent can go from discovery to installation without a second lookup.
In-page tools
The page registers three read-only tools through document.modelContext. They are real, and they are browser-mediated: a crawler cannot call one, so each names the static document that answers it instead.
The page registers search-projects, get-project, and describe-site when it loads, through the browser's document.modelContext. They run in a visitor's browser, so they need a browser that exposes document.modelContext; registering a tool is not a claim that it is callable remotely, and no HTTP client can invoke one. Every answer they give already exists as a static document:
search-projectsis answered by /llms.txt and /projects.md.get-projectis answered by the markdown twin of a project page, at its path with.mdappended.describe-siteis answered by /llms.txt, /openapi.json, and /sitemap.xml.
The decision is recorded in docs/adr/0005-webmcp-is-browser-mediated.md.
Reaching a person
There is no support desk behind a static site. There is an inbox, and it is read.
Ravicha Suksawasdi Na Ayuthaya maintains these documents. Anything wrong in them — a stale path, a shape that does not match — is worth an email to palm.ravicha@outlook.com.
Get in touch
Master of IT at UNSW Sydney (WAM 83 / Distinction, graduating Dec 2026) · Open to full-time Applied AI & Backend Systems roles.