Point the Homelab Tools at Any Model — Including One You Host

Four of my field tools only worked on claude.ai. They now run against OpenAI, Gemini, DeepSeek, Groq, OpenRouter or your own Ollama — and here is the browser rule that decides which of those can work from a website at all.

On this page
  1. Why they were stuck on claude.ai in the first place
  2. Your key does not pass through this site
  3. Which providers actually work from a browser
  4. The interesting part: why your own Ollama can’t be reached from a website
  5. What this changes

I built eleven field tools for the questions homelab guides skip. Seven of them are arithmetic and decision trees — they run entirely in your browser and keep working with the network unplugged. The other four need a language model behind them, because “which line in this log is the actual cause” is not a calculation.

Those four had a flaw I’d been quietly living with: they didn’t work on my own website.

If you opened Log Triage on peira.dev, you got a polite notice explaining that this one thinks for a living and a link sending you to claude.ai. The tool was right there on the page, fully rendered, and completely inert. Four of my eleven tools were a brochure for themselves.

That’s fixed. They now ask you which model to use, and then talk to it directly from your browser.

peira.dev/tools/troubleshooter/
The model setup panel inside a field tool, showing a provider dropdown, a base URL field, an API key field, a model field, a 'remember the key on this device' checkbox, a 'Load models' button, and a note stating the key is held for the browser tab only and is never written into the lab profile.
Pick a provider, paste a key, choose a model. Or pick Ollama and give it an address — no key involved at all.

Why they were stuck on claude.ai in the first place

Each tool is a single self-contained HTML file. No build step, no server, no bundle. That constraint is the whole point — you can save one to a USB stick and it still works — but it means there is nowhere to keep an API key. A key in the page source is a key you’ve published.

The original answer was to lean on window.claude.complete, an API that exists only inside a claude.ai artifact. It’s genuinely elegant: the reader’s own subscription pays for the inference, I pay nothing, and so the tools can stay free indefinitely without me quietly hoping nobody uses them. It’s also why I could publish tools that call a model at all without a funding model.

The catch is that the API exists only there. On any other page, window.claude is undefined, and the tool had nothing to fall back to.

The fix is the obvious one I’d been avoiding because it sounded like a security problem: let you bring your own key. It turns out the browser makes this safer than it sounds, for a reason worth explaining.

Your key does not pass through this site

There is no server here. peira.dev is static files on a CDN. When you paste a key into one of these tools, the page calls the provider directly from your browser — the request goes from your machine to OpenAI, or Anthropic, or your own Ollama, and never touches any infrastructure of mine.

This isn’t a promise about my good intentions; it’s a property of the architecture. I couldn’t log your key if I wanted to, because there’s nothing in the path that could log it.

What I can get wrong is where the key sits in your browser, so:

  • It lives in sessionStorage and dies when you close the tab, unless you explicitly tick remember on this device.
  • It is never written into your lab profile. That’s deliberate and load-bearing: the profile exists to be exported as JSON and rendered into a shareable lab record, so a credential in it would be handed out along with it.
  • It goes to exactly one host — the provider you chose.
A key you paste anywhere is a key you should be able to revoke

This applies to every browser tool that asks for one, not just mine. Use a key scoped to the smallest thing that works, and know where the revoke button is. If you point a tool at a custom endpoint, you’re sending your key to whoever runs that endpoint — which is inherent to the feature, and worth saying plainly rather than burying.

Which providers actually work from a browser

This part I tested rather than assumed, because “the API supports CORS” is a claim that ages badly and half the answers online are guesses. Every one of these was checked with a real cross-origin preflight from https://peira.dev on 14 August 2026:

Provider Preflight What it returns
OpenAI 200 reflects the origin
Google Gemini 200 reflects the origin
DeepSeek 200 reflects the origin
Anthropic 200 *
Groq 204 *
OpenRouter 204 *

All six work directly from a web page. Anthropic requires you to opt in with a header that is named, with admirable bluntness, anthropic-dangerous-direct-browser-access — the danger being exactly the one above: your key is in a browser, so treat it accordingly.

Anything else speaking the OpenAI chat API works too — LM Studio, llama.cpp’s server, vLLM, LiteLLM, Together, Fireworks. There’s a free-text base URL for that.

The interesting part: why your own Ollama can’t be reached from a website

Here’s the finding I didn’t expect, and the one most likely to save you an evening.

You cannot point peira.dev at your local Ollama. Not because I disallowed it — because the browser and Ollama each independently refuse, and either one alone would be enough.

Ollama refuses the origin. Out of the box it accepts requests from localhost and 127.0.0.1 origins and rejects everything else. A request carrying Origin: https://peira.dev gets a flat 403, before any question of models or keys arises.

Chrome refuses the address. Even with Ollama’s origins opened up, Private Network Access stops a public HTTPS page from reaching a private address unless the local server explicitly opts in by returning Access-Control-Allow-Private-Network: true. Ollama doesn’t send that header. Chrome has been enforcing this since v130.

This is a good rule, not an obstacle

It exists because the alternative is worse. Without it, any website you visit could quietly probe and poke every device on your home network — your router’s admin page, your NAS, your printer — using your browser as the way in. The rule that blocks my tool from reaching your Ollama is the same rule that stops a malicious page reaching your Proxmox host.

So the local path is: serve the tool yourself. Every tool in the repo is one file, and there’s a tiny loopback-only server included:

git clone https://github.com/peiralabs/field-tools.git
cd field-tools
python3 cors-server.py

Then open http://localhost:8643/log-triage.html and choose Ollama. No Ollama configuration is needed — it already allows localhost origins, which is now what your page has. Point it at http://localhost:11434/v1, or at another box on your LAN like http://10.0.0.50:11434/v1; what Ollama checks is the page’s origin, not the address you’re calling.

I ran exactly this against a CPU-only Ollama node running qwen2.5-coder:7b. Pasted a log with an ext4 error buried in six lines of noise, and it correctly pulled out the buffer I/O error as the line that mattered, told me which lines to ignore, and suggested smartctl. It took a while — CPU inference on old hardware is not fast — but it worked, entirely inside my own network.

Click Load models rather than trusting my defaults

Each provider gets a default model name in the panel, and model names go stale fast. Load models asks your provider what your key can actually see and fills the list from the answer. If you get a 404 mentioning the model name, that’s what to press.

One gotcha it now handles for you: if you run embedding models alongside chat models, nomic-embed-text often sorts first alphabetically — and it cannot answer a chat request. The panel skips embedding models when picking a default, because the first version didn’t, and the first thing it did was choose one.

What this changes

Mostly it means the tools are honest about what they are. Four of them claimed to be free browser tools while actually being adverts for a page on someone else’s site. Now they’re what they said they were.

It also means the tools survive me. If I lose interest, or Anthropic changes the artifact API, or peira.dev goes away — you have a file that runs against any model you like, on hardware you control, with no dependency on my continued attention. That was always the intent behind making them single files. This closes the last gap.

The seven offline tools are unchanged and still need nothing at all. All eleven are at peira.dev/tools, and the source, including the reasoning and the measurements above, is at github.com/peiralabs/field-tools.


Related posts:

Comments

Comments are powered by GitHub Discussions — sign in with a GitHub account to join the conversation.