Notes for September 29-October 12

I have been rather too busy hopping from project to project to do anything but read and watching a little TV in the evenings, as well as a bit annoyed by more industry disturbances and .

Despite the lack of long-form posts, I am still (slowly) poking at a few things:

  • I updated umcp both as a follow-up to and after fine-tuning the server I use to reformat old posts to a point where I can leave Copilot or aider to convert 10-20 old posts to with minimal oversight (there are still 3900+ pages in this site with legacy markup).
  • I added a note on my page regarding enabling Wake-on-LAN, since some people who read were having trouble getting Steam Link to wake up their machines.
  • I am again circling the custom keyboard rabbit hole, with the likely outcome being my building a Totem for both ergonomics and portability. And no, ZSA’s voyager isn’t available with either Bluetooth or truly silent switches.
  • On that topic, I have found myself revisiting keyboard-oriented and realizing nobody implemented something I really need (shifting focus to an adjacent window by direction), so I spend a while fiddling with and came up with this config, which works fine except that in Sonoma and Tahoe Safari is still buggy and delays window enumerations by several seconds
  • I updated my notes on getting a new 3D printer and nearly pulled the trigger on an (which was briefly on sale, and which I’m partial to for hackability) before noticing that Bambu will be updating the P1S. I am more interested in multi-material and engineering materials than multi-color (I did a little video on modding the with a carbon fiber part), so I’m going to see what they come up with–I might even opt for getting a discounted older model.
  • bun 1.3 came out, so I upgraded a few of my instances (bun has almost completely replaced NodeJS for my personal projects)

There are also a few hardware reviews in progress, which have been slowed down by work and my trying to record more video, which makes everything take much longer.

Creating Per-Project MCP Servers

I must confess, first and foremost, that I am not a fan of as a protocol–I find it overly complex (why shunt that much JSON around and waste tokens parsing it?), badly designed for application scenarios (it is completely redundant if you have good Swagger specs for your APIs, not to mention poorly secured) and has generated so much hype that I instinctively shied away until the dust settled.

But a few months ago I found a (genius) minimalist stdio MCP server (in bash, of all things), turned it into a Python library (with both synchronous and asyncio flavors) and decided to build a couple of tools to extend GitHub Copilot inside .

And then one day I built another tool for another workspace. And another. And after three or so, a pattern emerged–even though provides Copilot with local filesystem and code structure information, I often needed to have specialist tools to help with things like:

  • Looking up snyk vulnerabilities in package.json files
  • Validating internal wiki links in Markdown files
  • Converting old Textile markup to Markdown
  • Adding or updating YAML front-matter in blog posts
  • Bulk-renaming (or linting/formatting) files according to some pattern

And I only needed those tools in one workspace at a time, so having a zillion tools available all the time was pointless (and confused the LLM).

So I started including simple task-specific servers in my repositories.

Configuring VS Code

As it happens, this very site is a good example. The git repository I use for the content has a wiki-helper server that makes it easy for me to check internal page links and perform chores like converting old Textile markup or adding data to YAML files when publishing a post.

stores its workspace preferences in a .vscode folder inside your repository, and the Copilot extension in particular gets its starting context from inside .github, so right now things look like this:

.github
└── copilot-instructions.md
.vscode
├── extensions.json
├── mcp.json
└── settings.json
tools
├── wiki_mcp.py
└── umcp.py

Since I do not need a virtual environment for this particular repository, I can just dump umcp.py alongside my server, and configure mcp.json to invoke it like this:

 cat .code/mcp.json
{
    "servers": {
        "wiki-helper": {
            "type": "stdio",
            // Use python executable as command; pass script path as first arg for consistent CWD handling.
            "command": "python3",
            "args": [
                "tools/wiki_mcp.py"
            ],
            // Provide explicit environment override so WIKI_ROOT uses workspace root (script already defaults correctly).
            "env": {
                "WIKI_ROOT": "${workspaceFolder}/space"
            }
        }
    }
}

This is actually one of my simplest servers (it mostly uses regexps, Path and a few more standard library functions), but I also have other projects that require specific libraries, so I use uv to run the server in those.

Also, besides including in copilot-instructions.md a short description of what the project is, what coding conventions and tooling I’m using, etc., I typically add “use tools from the foobar server to do these tasks”.

Configuring Zed

Configuring is very similar, since it too allows you to have per-workspace settings:

 cat .zed/settings.json 
{
  "context_servers": {
    "wiki-helper": {
      "source": "custom",
      "command": "python3",
      "args": ["tools/wiki_mcp.py"],
      "env": {}
    }
  }
}

However, does not seem to have an easy way to pass the workspace root as a variable, so I’ve had to hack that into the server itself. If anyone knows how to do that, please let me know.

Additionally, is rather picky about server versions (as of this writing it actually errors out if they’re not 2025-03-26 or 2024-11-05, which is a bit too limiting).

Either way, this approach has proven to be highly effective, enabling me to maintain per-project tooling with ease. This not only automates repetitive tasks but also significantly reduces costs and optimizes LLM usage. For instance, I can leverage gpt-4o or gpt-5-mini to handle specific tools, avoiding the need for more expensive models like gpt-5 or Claude, which incur premium charges in GitHub Copilot.

In particular, having a tool to check internal wiki links has been a godsend, since I can now just prompt Copilot to “reformat this post according to repository patterns” before publishing a post and be reasonably sure that I won’t have broken links (which is a pet peeve of mine):

Here's a recent example
Here's a recent example

The fact that I can also use Copilot to help me write the servers themselves with full context of what the project is about and how files are laid out is just icing on the cake, even if it smacks of self-improving

Notes for September 22-28

It was a moderately exciting week work-wise (in a positive way), but a recurrence of the highly disruptive habit people have of booking meetings the very next day or early the day after (even when any sort of effective work would take a day or so to yield finished results) made it hard to, well, do anything at all…

Read More...

Notes for September 15-21

A rather hectic week as work ramps up again and I start to progressively lose control of my calendar, but I’ve managed to slowly accrete some notes.

Read More...

Notes on the Liquid Glass Tsunami

Following my little saga with the , I upgraded a few of my Apple devices, including one of my Macs, to the final release versions of all the “26” operating systems, and… It’s even worse than I thought.

Read More...

Notes for September 8–14

I’m now fully back to work, so there hasn’t been any free time for anything but finishing overdue posts. I have, however, managed to sneak in a few leisurely half-hours in the mornings reading work e-mail from my balcony before my calls start, which has been a great way to enjoy the lingering summertime.

Read More...

The Cudy AX3000 Wi-Fi 6 System (with OpenWRT)

As I’ve been writing about or , I’ve recently upgraded my Wi-Fi after an attempt to use ISP-provided equipment to replace my remarkably long-lasting (and extremely reliable) base stations.

Read More...

The Chuwi AuBox 8745HS

As regular readers will know, I am quite fond of the various Ryzen APUs that have hit the market over the past couple of years, and I take a look at them whenever I can, since they have proven to be quite popular options—partially because of the high core counts and partly because of their increasingly powerful iGPUs.

Read More...

The iPhone 17 Event

This time I actually forgot to watch the live event.

Read More...

Archives3D Site Map