← All posts

Hello, skoderok.com

What this site is, what will live here, and why the blog is edited over MCP instead of a CMS.

2 min read

This post is also available in Russian: Привет, skoderok.com

I'm Valeriy Chupurnov. I've been writing software for a long time; most people who know my name know it from Jodit, the WYSIWYG editor I've been maintaining for over a decade. This site is the place where the rest of my work gets a home: the experiments, the tools, the things that are too small for a repo README and too large for a tweet.

What is here

  • About — a short page about me and how to reach me.
  • Projects — the things I maintain: Jodit and its plugins, internal tools, the ecosystem simulator I'll write about next.
  • Demos — things you can click. The first one is the World 2.0 viewer: a three.js sphere with animals that run on a tiny neural network trained inside a Rust simulation.
  • Articles — longer, edited texts. Fewer of them, more polished.
  • Blog — this. Working notes, written as I go. Two languages: Russian is the default (/blog/), English lives under /blog/en/. Not every post gets a translation; when one exists, the language switch in the header takes you to it.

How the blog works

I didn't want a CMS and I didn't want a static site I have to rebuild for every typo. The blog is an Astro app running in server mode inside a Docker container. Posts are plain markdown files with frontmatter in a mounted directory; the server reads them at request time and caches the rendered HTML by file mtime. Drop a file in, the post is live.

The interesting part is how the files get there. The blog exposes an MCP endpoint at /blog/mcp with a handful of tools: posts_list, posts_get, posts_search, posts_create, posts_update, posts_publish, posts_delete. Reading is open; writing needs a bearer token. That means I can open Claude Code, say "fix the typo in the second paragraph of the World post" or "draft the English translation of yesterday's note", and the agent edits the actual file on the server. Same for the simulator itself: when a training run finishes, an agent can write up the results directly into a draft here.

{
  "mcpServers": {
    "skoderok-blog": {
      "type": "http",
      "url": "https://skoderok.com/blog/mcp",
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}

The whole thing is small: one TypeScript module for reading and writing posts, one for the MCP tools, a few Astro pages. No database, no admin panel. If I stop liking it, the posts are still markdown files in a folder.

What's next

The first real post is about World 2.0: why I wrote an ecosystem simulator in Rust with zero dependencies and a bit-exact deterministic core, and what it took to train a 59-input MLP to behave like a hand-written animal. After that: notes on Jodit internals, on the tooling around this site, and whatever I happen to be debugging.

There's an RSS feed if you want to follow along.