Skip to content

feat(server): serve bundled API docs at /docs - #3347

Open
anditherobot wants to merge 9 commits into
lemonade-sdk:mainfrom
anditherobot:feat/1700-serve-api-docs
Open

feat(server): serve bundled API docs at /docs#3347
anditherobot wants to merge 9 commits into
lemonade-sdk:mainfrom
anditherobot:feat/1700-serve-api-docs

Conversation

@anditherobot

@anditherobot anditherobot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Serves the server's own API documentation three ways. Machine clients fetch an
index of the available pages and then each page as markdown, agents get the same
through an MCP tool, and browsers get the human-readable rendered site.

Route Returns
GET /v1/docs the list of documentation pages this server has
GET /v1/docs/api/lemonade the Lemonade API reference, as markdown
POST /mcp -> lemonade_docs the same list, or one page, for MCP clients
GET /docs/ the documentation website, rendered

The three API routes are always present. Additionally, the website can be
enabled with the BUILD_DOCS_SITE flag. The Windows installers set it, so an
MSI install includes the site; building from source, it is optional.

Fixes #1700

Scope

  • Documentation API (6b7b4f9) — index plus one page per URL, on all four
    prefixes; all 7 files in docs/api instead of 3, read from the folder rather
    than a list in the code.
  • MCP tool (b8f8ad5) — reuses the HTTP endpoint's code.
  • Rendered website (69ef6b2) — built with Zensical from the same source as
    the published site; the WiX generator now takes an id prefix so it can harvest
    more than one folder.
  • Installer builds (d506026) — both Windows jobs install Zensical and turn
    the flag on.

Enabling the site for the Debian package needs a separate change in
contrib/debian/rules, raised in the comments.

  • This PR addresses one clear issue or change.
  • I reviewed the full diff myself before submitting.
  • I removed unrelated local changes.
  • I kept refactoring separate unless it is required for this change.

Testing

  • Code builds without errors locally.
  • I tested this change locally.
  • I described the testing performed below.

Testing details:

All 63 cpp-ci tests pass, including the rewritten DocsEndpointTest.

Verified against a running server: the index and every page it lists, on all four
prefixes; unknown pages and path traversal rejected; the MCP tool over real
JSON-RPC; and /docs/ serving the site with the existing routes unaffected.

Built and extracted lemonade-server-minimal.msi to confirm the 7 markdown files
and 129 site files install, and confirmed the WiX generator still produces
identical output for the web app.

Documentation

  • Documentation is affected and has been updated.

docs/api/lemonade.md documents both endpoints, docs/api/mcp.md documents the
new tool, docs/api/README.md and AGENTS.md were updated to match.

Breaking Changes

  • This PR introduces breaking changes.

/v1/docs changes from concatenated markdown to a JSON index. The endpoint is
unreleased, so no shipped client depends on it.

AI-assisted contribution

  • I used AI tools for this PR.
  • I verified that I understand the changes.
  • I checked for hallucinated APIs, unrelated changes, and incorrect assumptions.

@github-actions github-actions Bot added area::api HTTP REST API surface and route handlers enhancement New feature or request labels Aug 25, 2026
@ckuethe

ckuethe commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Nice. It works for me, and degrades gracefully when the documentation path is inaccessible.

@jeremyfowers

Copy link
Copy Markdown
Member

Awesome! I would like to review this before it merges. Thanks for your patience :)

@anditherobot
anditherobot force-pushed the feat/1700-serve-api-docs branch from ca535f0 to a1335bc Compare August 26, 2026 21:10

@jeremyfowers jeremyfowers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, at the risk of scope-creeping you very badly...

How would you feel about changing this PR so that it builds the entire docs site with Zensical and serves that over the /docs endpoint, just like https://lemonade-server.ai/docs/ does? That would be much more comprehensive. It would also mean, later on, we could load it in an iframe in the GUI and display the complete up-to-date project documentation for the user's current install.

Alternatively, if you don't want to take that on, this PR still needs to be durable in the likely event people will want more in /docs than just api/lemonade.md. I think the simplest way to achieve that would be to make the current endpoint /docs/api/lemonade, and then it makes sense that it serves exactly that doc, at the same relative path that https://lemonade-server.ai/docs/api/lemonade/

Otherwise if /v1/docs serves the document /docs/api/lemonade.md it will be a breaking change when we inevitably decide to add more documentation to the endpoint.

Thoughts?

@ckuethe

ckuethe commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

what I would find most useful is to have /api/docs serve up a listing of markdown docs available. it can be html, json, or markdown - just something easy to parse. that tells the consumer which documentation pages the server knows about, eg. lemonade.md, openai.md, ollama.md,... . I can point any reasonably competent agent+model at it and it'll do the rest.

I don't think this is a breaking change because you first query /api/docs to see what's available on this server, and then you can fetch /api/docs/{doc}

I use this "here's the top of the docs, you figure it out" pattern a lot for making python api bindings.

you can serve a rendered copy of the docs from /docs for human consumption.

Replaces the concatenated response with a JSON index at /v1/docs and one
page per URL at /v1/docs/api/lemonade, so pages can be added later without
breaking clients. Widens the bundle to all of docs/api.
Lists the reference pages the server ships, or returns one as markdown when
`page` is given. Reuses the HTTP endpoint's lookup so the path confinement
is shared rather than written twice.
…ocs/

Adds BUILD_DOCS_SITE, off by default, which builds the existing Zensical
site into resources/docs-site and serves it at /docs/. Off by default
because zensical installs with pip; the Debian build uses only the archive.
Installs zensical and configures with BUILD_DOCS_SITE=ON in both Windows
installer jobs, so the shipped MSIs carry the docs site while source builds
that cannot install from pip are unaffected.
@anditherobot

anditherobot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Reading your comments, there are two audiences consuming that functionality, so I
increased the scope to cover both: Details are in the PR description.

@jeremyfowers, you're right, it was a much needed change, so I went ahead and
implemented it. One action item , on the GUI: should I open a separate issue under
GUI 3 for a docs panel? Something like:

GUI3: docs panel backed by the local docs endpoint
Add a Docs panel that fetches the index from GET /v1/docs on the running
server and renders the markdown pages in-app.

@ckuethe, this is the discovery-first shape you described. GET /v1/docs returns
JSON listing every page with its URL, and GET /v1/docs/api/lemonade returns raw
markdown. All 7 files in docs/api are included, so openai and ollama are
reachable too. It sits on the versioned prefixes rather than bare /api/docs,
which belongs to Ollama compatibility. A lemonade_docs MCP tool does the same
two operations. Does that cover what you had in mind?

@superm1, enabling the site for the Debian package needs a change in
contrib/debian/rules, and it pulls in zensical, which is not yet in the
archive. Please take a look whenever you are able.

Thank you all.

@ckuethe

ckuethe commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Lovely. Versioned doc API is fine, I'm just happy that there'll be an endpoint I can point my agent at, allowing it to figure out what endpoints are available and how to use them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area::api HTTP REST API surface and route handlers enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API documentation included with lemonade server

3 participants