---
title: "MCP server"
description: "A public, read-only MCP server at https://serhiichuk.dev/mcp. Streamable HTTP, no auth, no signup. Six tools over already-published data, including an llms.txt validator that works on any domain."
canonical_url: "https://serhiichuk.dev/tools/mcp/"
---

# MCP server

Public · read-only · no auth · no signup · free

An [MCP](https://modelcontextprotocol.io) server that lets your agent read this site directly — the
CV, the posts, the services — instead of scraping the HTML. Six tools, all read-only. Point a client
at the URL below and it works; there is nothing to sign up for and nothing to pay.

**Endpoint:** `https://serhiichuk.dev/mcp`

Streamable HTTP. No API key, no OAuth, no headers to set. There is no SSE endpoint — `serveSSE` is
deprecated, and shipping a deprecated transport on day one would be a strange thing to demonstrate.

## Add it to your client

Five clients, and all five want the same two facts — a name and a URL — in five different spellings:
`url` in one, `serverUrl` in another, a `type` the others do not have, a TOML table instead of JSON.
Every block names the server `serhiichuk`; rename it to whatever you like, the server does not care.

**Claude Code** (terminal):

```bash
claude mcp add --transport http serhiichuk https://serhiichuk.dev/mcp
```

That writes to local scope. Add `--scope user` to make it available in every project on your
machine, or `--scope project` to commit it into the repo's `.mcp.json` for the rest of your team.
Check it connected with `claude mcp list`.

**Codex** (`~/.codex/config.toml`):

```toml
[mcp_servers.serhiichuk]
url = "https://serhiichuk.dev/mcp"
```

Codex keeps its config in TOML, under `$CODEX_HOME` if you have set that. There is no `type` or
`transport` key — writing `url` rather than `command` is what selects Streamable HTTP. Older guides
also set `experimental_use_rmcp_client = true`; that flag no longer exists and the transport is
stable now, so leave it out. Or let the CLI write it:

```bash
codex mcp add serhiichuk --url https://serhiichuk.dev/mcp
```

**Antigravity** (`~/.gemini/config/mcp_config.json`):

```json
{
  "mcpServers": {
    "serhiichuk": {
      "serverUrl": "https://serhiichuk.dev/mcp"
    }
  }
}
```

That path is the global one; `.agents/mcp_config.json` does the same job for a single workspace. The
field is `serverUrl`, not `url`, and there is no `type` — the docs say legacy `url` and `httpUrl` are
not supported, and while newer builds do take `url`, `serverUrl` works everywhere.

**OpenCode** (`opencode.json`):

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "serhiichuk": {
      "type": "remote",
      "url": "https://serhiichuk.dev/mcp"
    }
  }
}
```

Per project, or `~/.config/opencode/opencode.json` for all of them. That is the shape stable OpenCode
reads — the published schema wants both `type` and `url`, and `type` takes only `remote` — while the
2.0 beta (`opencode2`) nests the same entry under `mcp.servers`. `timeout` defaults to 5000 ms and
takes a larger number if a call ever runs past it. Or let the CLI write it:

```bash
opencode mcp add serhiichuk --url https://serhiichuk.dev/mcp
```

**Any other client** (an `mcpServers` entry):

```json
{
  "mcpServers": {
    "serhiichuk": {
      "type": "http",
      "url": "https://serhiichuk.dev/mcp"
    }
  }
}
```

Paste the entry into whatever file your client keeps its servers in. Some clients spell the transport
`streamable-http` rather than `http`; both name the same thing, so use whichever one your client
documents.

## The six tools

Every one of them returns text. Nothing here writes, sends, or changes anything.

- `search_content(query, limit?)`: Searches the CV bullets, blog posts and site pages, and returns
  ranked excerpts with their URLs.
- `get_cv(format?)`: The CV. json returns JSON Resume v1.0.0 (structured, best for parsing); brief
  returns the prose summary in llms.txt format (best for reading).
- `list_posts()`: Every published blog post — title, slug, date and summary.
- `get_post(slug)`: The full Markdown of one post. The slug comes from list_posts or
  search_content.
- `get_services()`: What I offer as a consultant — services, engagement models, and how to get in
  touch.
- `validate_llms_txt(url)`: Checks any website's /llms.txt against the llmstxt.org spec: structure,
  link health, and whether each finding is spec, convention or hygiene. Works on any domain, not just
  this one.

## One of them is useful to you, not to me

Five of these tools describe me, which is only interesting if you are looking me up.
`validate_llms_txt` is the one an unrelated developer might keep installed: it checks *your* site's
llms.txt, or any other domain's, and tells you which findings are spec violations and which are only
convention. That is the reason this server is worth publishing rather than merely worth demoing.

It is the same validator that runs behind
[the llms.txt validator page](https://serhiichuk.dev/tools/llms-txt/index.md) — same rules, same
findings, one with a UI and one for your agent.

## What it does not do

### Search is keyword, not semantic

`search_content` ranks on the words you give it, so phrase your query with the words you expect to
appear on the page. The published search index does carry vectors, but they are only usable by the
on-device model the browser loads for site search — ranking against them means embedding the query
with that same model, which is tens of megabytes of browser-native code and never survives a Worker
bundle. Rather than ship a second, subtly different embedding and call it the same search, the tool
does the honest thing and matches keywords.

### There are no write tools

Nothing here sends an enquiry, books a call, or leaves a message. An unauthenticated tool that emails
someone is an abuse vector, and [the contact form](https://serhiichuk.dev/contact/) already covers
that path for humans. This is a deliberate omission, not a gap to be filled later.

### No tool writes prose about the CV

There is no "summarise his experience" tool and there will not be one. The tools return source
excerpts and let your model do the talking, which removes the fabrication risk rather than mitigating
it — a quote it can point at beats a paragraph it made up about me.

## Where the data comes from

Every tool reads a URL this site already publishes — the same bytes any visitor or crawler can fetch.
There is no second data pipeline and no copy of the CV source, which is what makes the server safe by
construction rather than by review: the publish gate that decides what reaches the public site is the
only gate, and this Worker inherits it instead of re-implementing it. Anything private would have to
leak onto the site first, at which point this server is the least of the problems.

## Want your own systems legible to agents?

I work on cloud architecture, DevOps and FinOps — including the part where the systems you already
run have to be readable by the agents that now read them.

[Book a call](https://serhiichuk.dev/contact/)
