AI News Hub Logo

AI News Hub

AI Without Backend: How ClientAgentJS Works

DEV Community
Fran Bar Instance

There are hardly any browser libraries that let you integrate a conversational AI agent without relying on a backend. Most options assume there's an intermediate server handling requests and protecting credentials. With the intention of exploring that space, I started developing ClientAgentJS, a utility written in JavaScript that runs directly in the user's browser and also includes compatibility with the Model Context Protocol (MCP). The code is available on GitHub if you want to take a look. The underlying idea is simple: from any web page, users can use their own AI model. Whether it's a commercial service with a personal key or a local one like Ollama, the library provides a unified interface to chat with the model or ask it to perform tasks. The design is shaped from the outset by two major constraints. The first is technical and has a name: CORS. Not all AI providers accept direct requests from a browser, and those that do often require specific configuration. This same limitation extends to any MCP servers the agent might want to connect to. The second constraint has more to do with typical user behavior. However technically possible, most people are not going to install Ollama or enter their own API keys on just any website. You can suggest it, but the most common response will be rejection or indifference. In fact, this point already hints at why tools of this kind are so rare. Even so, there are very specific scenarios where this approach fits naturally. Right here on dev.to, when creating the cover image for a post, the editor offers the option to generate it with AI. Although at the time of writing the image functionality is not yet implemented, the idea is a perfect example of the kind of integration ClientAgentJS is designed for. The first, and perhaps most immediate, is internal tools. In teams where everyone already manages their own API keys because they work regularly with these services, adding AI capabilities to an admin panel or a productivity utility becomes almost trivial. The developer integrates the library, and each user configures their profile once using their own credentials. A very specific and recurring case is admin forms. Think of an e-commerce panel where product sheets are entered. The operator can generate or improve the description from the attributes already filled in, using their own OpenAI or Anthropic account, without the company having to set up a shared service or bear the token costs. It also fits especially well in browser extensions. After all, an extension already runs in the client context and has access to visited pages. Reusing the core of the library to add summaries, translations, or suggestions on active content is a natural combination. Another fertile ground is prototypes and demos. When you're validating an idea and need to show something functional with AI, skipping all the backend infrastructure saves hours of setup and lets you iterate much faster. You carry everything in the frontend, host it on a static server, and it works. And finally, any application that wants to offer provider freedom to the user. If your product doesn't want to be tied to a single model and you prefer that each person chooses whether to use OpenAI, Anthropic, Google, or even their own local Ollama, the library abstracts those differences and provides a consistent experience without you having to write an adapter for each case. If you want to see it in action, there are several demos available that showcase different use cases: Chat Explorer : a full-featured chat interface with session management, streaming cancellation, and Markdown rendering. Ideal for testing the library in a classic conversational environment. Form Assistance : the example most aligned with the library's main use case. It shows how to add AI assistance to existing forms (bio, product description, support response) without redesigning the whole application. MCP Tools : a technical example focused on MCP server integration. It connects the agent to an example server and allows inspection of remote tools that the model can use automatically. Simple HTML Editor : a visual HTML template editor (intended for landings or content pages) that integrates ClientAgentJS so the user can ask the AI to write text, translate fragments, change buttons, or modify content directly from the editing panel. Anyone who has tried to call an external API directly from the browser has sooner or later encountered the same message in the console: the cross-origin resource sharing policy, better known as CORS. It's a browser security mechanism that prevents a web page from making requests to a domain different from the one that served it, unless the destination server explicitly allows it via certain headers. In the context of a library that wants to talk to AI providers directly from the client, CORS becomes the first major filter. Not all services are prepared to receive traffic from a browser, and those that are often require additional configuration or have limitations. It's worth noting an important detail about the library itself: it's written in standard JavaScript, with no external dependencies or transpilation needed. This means that, in addition to working on any web server, it also runs directly from the file:// protocol. In other words, you can open a local HTML file in your browser and the library will work just as if it were hosted on a domain. This feature, combined with localStorage persistence, makes quick tests and prototypes much easier without even needing to spin up a local server. That said, CORS still applies its rules when the destination is external, so the core problem remains. Each provider has its own stance regarding browser requests: Anthropic (Claude) does allow direct access, but requires the request to include a specific header: anthropic-dangerous-direct-browser-access. The library adds it automatically when using the native Anthropic adapter. The header name already hints that it's not the recommended flow for production, but for the use cases we're dealing with, it's perfectly valid. Google (Gemini) also supports CORS on its generative API without any additional steps. It's one of the most browser-friendly providers in this regard. OpenAI, on the other hand, does not allow direct access from a browser. Its endpoints reject requests with a web origin. This is a total blocker if you intend to use the pure client-to-provider model. Ollama, the popular local model server, does not enable CORS by default. It must be started with the OLLAMA_ORIGINS environment variable properly configured to accept requests from the application's domain. For cases where the provider doesn't support CORS, there are alternatives. A very practical one is OpenRouter, a service that acts as a unified gateway to dozens of models (including OpenAI's) and does allow browser requests. Another option, especially in development environments, is to use a public CORS proxy, though it's not recommended for production. And of course, there's always the possibility for the developer to set up their own proxy in the backend and expose a local endpoint that respects the same-origin policy. Compatibility with the Model Context Protocol adds an extra layer of complexity because MCP servers also need to be accessible from the browser. Many MCP servers are designed to run as local processes and communicate via stdio, not over HTTP with CORS. To use them with ClientAgentJS, the server must expose an HTTP endpoint with the appropriate CORS headers or run on localhost, in which case the same-origin policy doesn't apply if the page is also served from localhost. The cleanest solution for production environments is usually for the developer to host the required MCP servers and configure them with CORS, or for the user to run them on their local machine. The library cannot work magic with browser restrictions, but it does offer the flexibility for each case to adapt to what the provider or MCP server allows. That's all If you want to take a look, play around with the demos, or even use it in your own project, everything is on GitHub. And if you have any questions or suggestions, the comments are open.