Skip to content

v1.0.0

Choose a tag to compare

@luanAfons0 luanAfons0 released this 20 Sep 14:34
· 135 commits to main since this release

FirstMate is a local plugin host. It runs a person's own tools on their own machine and gives each one a process, a page and an address, so that no tool has to build a runtime of its own.

npx @luan-afonso/firstmate start

What a Plugin is

A directory, named in the Registry. There is no manifest and no schema.

  • Put a web/ directory in it and the Host serves it at /p/<name>/, byte for byte.
  • Put an executable named mcp in it and the Host runs it and speaks MCP to it over stdin and stdout. The shebang decides the language, so a Plugin Server can be written in anything.
  • A directory with neither is still a Plugin. It just has nothing to show.

Adding a Plugin neither copies nor symlinks its directory. The Registry holds the path, so a Plugin stays in its own repository wherever it already lives.

What the Host does

Four things, and nothing else: it supervises processes, it serves HTTP on loopback, it serves a Plugin's static files, and it is a JSON-RPC client.

  • Starts every Plugin Server at boot, and holds the truth about each. A Plugin is Running, Stopped, or has no Plugin Server, and the Index Page says which.
  • Serves the Index Page, every Plugin Page, and POST /p/<name>/rpc, which carries a Plugin Page's tool call to its own Plugin Server.
  • Carries a call from one Plugin Server to another over the stdio pipe it already owns, and only where the Registry records a Grant for that pair, in that direction. The calling Plugin Name comes from the pipe, so it cannot be forged.
  • Mints a token at every start and refuses every request that does not carry it. It checks Host and Origin on each one, and binds 127.0.0.1 and no other address.

What v1 does not do

The absences are deliberate. Each one is written down.

  • No scheduler. The Host runs nothing on a timer. Use cron, or systemd, or the Plugin's own loop (ADR-0004).
  • No sandbox. A Plugin is a directory its owner registered, run with the owner's own privileges. The Host supervises processes; it does not contain them. Registering a hostile Plugin is the same act as running a hostile program.
  • No data of yours. The Host keeps no run history, no logs and no settings for a Plugin. A Plugin owns its own data (ADR-0005).
  • No reach between Plugin Pages. A Plugin Page reaches its own Plugin and no other. The Tool Bus is on the pipe, and a browser holds no end of it (ADR-0009).
  • No restart of a Stopped Plugin. A broken Plugin stays visible rather than spinning in a restart loop. It still serves its Plugin Page.
  • No framework, no bundler, no build step in a clone. Node 24 runs the TypeScript directly. Only the published package is compiled (ADR-0010).
  • No runtime dependencies. The Host speaks MCP over about 140 lines of its own JSON-RPC.

Where it runs

Evidence, not a promise. WSL Debian is proved throughout. macOS and native Linux should work and are untried. Native Windows will not run a Plugin Server: the Supervisor tests the executable bit and runs the mcp file directly, and Windows reads no shebang. Plugin Pages are unaffected.

The README's platform table is where this is kept honest. If you run FirstMate somewhere untried, #46 is the smallest way to help.

Getting started

  • README — install it, add a Plugin, run the Host.
  • docs/plugin-guide.md — the whole Plugin contract: what the Host enforces, and what it only advises.
  • CONTEXT.md — every word this project uses.
  • docs/adr/ — the decisions that are expensive to reverse.

On the name

The package is @luan-afonso/firstmate. npm refuses the plain firstmate, and an org named firstmate, as too similar to first-mate — an unrelated TextMate package. The command is still firstmate:

npm install -g @luan-afonso/firstmate
firstmate add notes ~/plugins/notes
firstmate start

Node 24 or newer. MIT.