← All posts

What I learned building an MCP server

Notes from building JOS — an MCP server that turns markdown wikis into something an AI client can actually search.

  • MCP
  • Python
  • Tooling

This is a starter draft. Rewrite it in your own words, or delete the file — the site picks up whatever is in content/posts/.

I spent the last few months building JOS (Just One System), an open-source MCP server that exposes a markdown wiki to AI clients like Cursor and Claude Desktop. The idea is simple: you already keep notes: why should your tools not be able to read them?

The interface is another program

The thing that reframed the whole project for me is that nobody looks at an MCP server. There is no screen. Your only user is a model calling tools, and it decides what to call based on your tool descriptions alone.

That changes the design work. A vague description is a bug:

@mcp.tool()
def search(query: str, limit: int = 10) -> list[dict]:
    """Search wiki pages by full-text query.

    Titles and tags are boosted over body text, so a query matching
    a page title ranks above one that only matches the body.
    """
    return rank(query, limit=limit)

The docstring is the UI. I rewrote mine more times than the code under it.

Storage without a database

JOS uses GitHub as the storage backend rather than a database. That sounded lazy at first, but it buys a lot:

  • Every write is a commit, so history is free
  • Images live next to the pages that reference them
  • You can edit a page in GitHub's UI and the server picks it up
Approach History Hosting cost Edit outside the app
Postgres Manual Paid No
GitHub API Free Free Yes

What I would do differently

  1. Write the tool descriptions first, before any implementation.
  2. Test against more than one client early — Cursor and Claude Desktop disagree about edge cases.
  3. Keep the tool count down. I shipped 20+, and I suspect a smaller set would be used better.

If you want to poke at it, the source is on GitHub.

Thoughts on this? Email me.