Agents as system /devices

What if we could interact with our agents using /dev?

What if we could interact with our agents like we do standard linux device drivers?

Today we use somewhat opaque APIs and inspecting agent-traffic takes some time, effort, and SSL interception (which is generally a good thing). It makes sense that we are where we are right now - it wouldn't have made sense for the first chat CLIs to be their own /devices or /procs when they first came out a few years ago.

But now that they've definitely found product market fit, I think this could make a lot more sense. This is here to stay, and some of the coolest new things happen when we can experiment and tinker freely.

comic.png

Some things we could do:

what is the agent thinking?

tee -a thinking.log < /dev/agents/claude1/thinking

streaming chain of thought, live, into a second watchdog/critic while watching it on stdout

tee /dev/agents/codex1/io < /dev/agents/claude1/thinking

But even bigger: agents could introspect and see what other agents are thinking/doing.

We could also use standard linux filesystem permissions to decide who can see what.

I built devtee.com with the goal of logging what MMA (me and my agents) are doing/thinking.

Also, as we move away from the prompt-response model for interacting with agents (to things like continuous conversation, see what Thinking Machines are doing), a /dev approach could be beneficial, since agents could get a continual read on what we're doing.

This could go in a lot of interesting directions -- for example, let's say we wanted to prompt an LLM and we wanted it to see our reaction as it responded - we could pipe /dev/webcam | process-emotion-from-stream > /dev/agent/input/emotion0.

Treating agent streams as linux device drivers would:

  1. give the end user more control and visibility into what their agents are doing, without necessarily sacrificing the user experience.
  2. create a lot of interesting opportunities for making new things, and finding better ways for us to interact with our agents.

How could we try this?

Proof-of-possible solution:

MITM-proxy, intercept SSL, and then re-run the network request. Should be possible as I assume traffic is encrypted with system SSL certs, so anything is possible given you have keychain access to your own system.

Scoping v0

The goal of v0 is to get the core Unix workflows (tee, tail -f, cat, echo, chmod) working against real agents we already use today—without writing a kernel module or requiring a custom SDK.

1. Userspace filesystem, not a kernel driver

Writing a real character device driver (.ko on Linux, DriverKit/kext on macOS) is unnecessary friction for v0:

  • Linux: an unprivileged libfuse3 daemon (devagentsd) mounted at /dev/agents (or /run/user/$UID/agents symlinked in).
  • macOS: /dev is managed by devfs and macFUSE requires a kernel extension, so devagentsd can expose a local loopback NFSv3 server (the same zero-kext trick Lima and OrbStack use) mounted at ~/dev/agents or /Volumes/agents.

Every file is plain UTF-8 text so standard tools (grep, sed, awk, jq, tee) work without bespoke parsers.

2. Ground-truth capture via local MITM proxy

Wrapper commands (ANTHROPIC_BASE_URL=...) only see processes you remember to wrap—they miss desktop IDEs, background subagents, Electron apps, and silent side-channel calls (title generation, telemetry, repo indexing).

  1. Intercept localhost <> LLM API traffic directly (mitmproxy + local CA): trusting a local root CA in your system keychain (and NODE_EXTRA_CA_CERTS / SSL_CERT_FILE for runtimes with bundled CAs) lets devagentsd transparently inspect every HTTPS connection to api.anthropic.com, api.openai.com, generativelanguage.googleapis.com, etc. Any agent running anywhere on your machine automatically materializes in ~/dev/agents/ the moment it opens a request—and devagentsd demultiplexes its SSE chunks (reasoning tokens, tool calls, text) into live files in real time.
  2. Spawn a bare stream agent: mkdir ~/dev/agents/claude1 creates a headless session backed directly by devagentsd, ready to take prompts over io.

3. Minimal directory layout

One directory per live agent, six files:

agents/
  claude1/
    ctl        # write-only: pause, resume, cancel, model <id>
    io         # read/write: write a prompt, read streamed assistant text
    thinking   # read-only FIFO/stream: live chain-of-thought tokens
    trace      # read-only append log: tool calls, file opens, outbound requests
    context    # read-only snapshot of the current context window (JSONL or chat.xml)
    status     # read-only one-liner: idle | streaming | tool_call | paused

Read semantics matter:

  • thinking and io behave like character streams (blocking read() until end-of-turn EOF, or continuous with tail -f), so tee ~/dev/agents/codex1/io < ~/dev/agents/claude1/thinking works naturally.
  • context and status behave like /proc/<pid>/status: opening and reading them synthesizes a point-in-time snapshot (wc -c, diff, chat.xml).
  • ctl accepts newline-terminated commands (echo "pause" > ~/dev/agents/claude1/ctl holds the next outbound API turn at the proxy until resume or cancel).

4. Permissions & multi-agent introspection

Standard POSIX mode bits on each file (chmod, chown, groups) map directly to enforced access rules in devagentsd:

  • chmod 640 claude1/thinking lets a critic/watchdog agent in the same group read claude1's reasoning stream, while chmod 600 claude1/ctl ensures only your user (or a designated supervisor UID) can pause or steer it.
  • Cross-agent loops are just shell pipelines—no orchestration framework required:
# critic watches worker's thinking and pauses it if it loops
tee >(grep -q "wait, actually" && echo "pause" > ~/dev/agents/claude1/ctl) \
  < ~/dev/agents/claude1/thinking

5. Explicit non-goals for v0

  • No kernel modules or root daemons (except optional mount helpers).
  • No binary ioctl framing—plain text commands on ctl (Plan 9 style) beat C structs.
  • Defer full filesystem sandboxing (mounts) to v0.1—start by tracing network and tool activity across intercepted sessions (trace) and pausing on ctl, then layer Linux mount namespaces (bwrap/unshare) and macOS sandbox-exec on top once the stream primitives feel right.

some v0 open questions

  • how do we want to name the streams?
    • guessing APIs use UUIDs for conversations?
    • /dev/agents/claude/<uuid>, /dev/agents/claude-<uuid>, something else? Thinking about how filesystems are mounted by uuid.
  • How could we intercept and redirect network traffic?
  • comparing ~/.agent and what we're seeing in wiredumps

Also, we could build atop. This would also make it much easier to measure how much time your agents are spending waiting on you.

Get new posts by email

Get an email whenever I publish a new post.

© 2026 Omar Bohsali. RSS | @omarish