This is driven by instructions in the Claude Code system prompt:
> When the user directly asks about Claude Code (eg. "can Claude Code do...", "does Claude Code have..."), or asks in second person (eg. "are you able...", "can you do..."), or asks how to use a specific Claude Code feature (eg. implement a hook, or write a slash command), use the WebFetch tool to gather information to answer the question from Claude Code docs. The list of available docs is available at https://docs.claude.com/en/docs/claude-code/claude_code_docs....
The article seems a few months too late. Claude (and others) are already doing this: i've been instructing claude code to generate code following certain best practices provided through URLs or asking it to compare certain approaches from different URLs. Claude Skill uses file "URLs" to provide progressive disclosure: only include detailed texts into the context if needed. This helps reduce context size, and improves cachability.
Heh, the problem with having a half drafted post on your machine for a few weeks is the industry moves fast!
I had the post pretty much done, went on vacation for a week, and Claude Skills came out in the interim.
That being said Skills are indeed an implementation of the patterns possible with linking, but they are narrower in scope than what's possible even with MCP Resources if they were properly made available to agents (e.g. dynamic construction of context based on environment and/or fetching from remote sources).
The problem with MCP resources is someone needs to stand up a server. That’s enough overhead and infrastructure that it slows down creating these kinds of resources and linking. Do any of the popular forge sites have like a GitHub pages but it’s MCP kind of capability? I think that would lower the hurdle for standing up such tooling so it would be much more appealing to actually do.
Codex run locally doesn't have access to any "web search" tool, but that doesn't stop it from trying to browse the web via cURL from time to time. Place hyperlinks in the documents in the repository and it'll try to reach them best it can. It doesn't seem overly eager doing so though, and only does that when absolutely needed and it can't find the information elsewhere. This has been my experience with gpt-5-high at least.
Probably a security feature. If it can access the internet, it can send your private data to the internet. Of course, if you allow it to run arbitrary commands it can do the same.
That article appears to be very confused about how skills work.
It seems to think they are a vendor lockin play by Anthropic, running as an opaque black box.
To rebut their four complaints:
1. "Migrating away from Anthropic in the future wouldn't just mean swapping an API client; it would mean manually reconstructing your entire Skills system elsewhere." - that's just not true. Any LLM tool that can access a filesystem can use your skills, you just need to tell it to do so! The author advocates for creating your own hierarchy of READMEs, but that's identical to how skills work already.
2. "There's no record of the selection process, making the system inherently un-trustworthy." - you can see exactly when a skill was selected by looking in the tool logs for a Read(path/to/SKILL.md) call.
3. "This documentation is no longer readily accessible to humans or other AI agents outside the Claude API." - it's markdown files on disk! Hard to imagine how it could be more accessible to humans and other AI agents.
4. "You cannot optimize the prompt that selects Skills. You are entirely at the mercy of Anthropic's hidden, proprietary logic." - skills are selected by promoting driven by the system prompt. Your CLAUDE.md file is injected into that same system prompt. You can influence that as much as you like.
The closing section of that article revels where that author got confused They said: "Theoretically, we're losing potentially "free" server-side skill selection that Anthropic provides."
Skills are selected by Claude Code running on the client. They seem to think the it's a model feature that's proprietary to Anthropic - it's not, it's just another simple prompting hack.
That's why I like skills! They're a pattern that works with any AI agent already. Anthropic merely gave a name to the exact same pattern that this author calls "Agent-Agnostic Documentation" and advocates for instead.
This isn't an accurate take either. You can load client skills, sure, but the whole selling point from Anthropic is that skills are like memory, managed at the API layer "transparently" and that those skills are cross project. If you forced Claude to only use skills from the current project to try and be transparent, it would still be a black box that makes it harder to debug failures, and it'd still be agent and vendor specific rather than more human friendly and vendor agnostic.
Skills are just lazy loaded prompts. The system prompt will include the summary of every skill, and if the LLM decides it want to use a specific skill the details of that skill will be added to the system prompt. It's just markdown documents all the way down.
I'm talking about skills as they are used in Claude Code running on my laptop. Are you talking about skills as they are used by the https://claude.ai consumer app?
Spot on, this is a solid abstraction to build upon. I always felt MCP was a misstep in comparison to OpenAI’s focus on OpenAPI specs. HATEOAS is the principle that has become more useful as agents drive applications.
I just discovered that I can paste a link into a Claude prompt and ask it to follow read the page so we can talk about it. I no longer have to copy the text of the page and paste it in. Claude uses the web_fetch command. So we're heading in the direction this article discusses.
It refused to read this complaint about Grok because of the NSFW topic
"The irony is they trained their model on so much porn even barely NSFW prompts get flagged because Grok the Goon Commander thinks a simple fully-clothed lapdance requires a visible massive dong being thrusted up her piehole."
Is one of the reasons OpenAI made a browser (Atlas) and Perplexity made Comet and Anthropic made a Chrome extension to make it impossible for the site to tell whether a person or the person's AI assistant is making the request?
I wonder if append-only will continue to be important. As agents get more powers, their actions will likely be the bottleneck, not the LLM itself. And at n*2, recomputing a whole new context might not take much longer than just computing the delta, or even save time if the new context is shorter.
What you're describing is basically very stripped down versions of pre-SPA web pages.
We don't need MCPs for this, just make a tool that uses Trafilatura to read web pages into markdown and create oldschool server side web UIs, and let the agents curl them.
I wonder if I can instruct LLMs to use my MCP whenever they need to access anything online. So they can bypass AI blocks when I tell them to read some docs online.
This can already be done with Claude Code or most agentic tools. There will be restrictions for online platforms as LLMs are very vulnerable to prompt attacks.
HATEOAS always seemed a bit like a solution in search of a problem to me. It was a nice idea for more convenient "manual exploration" of APIs if you're a human developer and all you have is curl - but I never understood for what kind of "production" scenario they were designing their constraints. The kind of automated client that could make actual use of the metadata always seemed more of a fantasy.
...until now. It seems they finally found their problem.
> Purists have long claimed that a “truly” RESTful API should be fully self-describing, such that a client can explore and interact with it knowing nothing but an entrypoint in advance, with hyperlinks providing all necessary context to discover and consume additional endpoints.
> This never worked in practice. Building hypertext APIs was too cumbersome and to actually consume APIs a human needed to understand the API structure in a useful manner anyway.
Every time I read one of these comments I feel like DiCaprio's character in Inception going "but we did grow old together." HATEOAS worked phenomenally. Every time you go to a webpage with buttons and links in HTML that describe what the webpage is capable of (its API, if you will), you are doing HATEOAS [0]. That this interface can be consumed by both a user (via the browser) and a web scraper (via some other program) is the foundation of modern web infrastructure.
It's a little ironic that the explosion of information made possible by HATEOAS happened while the term it self largely got misunderstood, but such is life. Much like reclaiming the proper usage of its close cousin, "REST," using HATEOAS correctly is helpful for properly identifying what made the world's largest hypermedia system successful—useful if you endeavor to design a new one [1].
I think you're misunderstanding the purpose of hateoas.
If we jump down to the bolts and nuts, let's say on a json API, it's about including extra attributes/fields in your json response that contain links and information of how to continue. These attributes have to be blended with your other real attributes.
For example if you just created a resource with a POST endpoint, you can include a link to GET the freshly created resource ("_fetch"), a link to delete it ("_delete"), a link to list all resources of the same collection ("_list"), etc...
Then the client application is supposed to automatically discover the API's functionality. In case of a UI, it's supposed to automatically discover the API's functionality and build a presentation layer on the fly, which the user can see and use. From our example above, the UI codebase would never have a "delete" resource button, it would have a generic button which would be created and placed on the UI based on the _delete field coming back from the API
I agree. The “purist” REST using HATEOAS is the single most successful API architectural style in history by miles. It’s the foundation of the World-Wide Web, which would not have been anywhere near as successful with a different approach.
I worked for a company that was all hateoas. In the formal sense, explicitly structured around the concept, not the sense that html has both data and actions via links, it worked, it was a real product, but it was slow and terrible to develop and debug.
The front end ui was entirely driven, ui and functionality exposed by the data/action payload.
I'm still not sure if it's because of the implementation or because there is something fundemental.
I came away from that thinking that the db structure, the dag and data flow is what's really important for thinking about any problem space and any ui considerations should be not first class.
But I'm not a theorist, I just found a specific real, real formal working implementation in prod to be not great, it's a little hard even now to understand why.
Maybe it just works for purely text interfaces, adding any design or dynamic interaction causes issues.
I think maybe it's that the data itself should be first class, that well typed data should exist and a system that allows any ui and behavior to be attached to that data is more important than an api saying what explicit mutations are allowed.
If I was to explore this, I think folder and files, spreadsheet, dbs, data structures, those are the real things and the tools we use to mutate them are second order and should be treated as such. Any action that can be done on data should be defined elsewhere and not treated as being the same importance, but idk, that's just me thinking outloud.
> I worked for a company that was all hateoas. In the formal sense, explicitly structured around the concept, not the sense that html has both data and actions via links, it worked, it was a real product, but it was slow and terrible to develop and debug.
The web is also a real product, one that's (when not bloated with adtech) capable of being fast and easy to develop on. That other people have tried to do HATEOAS and failed to make it nice is part of why it's so useful to acknowledge as valid the one implementation that has wildly succeeded.
REST, including HATEOAS, was largely retrospective documentation of the architectural underpinning of the WWW by Roy Fielding (who played an important role in web technology from 1993 on, was the co-lead for the HTTP/1.0 spec, the lead for the original HTTP/1.1 spec, and also, IIRC, lead or co-lead on the original URL spec. The things it documented existed before it documented them.
> You aren't saying hypermedia/hyperlinks served by a backend equal hateaos are you?
That’s exactly what it is.
> hateaos is from 2000 isn't it? Long after hyperlinks and the web already existed.
> Over the past six years, the REST architectural style has been used to guide the design and development of the architecture for the modern Web, as presented in Chapter 6. This work was done in conjunction with my authoring of the Internet standards for the Hypertext Transfer Protocol (HTTP) and Uniform Resource Identifiers (URI), the two specifications that define the generic interface used by all component interactions on the Web.
This is straight from the intro of fielding’s doctoral dissertation.
REST / HATEOAS is basically one of the main architects of the web saying “these are the things we did that made the web work so well”. So yes, REST was published after the web already existed, but no that doesn’t mean that the web is not REST / HATEOAS.
Within the last 3 years. They had their own open sourced functional typescript framework that drove the front end.
You could use whatever lightweight rendering you wanted, mostly it was very minimal react but that hardly mattered. One thing that was a positive was how little the ui rendering choice mattered.
I don't really want to say more as it's unique enough to be equivalent to naming the company itself.
Totally agree, the web itself is absolutely HATEOAS, but there was a type of person in the 2000s era who insisted that APIs were not truly RESTful if they weren't also hypermedia APIs, but the only real benefit of those APIs was to enable overly generic API clients that were usually strictly worse than even clumsily tailored custom clients.
The missing piece was having machines that could handle enough ambiguity to "understand" the structure of the API without it needing to be generic to the point of uselessness.
> there was a type of person in the 2000s era who insisted that APIs were not truly RESTful if they weren't also hypermedia APIs
The creator of REST, Roy Fielding, literally said this loud and clear:
> REST APIs must be hypertext-driven
> What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period.
I appreciate the conceptual analogy, but that's not really HATEOAS. HATEOAS would mean your browser/client would be entirely responsible for the presentation layer, in whatever form you desired, whether it's buttons or forms or pages or not even a GUI at all, such as a chat interface.
The Web is not only true HATEOAS, it is in fact the motivating example for HATEOAS. Roy Fielding's paper that introduced the concept is exactly about the web, REST and HATEOAS are the architecture patterns that he introduces primarily to guide the design of HTTP for the WWW.
The concept of a HATEOAS API is also very simple: the API is defined by a communication protocol, 1 endpoint, and a series of well-defined media types. For a website, the protocol is HTTP, that 1 endpoint is /index.html, and the media types are text/html, application/javascript, image/jpeg, application/json and all of the others.
The purpose of this system is to allow the creation of clients and servers completely independently of each other, and to allow the protocols to evolve independently in subsets of clients and servers without losing interoperability. This is perfectly achieved on the web, to an almost incredible degree. There has never been, at least not in the last decades, a big where, say, Firefox can't correctly display pages severed by Microsoft IIS: every browser really works with every web server, and no browser or server dev even feels a great need to explicitly test against the others.
It's a broader definition of HATEOAS. A stricter interpretation with practical, real-world benefits is a RESTful API definition that is fully self-contained that the client can get in a single request from the server and construct the presentation layer in whole with no further information except server responses in the same format. Or, slightly less strictly, a system where the server procedurally generates the presentation layer from the same API definition, rather than requiring separate frontend code for the client.
> HATEOAS would mean your browser/client would be entirely responsible for the presentation layer, in whatever form you desired, whether it's buttons or forms or pages or not even a GUI at all, such as a chat interface.
Browsers can alter a webpage with your chosen CSS, interactively read webpages out loud to you, or, as is the case with all the new AI browsers, provide LLM powered "answers" about a page's contents. These are all recontextualizations made possible by the universal HATEOAS interface of HTML.
Altering the presentation layer is possible precisely because HTML is a semantic API definition: one broad enough to enable self-description across a variety of domains, but specific enough that those applications can still be re-contextualized according to the user's needs and preferences.
Deriving a presentation layer from an API definition has no bearing on whether the client has to be stateful or not. The key difference for 'true' HATEOAS is that the API schema is sufficiently descriptive that the client does not need to request any presentation layer; arguably not even HTML, but definitely not CSS or JavaScript.
Dude, he literally mentions Java Applets as an example (it was popular back then, if it was written today it would have been JavaScript). It's all there. Section 5.1.7.
It's an optional constraint. It's valid for CSS, JavaScript and any kind of media type that is negotiable.
> resource: the intended conceptual target of a hypertext reference
> representation: HTML document, JPEG image
A resource is abstract. You always negotiate it, and receive a representation with a specific type. It's like an interface.
Therefore, `/style.css` is a resource. You can negotiate with clients if that resource is acceptable (using the Accept header).
"Presentation layer" is not even a concept for REST. You're trying to map framework-related ideas to REST, bumping into an impedance mismatch, and not realizing that the issue is in that mismatch, not REST itself.
REST is not responsible for people trying to make anemic APIs. They do it out of some sense of purity, but the demands do not come from HATEOAS. They come from other choices the designer made.
I will concede the thrust of my argument probably does not fully align with Fielding's academic definition, so thank you for pointing me to that and explaining it a bit.
I'm realizing/remembering now that our internal working group's concept of HATEOAS was, apparently, much stricter to the point of being arguably divergent from Fielding's. For us "HATEOAS" became a flag in the ground for defining RESTful(ish) API schemas from which a user interface could be unambiguously derived and presented, in full with 100% functionality, with no HTML/CSS/JS, or at least only completely generic components and none specific to the particular schema.
"Schema" is also foreign to REST. That is also a requirement coming from somewhere else.
You're probably coming from a post-GraphQL generation. They introduced this idea of sharing a schema, and influenced a lot of people. That is not, however, a requirement for REST.
State is the important thing. It's in the name, right? Hypermedia as the engine of application state. Not application schema.
It's much simpler than it seems. I can give a common example of a mistake:
GET /account/12345/balance <- Stateless, good (an ID represents the resource, unambiguous URI for that thing)
GET /my/balance <- Stateful, bad (depends on application knowing who's logged in)
In the second example, the concept of resource is being corrupted. It means something from some users, and something to others, depending on state.
In the first example, the hypermedia drives the state. It's in the link (but it can be on form data, or negotiation, for example, as long as it is stateless).
There is a little bit more to it, and it goes beyond URI design, but that's the gist of it.
It's really simple and not that academical as it seems.
Fielding's work is more a historical formalisation where he derives this notion from first principles. He kind of proves that this is a great style for networking architectures. If you read it, you understand how it can be performant, scalable, fast, etc, by principle. Most of the dissertation is just that.
From what I read on wiki, I'm not sure what to think anymore - it does at least sound inline with the opinion that the current websites are actually HATeOAS.
I guess someone interested would have to read the original work by Roy (who seems to have come up with the term) to find out which opinion is true
I worked on frontend projects and API designs directly related to trying to achieve HATEOAS, in a general, practical sense, for years. Browsing the modern web is not it.
I think you are confusing the browser with the web page. You probably think that the Javascript code executed by your browser is part of the "client" in the REST architecture - which is simply not what we're talking about. When analyzing the WWW, the REST API interface is the interface between the web browser and the web server, i.e. the interface between, say, Safari and Apache. The web browser accesses a single endpoint on the server with no prior knowledge of what that endpoint represents, downloads a file from the server, analyzes the Content-Type, and can show the user what the server intends to show based on that Content-Type. The fact that one of these content types is a language for running server-controlled code doesn't influence this one bit.
The only thing that would have made the web not conform to HATEOAS were if browsers had to have code that's specific to, say, google.com, or maybe to Apache servers. The only example of anything like this on the modern web is the special log in integrations that Microsoft and Google added for their own web properties - that is indeed a break of the HATEOAS paradigm.
I'm not confusing it. I was heavily motivated by business goals to find a general solution for HATEOAS-ifying API definitions. And yes, a web page, implemented in HTML/CSS/JS is a facsimile for it in a certain sense, but it's not self-contained RESTful API definition.
HATEOAS is hypertext as the engine of application state. When a person reads a webpage and follows links, it’s not HATEOAS, because the person is not an application.
HATEOAS and by-the-book REST don’t provide much practical value for writing applications. As the article says, a human has to read the spec, make sense of each endpoint’s semantics, and write code specific to those semantics. At that point you might as well hardcode the relevant URLs (with string templating where appropriate) rather than jumping through hoops and pretending every URL has to be “discovered” on the off chance that some lunatic will change the entire URL structure of your backend but somehow leave all the semantics unchanged.
The exception, as the article says, is if we don’t have to understand the spec and write custom code for each endpoint. Now we truly can have self-describing endpoints, and HATEOAS moves from a purist fantasy to something that actually makes sense.
If you ask Claude Code a question about its own features you can see it using hyperlinks directly, starting with this dedicated markdown index page:
https://docs.claude.com/en/docs/claude-code/claude_code_docs...
This is driven by instructions in the Claude Code system prompt:
> When the user directly asks about Claude Code (eg. "can Claude Code do...", "does Claude Code have..."), or asks in second person (eg. "are you able...", "can you do..."), or asks how to use a specific Claude Code feature (eg. implement a hook, or write a slash command), use the WebFetch tool to gather information to answer the question from Claude Code docs. The list of available docs is available at https://docs.claude.com/en/docs/claude-code/claude_code_docs....
Screenshot and notes here: https://simonwillison.net/2025/Oct/24/claude-code-docs-map/
The article seems a few months too late. Claude (and others) are already doing this: i've been instructing claude code to generate code following certain best practices provided through URLs or asking it to compare certain approaches from different URLs. Claude Skill uses file "URLs" to provide progressive disclosure: only include detailed texts into the context if needed. This helps reduce context size, and improves cachability.
Heh, the problem with having a half drafted post on your machine for a few weeks is the industry moves fast!
I had the post pretty much done, went on vacation for a week, and Claude Skills came out in the interim.
That being said Skills are indeed an implementation of the patterns possible with linking, but they are narrower in scope than what's possible even with MCP Resources if they were properly made available to agents (e.g. dynamic construction of context based on environment and/or fetching from remote sources).
The problem with MCP resources is someone needs to stand up a server. That’s enough overhead and infrastructure that it slows down creating these kinds of resources and linking. Do any of the popular forge sites have like a GitHub pages but it’s MCP kind of capability? I think that would lower the hurdle for standing up such tooling so it would be much more appealing to actually do.
Codex run locally doesn't have access to any "web search" tool, but that doesn't stop it from trying to browse the web via cURL from time to time. Place hyperlinks in the documents in the repository and it'll try to reach them best it can. It doesn't seem overly eager doing so though, and only does that when absolutely needed and it can't find the information elsewhere. This has been my experience with gpt-5-high at least.
You can run "codex --search" and it gains a search tool. I'm not sure why that isn't the default (like it is for Claude Code.)
Probably a security feature. If it can access the internet, it can send your private data to the internet. Of course, if you allow it to run arbitrary commands it can do the same.
You can actually enable search in codex but adding the following to the config file
[tools] web_search = true
It silently fails to work, very often. Anthropomorphizing a bit, it just won't follow the link, and make you think that it did.
Not an exact science yet.
Thanks for that. Comments like yours are why I visit this site and don’t have to read the original article.
Though in this case, I did read the original article.
That's fair, but not everyone reads and tries every single AI thing every day, or they might not get to applying it.
Claude skills is bad mate, it needs to be put to bed. The approach this guy is talking about is better because it's open and explicit. https://sibylline.dev/articles/2025-10-20-claude-skills-cons...
That article appears to be very confused about how skills work.
It seems to think they are a vendor lockin play by Anthropic, running as an opaque black box.
To rebut their four complaints:
1. "Migrating away from Anthropic in the future wouldn't just mean swapping an API client; it would mean manually reconstructing your entire Skills system elsewhere." - that's just not true. Any LLM tool that can access a filesystem can use your skills, you just need to tell it to do so! The author advocates for creating your own hierarchy of READMEs, but that's identical to how skills work already.
2. "There's no record of the selection process, making the system inherently un-trustworthy." - you can see exactly when a skill was selected by looking in the tool logs for a Read(path/to/SKILL.md) call.
3. "This documentation is no longer readily accessible to humans or other AI agents outside the Claude API." - it's markdown files on disk! Hard to imagine how it could be more accessible to humans and other AI agents.
4. "You cannot optimize the prompt that selects Skills. You are entirely at the mercy of Anthropic's hidden, proprietary logic." - skills are selected by promoting driven by the system prompt. Your CLAUDE.md file is injected into that same system prompt. You can influence that as much as you like.
There's no deep, proprietary magic to skills. I frequently use claude-trace to dig around in Claude Code internals: https://simonwillison.net/2025/Jun/2/claude-trace/ - here's an example from last night: https://simonwillison.net/2025/Oct/24/claude-code-docs-map/
The closing section of that article revels where that author got confused They said: "Theoretically, we're losing potentially "free" server-side skill selection that Anthropic provides."
Skills are selected by Claude Code running on the client. They seem to think the it's a model feature that's proprietary to Anthropic - it's not, it's just another simple prompting hack.
That's why I like skills! They're a pattern that works with any AI agent already. Anthropic merely gave a name to the exact same pattern that this author calls "Agent-Agnostic Documentation" and advocates for instead.
This isn't an accurate take either. You can load client skills, sure, but the whole selling point from Anthropic is that skills are like memory, managed at the API layer "transparently" and that those skills are cross project. If you forced Claude to only use skills from the current project to try and be transparent, it would still be a black box that makes it harder to debug failures, and it'd still be agent and vendor specific rather than more human friendly and vendor agnostic.
Skills are just lazy loaded prompts. The system prompt will include the summary of every skill, and if the LLM decides it want to use a specific skill the details of that skill will be added to the system prompt. It's just markdown documents all the way down.
What do you mean by "managed at the API layer"?
I'm talking about skills as they are used in Claude Code running on my laptop. Are you talking about skills as they are used by the https://claude.ai consumer app?
Spot on, this is a solid abstraction to build upon. I always felt MCP was a misstep in comparison to OpenAI’s focus on OpenAPI specs. HATEOAS is the principle that has become more useful as agents drive applications.
I just discovered that I can paste a link into a Claude prompt and ask it to follow read the page so we can talk about it. I no longer have to copy the text of the page and paste it in. Claude uses the web_fetch command. So we're heading in the direction this article discusses.
Except that more often than not, Claude is blocked from reading the article.
This used to work great two years ago when chatgpt first got the Web browsing feature. Nowadays, no eyeballs on ads: no content.
It refused to read this complaint about Grok because of the NSFW topic
"The irony is they trained their model on so much porn even barely NSFW prompts get flagged because Grok the Goon Commander thinks a simple fully-clothed lapdance requires a visible massive dong being thrusted up her piehole."
https://old.reddit.com/r/grok/comments/1ofd6xm/the_irony_is_...
Claude Code running on your machine can switch to "curl" or even Playwright if it needs to.
Is one of the reasons OpenAI made a browser (Atlas) and Perplexity made Comet and Anthropic made a Chrome extension to make it impossible for the site to tell whether a person or the person's AI assistant is making the request?
I wonder if append-only will continue to be important. As agents get more powers, their actions will likely be the bottleneck, not the LLM itself. And at n*2, recomputing a whole new context might not take much longer than just computing the delta, or even save time if the new context is shorter.
What you're describing is basically very stripped down versions of pre-SPA web pages.
We don't need MCPs for this, just make a tool that uses Trafilatura to read web pages into markdown and create oldschool server side web UIs, and let the agents curl them.
I wonder if I can instruct LLMs to use my MCP whenever they need to access anything online. So they can bypass AI blocks when I tell them to read some docs online.
This can already be done with Claude Code or most agentic tools. There will be restrictions for online platforms as LLMs are very vulnerable to prompt attacks.
HATEOAS always seemed a bit like a solution in search of a problem to me. It was a nice idea for more convenient "manual exploration" of APIs if you're a human developer and all you have is curl - but I never understood for what kind of "production" scenario they were designing their constraints. The kind of automated client that could make actual use of the metadata always seemed more of a fantasy.
...until now. It seems they finally found their problem.
> Purists have long claimed that a “truly” RESTful API should be fully self-describing, such that a client can explore and interact with it knowing nothing but an entrypoint in advance, with hyperlinks providing all necessary context to discover and consume additional endpoints.
> This never worked in practice. Building hypertext APIs was too cumbersome and to actually consume APIs a human needed to understand the API structure in a useful manner anyway.
Every time I read one of these comments I feel like DiCaprio's character in Inception going "but we did grow old together." HATEOAS worked phenomenally. Every time you go to a webpage with buttons and links in HTML that describe what the webpage is capable of (its API, if you will), you are doing HATEOAS [0]. That this interface can be consumed by both a user (via the browser) and a web scraper (via some other program) is the foundation of modern web infrastructure.
It's a little ironic that the explosion of information made possible by HATEOAS happened while the term it self largely got misunderstood, but such is life. Much like reclaiming the proper usage of its close cousin, "REST," using HATEOAS correctly is helpful for properly identifying what made the world's largest hypermedia system successful—useful if you endeavor to design a new one [1].
[0] https://htmx.org/essays/hateoas/
[1] https://unplannedobsolescence.com/blog/why-insist-on-a-word/
I think you're misunderstanding the purpose of hateoas.
If we jump down to the bolts and nuts, let's say on a json API, it's about including extra attributes/fields in your json response that contain links and information of how to continue. These attributes have to be blended with your other real attributes.
For example if you just created a resource with a POST endpoint, you can include a link to GET the freshly created resource ("_fetch"), a link to delete it ("_delete"), a link to list all resources of the same collection ("_list"), etc...
Then the client application is supposed to automatically discover the API's functionality. In case of a UI, it's supposed to automatically discover the API's functionality and build a presentation layer on the fly, which the user can see and use. From our example above, the UI codebase would never have a "delete" resource button, it would have a generic button which would be created and placed on the UI based on the _delete field coming back from the API
I agree. The “purist” REST using HATEOAS is the single most successful API architectural style in history by miles. It’s the foundation of the World-Wide Web, which would not have been anywhere near as successful with a different approach.
I worked for a company that was all hateoas. In the formal sense, explicitly structured around the concept, not the sense that html has both data and actions via links, it worked, it was a real product, but it was slow and terrible to develop and debug.
The front end ui was entirely driven, ui and functionality exposed by the data/action payload.
I'm still not sure if it's because of the implementation or because there is something fundemental.
I came away from that thinking that the db structure, the dag and data flow is what's really important for thinking about any problem space and any ui considerations should be not first class.
But I'm not a theorist, I just found a specific real, real formal working implementation in prod to be not great, it's a little hard even now to understand why.
Maybe it just works for purely text interfaces, adding any design or dynamic interaction causes issues.
I think maybe it's that the data itself should be first class, that well typed data should exist and a system that allows any ui and behavior to be attached to that data is more important than an api saying what explicit mutations are allowed.
If I was to explore this, I think folder and files, spreadsheet, dbs, data structures, those are the real things and the tools we use to mutate them are second order and should be treated as such. Any action that can be done on data should be defined elsewhere and not treated as being the same importance, but idk, that's just me thinking outloud.
> I worked for a company that was all hateoas. In the formal sense, explicitly structured around the concept, not the sense that html has both data and actions via links, it worked, it was a real product, but it was slow and terrible to develop and debug.
The web is also a real product, one that's (when not bloated with adtech) capable of being fast and easy to develop on. That other people have tried to do HATEOAS and failed to make it nice is part of why it's so useful to acknowledge as valid the one implementation that has wildly succeeded.
I do just want to be clear because I'm not 100% following I don't think.
You aren't saying hypermedia/hyperlinks served by a backend equal hateaos are you?
hateaos is from 2000 isn't it? Long after hyperlinks and the web already existed.
REST, including HATEOAS, was largely retrospective documentation of the architectural underpinning of the WWW by Roy Fielding (who played an important role in web technology from 1993 on, was the co-lead for the HTTP/1.0 spec, the lead for the original HTTP/1.1 spec, and also, IIRC, lead or co-lead on the original URL spec. The things it documented existed before it documented them.
Thanks. Appreciate it.
> You aren't saying hypermedia/hyperlinks served by a backend equal hateaos are you?
That’s exactly what it is.
> hateaos is from 2000 isn't it? Long after hyperlinks and the web already existed.
> Over the past six years, the REST architectural style has been used to guide the design and development of the architecture for the modern Web, as presented in Chapter 6. This work was done in conjunction with my authoring of the Internet standards for the Hypertext Transfer Protocol (HTTP) and Uniform Resource Identifiers (URI), the two specifications that define the generic interface used by all component interactions on the Web.
This is straight from the intro of fielding’s doctoral dissertation.
REST / HATEOAS is basically one of the main architects of the web saying “these are the things we did that made the web work so well”. So yes, REST was published after the web already existed, but no that doesn’t mean that the web is not REST / HATEOAS.
Was this recently, using something like HTMX? Or years ago using some other system (or pure/standard HTML)?
Within the last 3 years. They had their own open sourced functional typescript framework that drove the front end.
You could use whatever lightweight rendering you wanted, mostly it was very minimal react but that hardly mattered. One thing that was a positive was how little the ui rendering choice mattered.
I don't really want to say more as it's unique enough to be equivalent to naming the company itself.
Totally agree, the web itself is absolutely HATEOAS, but there was a type of person in the 2000s era who insisted that APIs were not truly RESTful if they weren't also hypermedia APIs, but the only real benefit of those APIs was to enable overly generic API clients that were usually strictly worse than even clumsily tailored custom clients.
The missing piece was having machines that could handle enough ambiguity to "understand" the structure of the API without it needing to be generic to the point of uselessness.
> there was a type of person in the 2000s era who insisted that APIs were not truly RESTful if they weren't also hypermedia APIs
The creator of REST, Roy Fielding, literally said this loud and clear:
> REST APIs must be hypertext-driven
> What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period.
— https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypert...
I think of all the people in the world, the creator of REST gets to say what is and isn’t REST.
Fair, but the person who coins a term generally doesn't ultimately decide how it's going to be used, see vibe coding for a more recent example.
REST API became colloquially defined as "HTTP API with hierarchical URL structure, usually JSON". I wrote about the very phenomenon 15 years ago! https://www.mobomo.com/2010/04/rest-isnt-what-you-think-it-i...
I appreciate the conceptual analogy, but that's not really HATEOAS. HATEOAS would mean your browser/client would be entirely responsible for the presentation layer, in whatever form you desired, whether it's buttons or forms or pages or not even a GUI at all, such as a chat interface.
The Web is not only true HATEOAS, it is in fact the motivating example for HATEOAS. Roy Fielding's paper that introduced the concept is exactly about the web, REST and HATEOAS are the architecture patterns that he introduces primarily to guide the design of HTTP for the WWW.
The concept of a HATEOAS API is also very simple: the API is defined by a communication protocol, 1 endpoint, and a series of well-defined media types. For a website, the protocol is HTTP, that 1 endpoint is /index.html, and the media types are text/html, application/javascript, image/jpeg, application/json and all of the others.
The purpose of this system is to allow the creation of clients and servers completely independently of each other, and to allow the protocols to evolve independently in subsets of clients and servers without losing interoperability. This is perfectly achieved on the web, to an almost incredible degree. There has never been, at least not in the last decades, a big where, say, Firefox can't correctly display pages severed by Microsoft IIS: every browser really works with every web server, and no browser or server dev even feels a great need to explicitly test against the others.
It's a broader definition of HATEOAS. A stricter interpretation with practical, real-world benefits is a RESTful API definition that is fully self-contained that the client can get in a single request from the server and construct the presentation layer in whole with no further information except server responses in the same format. Or, slightly less strictly, a system where the server procedurally generates the presentation layer from the same API definition, rather than requiring separate frontend code for the client.
> HATEOAS would mean your browser/client would be entirely responsible for the presentation layer, in whatever form you desired, whether it's buttons or forms or pages or not even a GUI at all, such as a chat interface.
Browsers can alter a webpage with your chosen CSS, interactively read webpages out loud to you, or, as is the case with all the new AI browsers, provide LLM powered "answers" about a page's contents. These are all recontextualizations made possible by the universal HATEOAS interface of HTML.
Altering the presentation layer is not the same thing as deriving it from a semantic API definition.
Altering the presentation layer is possible precisely because HTML is a semantic API definition: one broad enough to enable self-description across a variety of domains, but specific enough that those applications can still be re-contextualized according to the user's needs and preferences.
Your point would be much stronger if all web forms were served in pure HTML and not 95% created by JS SPAs.
That's a little picky, maybe it's HATEOAS + a little extra presentation sauce (the hottest HATEOAS extension!)
It's not. The whole point of HATEOAS is that the presentation can be entirely derived from the API definition, full stop.
Yes, which is exactly true of the Web. There is no aspect of a web page that is not derived from the HTML+JS+CSS files served by a server.
...which are a presentation layer and not a semantic, RESTful API definition.
That is just wrong.
https://ics.uci.edu/~fielding/pubs/dissertation/net_arch_sty...
The server MUST be stateless, the client MAY be stateful. You can't get ETags and stuff like that without a stateful client.
Deriving a presentation layer from an API definition has no bearing on whether the client has to be stateful or not. The key difference for 'true' HATEOAS is that the API schema is sufficiently descriptive that the client does not need to request any presentation layer; arguably not even HTML, but definitely not CSS or JavaScript.
https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_st...
> any concept that might be the target of an author's hypertext reference must fit within the definition of a resource
Dude, he literally mentions Java Applets as an example (it was popular back then, if it was written today it would have been JavaScript). It's all there. Section 5.1.7.
It's an optional constraint. It's valid for CSS, JavaScript and any kind of media type that is negotiable.
> resource: the intended conceptual target of a hypertext reference
> representation: HTML document, JPEG image
A resource is abstract. You always negotiate it, and receive a representation with a specific type. It's like an interface.
Therefore, `/style.css` is a resource. You can negotiate with clients if that resource is acceptable (using the Accept header).
"Presentation layer" is not even a concept for REST. You're trying to map framework-related ideas to REST, bumping into an impedance mismatch, and not realizing that the issue is in that mismatch, not REST itself.
REST is not responsible for people trying to make anemic APIs. They do it out of some sense of purity, but the demands do not come from HATEOAS. They come from other choices the designer made.
I will concede the thrust of my argument probably does not fully align with Fielding's academic definition, so thank you for pointing me to that and explaining it a bit.
I'm realizing/remembering now that our internal working group's concept of HATEOAS was, apparently, much stricter to the point of being arguably divergent from Fielding's. For us "HATEOAS" became a flag in the ground for defining RESTful(ish) API schemas from which a user interface could be unambiguously derived and presented, in full with 100% functionality, with no HTML/CSS/JS, or at least only completely generic components and none specific to the particular schema.
It happens.
"Schema" is also foreign to REST. That is also a requirement coming from somewhere else.
You're probably coming from a post-GraphQL generation. They introduced this idea of sharing a schema, and influenced a lot of people. That is not, however, a requirement for REST.
State is the important thing. It's in the name, right? Hypermedia as the engine of application state. Not application schema.
It's much simpler than it seems. I can give a common example of a mistake:
GET /account/12345/balance <- Stateless, good (an ID represents the resource, unambiguous URI for that thing)
GET /my/balance <- Stateful, bad (depends on application knowing who's logged in)
In the second example, the concept of resource is being corrupted. It means something from some users, and something to others, depending on state.
In the first example, the hypermedia drives the state. It's in the link (but it can be on form data, or negotiation, for example, as long as it is stateless).
There is a little bit more to it, and it goes beyond URI design, but that's the gist of it.
It's really simple and not that academical as it seems.
Fielding's work is more a historical formalisation where he derives this notion from first principles. He kind of proves that this is a great style for networking architectures. If you read it, you understand how it can be performant, scalable, fast, etc, by principle. Most of the dissertation is just that.
From what I read on wiki, I'm not sure what to think anymore - it does at least sound inline with the opinion that the current websites are actually HATeOAS.
I guess someone interested would have to read the original work by Roy (who seems to have come up with the term) to find out which opinion is true
I worked on frontend projects and API designs directly related to trying to achieve HATEOAS, in a general, practical sense, for years. Browsing the modern web is not it.
I think you are confusing the browser with the web page. You probably think that the Javascript code executed by your browser is part of the "client" in the REST architecture - which is simply not what we're talking about. When analyzing the WWW, the REST API interface is the interface between the web browser and the web server, i.e. the interface between, say, Safari and Apache. The web browser accesses a single endpoint on the server with no prior knowledge of what that endpoint represents, downloads a file from the server, analyzes the Content-Type, and can show the user what the server intends to show based on that Content-Type. The fact that one of these content types is a language for running server-controlled code doesn't influence this one bit.
The only thing that would have made the web not conform to HATEOAS were if browsers had to have code that's specific to, say, google.com, or maybe to Apache servers. The only example of anything like this on the modern web is the special log in integrations that Microsoft and Google added for their own web properties - that is indeed a break of the HATEOAS paradigm.
I'm not confusing it. I was heavily motivated by business goals to find a general solution for HATEOAS-ifying API definitions. And yes, a web page, implemented in HTML/CSS/JS is a facsimile for it in a certain sense, but it's not self-contained RESTful API definition.
HATEOAS is hypertext as the engine of application state. When a person reads a webpage and follows links, it’s not HATEOAS, because the person is not an application.
HATEOAS and by-the-book REST don’t provide much practical value for writing applications. As the article says, a human has to read the spec, make sense of each endpoint’s semantics, and write code specific to those semantics. At that point you might as well hardcode the relevant URLs (with string templating where appropriate) rather than jumping through hoops and pretending every URL has to be “discovered” on the off chance that some lunatic will change the entire URL structure of your backend but somehow leave all the semantics unchanged.
The exception, as the article says, is if we don’t have to understand the spec and write custom code for each endpoint. Now we truly can have self-describing endpoints, and HATEOAS moves from a purist fantasy to something that actually makes sense.