# Anurag Dhungana > I believe in doing hard things, shipping fast, and learning obsessively. This is my corner of the internet where I share what I'm building and learning. Personal website and portfolio at anuragd.me. Profile details and content are served from api.anuragd.me. ## Projects ### SplitSimple Easy expense splitting web app that helps divide bills among friends, colleagues, or groups with an intuitive interface. **Status:** In Progress | **Link:** https://github.com/aarekaz/splitsimple | **Tech:** Next.js, React, TypeScript ### Dispatch Self-hostable control plane for running deployable agents, with isolated sandboxes, chat, tool traces, channels, files, and scheduled runs. **Status:** In Progress | **Link:** https://github.com/Aarekaz/dispatch | **Tech:** Next.js, Convex, OpenCode, Daytona, Composio ### Shrimp Open source agent harness — pluggable memory, sub-agents, browser control, and 1000+ app integrations. The model is the brain, Shrimp is the body. **Status:** In Progress | **Link:** https://github.com/Aarekaz/shrimp | **Tech:** TypeScript, Bun, ReAct, Agent Framework, Composio ### SwitchBoard Write one AI bot and run it across Slack, Teams, Google Chat, and Discord without rebuilding the same integration four times. **Status:** In Progress | **Link:** https://github.com/Aarekaz/switchboard | **Tech:** TypeScript ### Metro MCP Model Context Protocol server for real-time transit information across DC Metro and NYC Subway systems. Built on Cloudflare Workers with OAuth 2.1 authentication. Used by about 2K+ people daily **Status:** Live | **Link:** https://github.com/Aarekaz/metro-mcp | **Tech:** TypeScript, Cloudflare Workers, MCP, OAuth 2.1, WMATA API, MTA GTFS ### Personal API Personal API to manage my website, personal content and all personal digital database **Status:** In Progress | **Link:** https://github.com/Aarekaz/api | **Tech:** TypeScript, Cloudflare Workers, Cloudflare D1 DB, Cloudflare R2 Object Storage ### Session Base Capture, organize, and share sessions across coding agent platforms, helping you and your dev team preserve valuable context. **Status:** Live | **Link:** https://github.com/sessionbase/cli | **Tech:** Typescript, AWS, CLI, TUI, MCP Server ### SEAS Search Knowledge graph-based course QA system that fine-tunes Llama 3.1 with Graph-RAG to answer questions about GWU SEAS courses, schedules, and prerequisites. **Status:** Live | **Link:** https://github.com/itsmepraks/SEAS_Search | **Tech:** LLM, Knowledge Graph, Llama 3.1, Graph-RAG ### Varonatica Browser-based virtual world with real-time multiplayer interaction, avatar customization, and social spaces. Modern take on classic virtual worlds. **Status:** In Progress | **Link:** https://github.com/aarekaz/varonatica | **Tech:** WebSocket, Real-time, Isometric 3D ### Termweather npm install -g termweather Beautiful weather in your terminal - CLI commands + interactive TUI dashboard + Website. Features one-shot weather queries, forecasts, and location search with multiple output formats. **Status:** Live | **Link:** https://github.com/Aarekaz/termweather | **Tech:** TypeScript, Node.js, React, Ink, Turbo, Commander, Open-Meteo API ### FlowWrite Minimal distraction-free writing app with timer, word count, and theme options. Fully local for complete privacy. **Status:** Live | **Link:** https://github.com/aarekaz/flowwrite | **Tech:** Next.js, React, Local Storage ### Minesweeper Classic minesweeper game built entirely by a cloud background agent in just 2 prompts. Experiment to see how much can be pushed to AI agents. **Status:** Live | **Link:** https://github.com/Aarekaz/minesweeper_game | **Tech:** AI-Generated, Cloud Agent, React ### Runwayr Headcount scenario planner with a board-ready runway tool and a casino mode for seeing how fast a hiring plan can kill your startup. **Status:** Archived | **Link:** https://github.com/aarekaz/runwayr | **Tech:** TypeScript ### Tembo Discord bot A production-ready Discord bot built on Cloudflare Workers that integrates with Tembo to manage tasks directly from Discord using slash commands. Made by Anurag Dhungana and Dominik Koch **Status:** Live | **Link:** https://github.com/mezotv/tembo-discord-bot | **Tech:** TypeScript, Cloudflare Workers, DiscordJS ### Ivy Wallet Free, open-source Android money manager for tracking balances, spending, and financial goals without falling back to a spreadsheet. **Status:** Archived | **Link:** https://github.com/Ivy-Apps/ivy-wallet | **Tech:** Next.js, Open Source ## Blog ### From an empty file **Date:** 2026-09-27T15:25:51Z | Extracted from Apple’s empty file icon. *Source: https://www.anuragd.me/blog/from-an-empty-file.md* Here's to the crazy ones. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They're not fond of rules. They have no respect for the status quo. You can praise them, disagree with them, quote them, disbelieve them, glorify or vilify them. About the only thing you can't do is ignore them. Because they change things. They invent. They imagine. They heal. They explore. They create. They inspire. They push the human race forward. Maybe they have to be crazy. How else can you stare at an empty canvas and see a work of art? Or sit in silence and hear a song that's never been written? Or gaze at a red planet and see a laboratory on wheels? We make tools for these kinds of people. *This was extracted from Apple's empty file icon.* --- ### Harness engineering **Date:** 2026-06-02T04:20:50.000Z | Harness engineering is the work of turning models into systems you can operate, inspect, and trust: tools, memory, permissions, feedback loops, and stopping conditions. *Source: https://www.anuragd.me/blog/agent-harnesses-explained.md* My understanding from building agent infrastructure: how models become systems you can operate, inspect, and trust. The first useful thing I learned about agents was that the model was not the part I kept fixing. The model was usually good enough to try the next step. It could read the error. It could explain the file. It could call the tool. It could make a plausible plan. The failures came from everything around it. The agent lost track of what it had already done. It trusted stale memory. It called the wrong tool because every tool looked equally available. It kept going after a failure it should have surfaced. It stopped because it had produced an answer, not because the task was actually done. That is when the word "agent" starts to feel too vague. Sometimes people mean a chatbot with tools. Sometimes they mean a coding assistant. Sometimes they mean a workflow with a model call inside it. The word has been stretched enough that I think it needs a cleaner frame. The frame I keep coming back to is simple: The model is the brain. The harness is the body. The model reasons. The harness lets that reasoning touch the world. That distinction changes where you look when an agent fails. The answer is not always "use a better model" or "write a better prompt." A lot of the time the answer is: the harness did not give the model the right state, tools, memory, feedback, visibility, or stopping condition. That is the part I keep running into in my own projects. [Shrimp](https://github.com/Aarekaz/shrimp) is a harness around an LLM. [Dispatch](https://github.com/Aarekaz/dispatch) is a control plane for deployable agents. [Switchboard](https://github.com/Aarekaz/switchboard) is a harness around chat platforms. [Metro MCP](https://github.com/Aarekaz/metro-mcp) is an MCP server that taught me how much agent tools depend on schemas, permissions, transport, and client behavior. Different names. Same pressure. The interesting part is usually not the model, the API call, or the first happy-path demo. The interesting part is the harness around it. ![The model is the brain. The harness is the body.](https://media.anuragd.me/blog/71ac98b0-4c4c-474a-9a62-e59391c5a3d5.webp) ## Prompting gets you started The first layer is prompting. You tell the model what you want: write this email, summarize this file, fix this bug, return JSON, use this tone. For small tasks, that works. The instruction is clear, the context fits in the prompt, and the answer comes back in one shot. The problem starts when the task stops being one shot. Real work has steps. The model needs to inspect files, choose tools, compare results, remember what happened earlier, and sometimes ask before doing something risky. At that point, the prompt still matters, but it is not the system. It is just one input. ## Context helps, until it becomes the problem The next layer is context engineering. Instead of hoping the model guesses correctly, you give it the right material: docs, files, prior messages, tool outputs, user preferences, examples, constraints. This is a big jump. A plain prompt with the right context usually beats a clever prompt with no context. But then a new problem shows up. Something has to decide what context gets loaded. Should the agent read the README or the test file? Should it search memory or inspect the current diff? Should it trust an old note or re-check the code? Should it keep going after a tool error or stop and ask? Those decisions do not live in the prompt. They live in the harness. This is one of the things I learned building Metro MCP. The useful part was not just exposing transit data as a tool. It was making the tool legible to agents: what inputs were valid, what the output meant, how OAuth worked, which transport the client expected, and what failure looked like. Once the right context was in the room, the agent got more useful. Not because the prompt was magical. Because the harness found the evidence. ![Context management as an aquarium filter: signal stays visible, old output gets filtered out.](https://media.anuragd.me/blog/de573810-7f6a-4237-85c6-8b9ef8b1be24.webp) ## The harness is the loop Most agents have a loop somewhere inside them. ![The agent loop is small; reliability comes from the rails around it.](https://media.anuragd.me/blog/08976436-29b5-4b45-a743-ac1558438c24.webp) Look at the task. Pick the next action. Call a tool. Read the result. Update state. Decide whether to continue. That loop is easy to draw and annoying to build. What tools are available? What do their inputs look like? What happens when one fails? Which actions can run automatically? Which ones need approval? Where does memory live? How does the user see progress? What counts as done? If you do not answer those questions, the model has to improvise. Sometimes that works. Often it produces the familiar agent failure mode: a confident loop of half-correct actions that looks busy but never actually lands the task. [Shrimp](https://github.com/Aarekaz/shrimp) came from running into this over and over. I kept building agents where the model was not the hard part. The hard part was everything around it: the ReAct loop, event bus, capability registry, approval gate, dashboard, memory, subagents, browser control, and app integrations. Once that was clear, Shrimp became the obvious shape: keep the model swappable, keep the capabilities pluggable, and make the core loop visible. The model thinks. The harness lets it act. ## Some harnesses become control planes [Dispatch](https://github.com/Aarekaz/dispatch) is the same lesson at a larger scale. It is not just a chat box pointed at a model. The useful part is the operating surface around the agent: create an agent, provision a Daytona sandbox, write its runtime config, start OpenCode, stream tool calls back to the UI, persist sessions and runs in Convex, connect channels, and run scheduled automations. That is a lot of plumbing for one sentence: "talk to an agent." But that plumbing is the point. If the sandbox is cold, something has to wake it. If OpenCode is stale, something has to rebuild it. If a tool call streams in a weird shape, something has to normalize it. If a run fails, something has to store the error in a way a human can inspect later. If the same agent talks in the web app, Slack, Telegram, and a cron job, something has to make those surfaces share the same execution path. This is where "agent infrastructure" stops being abstract. A model call becomes a system when you can operate it. You can see the session. You can see the run. You can see the tool events. You can see the failure category. You can restart the sandbox. You can change the permissions. You can ask why something happened without digging through vibes. That is what I mean by harness engineering. ## Some harnesses are built for one task Not every harness has to be a full product runtime. Some harnesses are dynamic. They exist for one hard task, then disappear. This is what clicked for me in the recent Claude Code dynamic workflows writing. A workflow can be a temporary harness: a small JavaScript coordinator that spawns subagents, gives each one a narrow job, waits for results, verifies them, and loops until a stop condition is met. That matters because some tasks need shape more than they need another paragraph of instruction. If a flaky test fails once every 50 runs, one agent in one context window may chase its first theory too hard. A workflow can spawn independent hypothesis agents, run them in worktrees, and then ask verifier agents to attack each theory. If a draft needs every technical claim checked, one agent can miss claims or trust its own answer. A workflow can extract claims, assign each claim to a checker, ask another agent to inspect source quality, and only then revise the draft. If you need to rank 100 support tickets, one prompt will blur. A workflow can bucket, compare, dedupe, and merge. The useful patterns are not complicated: - classify and route - fan out and synthesize - generate and filter - make agents compete - verify adversarially - loop until done The point is not "more agents." The point is that the harness can change the shape of the work. ## What the body is made of A harness is not one magic component. It is a pile of ordinary things that work together: - local instructions like `AGENTS.md` or `CLAUDE.md` - progress files - task templates - tool schemas - permission gates - memory stores - eval scripts - browser or runtime feedback - logs and traces - stop conditions That list looks boring. That is why it works. The model does not need a mystical environment. It needs a legible one. A bad harness gives the model a giant prompt, exposes every tool, hides state in conversation history, skips verification, and returns only a final answer. A better harness gives the model grounded context, scoped tools, durable state, feedback loops, and a visible trace. Prompting tells the model what to do. Context tells the model where it is. The harness decides what the model can do, what it can see, how it checks itself, and when it must stop. ## The environment has to be legible A good harness does not just give agents tools. It makes the environment legible. That word matters. If the agent cannot see a fact while it is working, that fact does not exist. A Slack thread, a Google Doc, a design decision in someone's head, a random note from last week: all of that may be true, but the agent cannot use it unless the harness exposes it in a form the agent can inspect. This is why repo-local instructions matter. An `AGENTS.md` file is not an encyclopedia. It is more like a map. It tells the agent where the important things live, what conventions matter, and what to check before acting. The deeper knowledge still lives in the repo: code, tests, docs, plans, references, quality notes, commit history, and checks the agent can actually run. That matches what I have been learning in my own systems. [Metro MCP](https://github.com/Aarekaz/metro-mcp) works better when tool schemas, auth behavior, and transport contracts are explicit. [Shrimp](https://github.com/Aarekaz/shrimp) works better when tool calls, events, and approvals are visible instead of hidden inside a final answer. [Dispatch](https://github.com/Aarekaz/dispatch) works because agents are not only conversations; they are sandboxes, sessions, runs, messages, memory files, channel bindings, automations, and failure states. The harness turns hidden work into something the agent can read. ![Hidden work becomes a system of record the agent can read and update.](https://media.anuragd.me/blog/38a42ed0-936e-4004-9eee-931f582d7765.webp) ## Tools need contracts It is tempting to think of tools as simple functions. ![Tools need contracts and permission levels: auto, ask, and block.](https://media.anuragd.me/blog/a47d6a20-b5be-474b-9f5a-1e69c2491507.webp) The model calls `read_file`, `search_web`, `send_email`, `run_tests`, whatever. Function in, result out. That is too loose. For an agent, a tool needs a contract. The model needs to know what the tool does, what inputs are valid, what the output means, and what failure looks like. More importantly, the harness needs to know what kind of action this is. Reading a file and sending an email are not the same category of thing. Searching docs and deleting data are not the same category of thing. So the harness needs permission levels. Some tools can just run. Some should run but notify the user. Some should ask first. Some should not exist in that environment at all. [Dispatch](https://github.com/Aarekaz/dispatch) made this feel less theoretical. An agent can have conservative, balanced, or permissive tool permissions. It can have Composio toolkits scoped to that agent. It can have Slack or Telegram bindings. It can have a runtime config generated from its model, persona, tools, memory, and channel context. Those are not prompt details. They are contracts. The model should not have to guess which tools exist, which ones are safe, or what a tool result means. The product layer should know that before the model starts acting. [Coop](https://github.com/Aarekaz/coop) still matters here as a smaller version of the same idea: if an agent definition has no schema, no validator, no warnings for lossy export, and no stable source of truth, you do not have an agent definition. You have a screenshot of some settings somewhere. The harness makes the contract visible. ## Planning and execution are different jobs One of the easiest ways to make an agent worse is to ask it to plan, build, judge, and summarize in one continuous blur. It will do it. That does not mean the shape is good. Planning and execution benefit from separation. Before the model starts changing things, the harness can force a plan into a concrete shape: - real file paths - real symbols - existing patterns - acceptance criteria - verification steps - known risks That does not have to be a heavyweight spec. It can be a small impact map. The point is to stop the agent from hallucinating the environment before it acts inside it. This also explains why planner/generator/evaluator setups work better than they sound. The planner turns the request into a grounded task. The generator implements one slice. The evaluator checks the result like a skeptical user. The same model may play each role. The harness keeps the roles from collapsing into each other. ## Adapters keep the mess out of your head [Switchboard](https://github.com/Aarekaz/switchboard) taught me the same lesson in a less agent-shaped place. Discord, Slack, and Telegram all have messages. They all have replies. They all have events. They all have annoying little differences that leak into your code if you let them. Switchboard is a harness around those platforms. One Bot API on top, adapters underneath. Your handler should not care whether the message came from Discord or Slack. It should care about the user, the message, the reply, and the conversation. The rest belongs in the adapter layer. This is the part I keep accidentally caring about. Where does the messy outside world end? Where does the clean interface begin? That boundary is usually the product. ## The pattern underneath [Shrimp](https://github.com/Aarekaz/shrimp), [Dispatch](https://github.com/Aarekaz/dispatch), [Switchboard](https://github.com/Aarekaz/switchboard), and [Metro MCP](https://github.com/Aarekaz/metro-mcp) are not the same project. But they rhyme. Each one sits around a messy capability and gives it structure. [Shrimp](https://github.com/Aarekaz/shrimp) sits around an LLM and gives it tools, memory, approvals, and visibility. [Dispatch](https://github.com/Aarekaz/dispatch) sits around deployable agents and gives them sandboxes, sessions, state, channels, automations, and an operator-facing control plane. [Switchboard](https://github.com/Aarekaz/switchboard) sits around chat platforms and gives them one API. [Metro MCP](https://github.com/Aarekaz/metro-mcp) sits around public transit systems and gives agents a cleaner way to ask for live context through MCP tools. The repeated lesson is simple: The hard part is rarely making something happen once. The hard part is making the shape around it stable enough that you can keep using it. That means interfaces. It means normalization. It means logs. It means explicit failure states. It means approvals. It means boring names for things that would otherwise stay fuzzy. It means knowing what is inside the core and what is an adapter. That last one matters a lot. If everything is core, the system becomes fragile. If everything is a plugin, the system has no opinion. Harness engineering is deciding where the boundary goes. ## Memory is not a bigger prompt Memory gets hand-waved a lot. People talk about it like you can stuff more text into the context window and call it a day. That works for demos. It breaks fast in real use. An agent has different kinds of memory. There is the short-term state of the current task. There are long-term facts about the user. There is project memory: how this repo works, what commands are safe, what past decisions matter. There is procedural memory: the way the agent learned to do a kind of work. The harness decides where those memories live and when they get pulled back in. It also has to treat memory with suspicion. Old memory can be stale. Summaries can flatten the important detail. A preference can be true in one project and wrong in another. If the agent cannot tell where a memory came from or when it was last checked, it will eventually make a confident mistake. Good memory needs provenance. Bad memory is worse than no memory. [Dispatch](https://github.com/Aarekaz/dispatch) forced this distinction for me. OpenCode and the Daytona volume are good places for runtime memory: session history, workspace files, config, and the agent's own notes. Convex is better for product memory: agent records, runs, sessions, messages, channel bindings, automation status, failures, credits, and things the UI needs to inspect. Those are different jobs. If you collapse them into one blob, the product cannot operate the agent and the agent cannot reason cleanly about its own work. [Metro MCP](https://github.com/Aarekaz/metro-mcp) taught me a version of this through tools rather than notes. A tool result is memory for the next turn, even if it only lives in the context window for a few minutes. If the output has no provenance, no timestamp, no station identity, or no clue about whether the data came from WMATA or MTA, the agent will eventually sound more certain than it should. If there are two sources of truth, there is no source of truth. So the boring details matter: typed inputs, normalized station names, explicit provider boundaries, and errors that tell the model what failed instead of forcing it to guess. ## Observability is not optional If an agent does ten steps and only shows you the final answer, you do not know what happened. Maybe it read the right file. Maybe it skipped the only file that mattered. Maybe a tool failed and it guessed. Maybe it got lucky. For toy tasks, that might be fine. For real work, it is not. A good harness shows the path: tool calls, outputs, errors, approvals, retries, and changes in direction. Not because logs are pretty. Because inspection is how trust gets built. You cannot trust an agent you cannot audit. This is another place where the recent harness writing was useful. A serious coding agent is not just a chat box pointed at a repo. It can observe the app, read logs, run checks, inspect screenshots, make a change, and loop. That is different from pasting errors into a chat. It means the agent can observe the system directly. That is harness engineering. Not a better prompt. A better feedback loop. Addy's "Orchestration Tax" article describes the human side of the same problem. Starting more agents is cheap. Closing the loop on their work is not. If every agent output routes straight into your brain, you become the single-threaded bottleneck. A useful harness does not remove judgement. It protects it. It makes the agent prove the boring parts first: tests, screenshots, traces, structured diffs, reproducible steps. Then your attention goes to the part that actually needs a human. ![Without a harness, more agents dump work onto the human bottleneck. With a harness, routine evidence is filtered first.](https://media.anuragd.me/blog/62001856-cf02-4755-b50f-16f9d03ce0eb.webp) ## Verification needs a separate path The most dangerous version of an agent is one that can act but cannot check. ![Separate the doer from the judge: one agent builds, another verifies with tests and screenshots.](https://media.anuragd.me/blog/01557560-c0ca-4f84-ac58-6817e2207471.webp) It will produce work. It will also produce explanations for why the work is fine. That is not enough. A harness needs feedback paths the model does not get to hand-wave away: - tests - type checks - linters - screenshots - runtime logs - comparison agents - human approval gates - explicit acceptance criteria Some feedback is computational. A test passes or it fails. A type checker returns errors or it does not. Some feedback is inferential. A reviewer agent checks whether the UI matches the request. A human decides whether the tone works. A browser screenshot reveals that the button technically exists but looks wrong. You need both. This is where separating the doer from the judge matters. A generator is usually generous about its own output. A standalone evaluator can be skeptical. The harness should make skepticism cheap. ## One thing at a time is a system feature Agents get worse when the task gets too wide. ![One thing at a time: progress, build, verify, commit.](https://media.anuragd.me/blog/e7bc95a7-a28a-40a5-85e8-19ceb20c1d53.webp) They run out of context. They silently drop requirements. They make one good change and three unnecessary ones. They forget to verify the thing the user actually asked for. The fix is not only "be more careful." The fix is often a harness rule: Read progress. Pick one failing feature. Implement it. Verify it. Commit it. Update progress. Repeat. That sounds basic, but it changes the work. The agent no longer has to keep the entire project in its head. The progress file holds the queue. The repo holds the state. The tests hold the acceptance criteria. The commit boundary gives each slice a place to land. One thing at a time is not a motivational slogan. It is infrastructure. ## Stopping is part of the system One of the least glamorous parts of agents is stopping. When is the task done? When should the agent retry? When should it ask for help? When should it give up? If the harness does not define this, the model guesses. That is how you get agents that keep searching after they already found the answer, keep editing after the fix is done, or declare success because they produced a plausible final message. The harness can make the boundary explicit. Maybe tests have to pass. Maybe a screenshot has to be generated. Maybe a destructive action needs approval. Maybe the agent must produce a specific artifact before it can say it is finished. The model still reasons. The harness decides what "done" means. ## Harnesses need garbage collection Agent systems produce stuff quickly. Some of it is good. Some of it is weird. Some of it is locally fine but creates long-term drift. If you do not build cleanup into the harness, the system slowly teaches future agents the wrong patterns. You need recurring cleanup, mechanical checks, and a way to turn human taste into rules the agent can keep applying. Otherwise the harness gets heavier every week. This is also where "build to delete" matters. ![Build to delete: test harness components for quality, cost, and time, then remove what stops helping.](https://media.anuragd.me/blog/c7796c74-a496-43cb-a405-5fb0c36816a9.webp) Every harness component encodes a belief about what the model cannot do yet. A planning gate says the model is not reliable enough to plan and execute in one pass. A verifier says the generator is not reliable enough to judge itself. A detailed tool description says the model needs that guidance to use the tool correctly. Those beliefs can expire. As models improve, some harness components stop earning their keep. A rule that prevented mistakes in March can become token overhead in June. A complex workflow can become slower than a simpler one. A tool list can grow until the model performs worse because it sees too many options. Good harness engineering is not adding scaffolding forever. It is adding constraints, measuring whether they help, and deleting the ones that stop paying rent. ## Same brain, different body This is why two products using the same model can feel completely different. One feels chaotic. Another feels reliable. The difference is usually not the model. It is the body around the model. The prompt matters. Context matters. The model matters too. But the agent experience is the whole thing: tools, memory, approvals, state, logs, UI, evals, and stop conditions. That is the harness. And once you see it, a lot of agent work starts to look different. The question is not only: Which model are you using? The better question is: What have you built around it? Because that is where most of the product lives. For a while, I would have called this agent engineering, dev tools, or workflow automation, depending on the project. Those labels are still true. But they miss the thing I keep caring about. I care about the shape around the intelligence. I care about the layer that turns a powerful but slippery capability into something you can operate, inspect, move, and trust. That is why I keep building runtimes, formats, adapters, queues, ledgers, approval gates, and validators. The model is easy to point at. The API is easy to demo. The first version is easy to believe in. The harness is what survives contact with actual use. ## Sources I found useful - Caleb Writes Code, ["Agent Harness explained in 8min.."](https://www.youtube.com/watch?v=1a1VXDdIyrk) - OpenAI, ["Harness engineering: leveraging Codex in an agent-first world"](https://openai.com/index/harness-engineering/) - Zhong and Zhu, ["AI Harness Engineering: A Runtime Substrate for Foundation-Model Software Agents"](https://arxiv.org/abs/2605.13357) - Thariq Shihipar and Sid Bidasaria, ["A harness for every task: dynamic workflows in Claude Code"](https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code) - Akshay Pachaar, ["The Anatomy of an Agent Harness"](https://www.langchain.com/blog/the-anatomy-of-an-agent-harness) - Rahul, ["Harness Engineering: What Every AI Engineer Needs to Know in 2026"](https://x.com/sairahul1/article/2063544956158185927) --- ### the brain is easy. the body is hard. **Date:** 2026-04-24T16:02:15.031Z | draft, notes on building agents *Source: https://www.anuragd.me/blog/the-brain-is-easy-the-body-is-hard.md* # The model is easy. The body is hard. I used to think most of the pain in agent systems would come from prompts. Not all of it, obviously. But enough of it that if I got the prompting right, the rest would feel manageable. Building Shrimp cured me of that pretty quickly. [Shrimp](https://github.com/aarekaz/shrimp) is an open-source agent harness I started pulling together after I got tired of rewriting the same glue around different models. I did not set out to make some grand statement about agents. I mostly wanted a runtime that could survive contact with real I/O: tool calls, approvals, sessions, memory, browser control, and all the awkward wiring that starts to matter the second a model has to do anything outside a text box. That changed how I think about where the hard part actually lives. The model is the easy part. Or at least, it is easier than the body around it. The body is everything that has to hold together once the model leaves the sandbox. Tool execution. Session state. Approval flows. Error handling. Eventing. Memory. Cost tracking. The unglamorous stuff that determines whether the system is usable, debuggable, and safe after the demo energy wears off. I kept running into the same pattern: the model call itself was rarely the thing making my life miserable. What hurt was the runtime around it getting tangled. ## The first shift: make the loop observable My first versions of the agent loop were heading in a familiar direction. Everything wanted to know what the agent was doing, so everything got wired into the loop itself. Logging lived there. Approvals lived there. Dashboard updates lived there. Cost tracking lived there. Session persistence lived there. The result was predictable. The loop got bigger and more fragile. A feature that should have felt adjacent started feeling invasive because adding anything new meant touching the one place that already felt overloaded. The fix was not especially glamorous. I turned the loop into something that emitted events. That sounds like a small implementation detail. For me it changed the entire shape of the system. Once the loop became observable, it stopped needing to know who was listening. The dashboard could subscribe. Session persistence could subscribe. Cost tracking could subscribe. Future features could subscribe without turning `loop.ts` into a landfill. That separation matters more than people give it credit for. There is also a subtler effect: an observable loop is psychologically easier to work on. When I can see what the system is doing and attach features around it instead of inside it, I stop treating the core loop like a bomb I should not touch. That matters if you want the project to survive beyond the first few clever demos. One thing I learned the hard way: observability is only real if observers can fail in isolation. If one bad subscriber can crash the loop, your event system is decorative. That sounds mechanical, but it is load-bearing. A dashboard bug should not take down the agent. Neither should a persistence bug or a cost meter bug. ## The second shift: memory should include methods, not just facts Most conversations about memory in agent systems focus on facts. Facts about the user. Facts from documents. Facts from prior sessions. That stuff matters. I am not arguing against it. But building Shrimp pushed me toward a different kind of memory that I think is under-discussed: memory the system writes about its own behavior. The version I have right now is simple. Honestly, embarrassingly simple. If the agent finishes something that involved a multi-step tool sequence, it can write down the rough procedure it used. Not the final answer. The method. Something like: "Last time you asked me something like this, I used these tools in this order." That sounds obvious once you say it plainly, but it felt different when I saw it happen in practice. The useful thing was not that the system remembered a fact I had fed it. The useful thing was that the harness remembered a pattern it had generated itself. That is a different class of help. It is also closer to how a good runtime should compound. Not by pretending the model got smarter overnight, but by making the surrounding system less likely to flail the next time it sees a familiar shape. The current implementation is still rough. The matching is dumb. Retrieval can be noisy. There has to be a way to forget bad procedures or you just create a self-poisoning memory system. But even the crude version changed how I think about where leverage lives. People spend a lot of time asking how smart the brain is. I am more interested in how much the body can learn from its own behavior. ## This also changes how I think about “harness thickness” A lot of agent-framework discussion reduces to a familiar choice: - keep the harness thin and trust the model - put more explicit logic into the harness That framing is useful, but it misses a third shape I keep seeing in practice. If the runtime is observable and can accumulate procedural memory, you do not have to decide all of the thickness up front. You can keep the core loop relatively small. You can add surrounding behavior through subscriptions instead of invasive rewrites. You can let repeated work teach the system something about method. The system still gets more capable, but not because you stuffed every possible rule into the loop on day one. That feels like a healthier direction to me than either extreme. ## What I wish I had internalized earlier I would have spent less time obsessing over prompts and more time cleaning up the runtime. I would have added an event bus earlier. I would have treated failure isolation as a core requirement instead of something to patch in once the dashboard or memory layer broke. And I would have taken procedural memory more seriously sooner, even in its dumb form. Not because the current implementation is magic. It is not. But because it points at something that feels more durable than the usual cycle of prompt tweaks and framework debates. The interesting question for me is no longer just "how smart is the model?" It is: What kind of body have you built around it? Because that body determines whether the agent is just impressive in a screenshot, or useful once it has to live in the world. --- ### tinkering **Date:** 2026-01-22T05:38:38.885Z | Today is a great day to build *Source: https://www.anuragd.me/blog/tikering.md* Today is a great day to build That's what I tell myself almost every morning. Not in some motivational-poster kind of way, but because it's true. Most general advice is that you need a plan. A roadmap. A clear business case. I tried a lot to do that, but I realized that I've never worked that way. My process is simple: I run into something annoying, I wonder if I can fix it, and then I disappear for a few days (or weeks) trying to figure it out. Sometimes it works. Sometimes it doesn't. Either way, I learn something. Take Metro MCP. I didn't wake up thinking "I need to build an MCP server for transit data." I woke up thinking "Why can't I just ask my AI Agent when my train is coming? Why cant I dynamically automate it?" That question bothered me enough to figure out how to connect LLMs to real-time transit APIs. Now it's live at metro-mcp.anuragd.me, and people are actually using it. Wild. That's the pattern: personal pain point → obsessive building → something real. This is how I learn. This is how I push myself. Here's what I've figured out: the world doesn't need another person with a five-year plan and a perfectly polished resume. It needs more people who see something broken and think "I wonder if I could fix that" and then actually try. It needs people who ship messy v1s instead of perfect never-released projects. It needs tinkerers. Because tinkering isn't just about building random projects. It's about developing a bias toward action. It's about learning to trust your ability to figure things out. It's about proving to yourself that you can go from "I have no idea how to do this" to "okay, it works" through sheer persistence. That's the real skill. Not knowing everything. Not having a plan. But being willing to start anyway. --- ### Mantras **Date:** 2025-11-15 | Personal mantras and principles I live by—things I try to read every day to stay focused and grounded. *Source: https://www.anuragd.me/blog/mantras.md* These mantras have lived in my Notion for a while, but I wanted to publish them here. Inspired by [Bu Kinoshita's post on principles](https://bukinoshita.com/thoughts/on-principles), I believe sharing these helps hold me accountable and might resonate with others on a similar journey. ## Things That I Try to Read Everyday - Today is a great day to build. - To get head of 99% of the people, I will have to do what the 99% is unwilling to do. - No one is responsible for my success besides me. - I welcome the learning process with open arms. - Everyone was once a beginner. - Mastery over my craft is the highest accolade. - To unlock the upside, I must face the risk of the downside. - I need to be patiently impatient and have a bias toward action. - The enemy of long-term compounding is short-term results. - Wealth is built over decades, not days. - I have no competition, because I am only competing against myself. - The world rewards those who do what others do not. - I trust myself and my convictions. - Every failure is an opportunity to learn. - Every success is an opportunity to start again. - Forward is the only option. There is no going back. - I own my shortcomings—and leverage them to my advantage. - Dwelling on a mistake where the lesson has already been extracted is a waste of precious time. - My potential knows no limits. - Simplicity is velocity, because the simple thing is the hard thing. - It's better to move slowly in the right direction than quickly in the wrong direction. - I do not accept any obstacle in my way. - "Tomorrow" is an excuse. Do it now or don't do it at all. - I don't know how yet—but I will figure it out. - What I once wanted, I currently have. (The destination isn't what matters.) - Hours are a poor measure of effort. Intentional practice is the only thing that matters. - I will not judge my entire life based on any single day. - Better to be singular and deep than multifaceted and shallow. - Real progress is made in silence. - Life is not a zero-sum game. We can all win. - Failure doesn't mean you're worthless, it means you must look for another route to achieving worth wide goals. - Don't stop when you're tired. Stop when you're done. - True motivation arises when you immerse yourself in the flow of work, irrespective of external influences. - Study greatness. Reverse-engineer it. And make it your own. - Say what you can do, do what you say. - Don't half ass it. --- ### Go after the hardest thing **Date:** 2025-11-12 | Why we should chase the toughest challenges—not because they're easy, but because they're hard. Our duty to future generations. *Source: https://www.anuragd.me/blog/go-after-the-hardest-thing.md* JFK got it right - don't do things because they are easy, but because they are hard. We only have one shot at life, so why waste it taking the easy road? If our ancestors took the easy path, who knows where we would be right now. All I know is we wouldn't have cars, phones, or the other magnitude of inventions that we all take for granted. Something I heard recently that I'm guilty of forgetting is that everything in the world around us was built by people no smarter than us. Every building, every technology, everything we see, it wasn't there before us humans evolved on this planet. They don't just magically spawn in. Somebody had to pour their blood, sweat, and tears into making the world a better place for the people of tomorrow. I truly believe that that's a big part of why a small handful of people build the courage to attack the most difficult problems: If not us, then who? If not now, then when? Read that again. As humanity, we have a duty to face the toughest challenges head on for our fellow, future humans. To leave our planet better than how we found it. That's what it's all about, and it's so god damn inspiring. Just imagine the amount of people who came before you to give you the ability to be here, breathing, living today. The struggles, the hopes, the dreams that have lived to allow you to have the chance to leave your mark. We owe it to them to go after that thing that scares us. Just do it, try to make a dent. You will often be surprised by how far you can go. That being said, chase the hardest, most impactful problem you can find. Do it for you, do it for your fellow humans - past, present, and future. --- ### thoughts on background coding agents via Tembo **Date:** 2025-11-07 | Exploring the potential and implications of background coding agents through the lens of Tembo's approach to autonomous development. *Source: https://www.anuragd.me/blog/tembo.md* The idea of coding agents working in the background while we sleep, eat, or focus on other things is compelling. As someone who does not have a goodish [laptop](https://www.anuragd.me/uses), I am often limited by how much I can do at the same time and how long I can push LLMs and agents for. I was having instances where everything was super laggy if I had 2 or more CLI agents working on something parallel. It was brutal, and it took away so much of my productivity. Chrome tabs lagging, the CLI stuttering to load the diff. That's why I had gravitated a bit towards finding cloud based solutions. There were Codex , Claude Code and Cursor on the web. But the main issue with these for me, all of them were just one model provider, which I often don't like as I like different models for different type of dev works. Then I stumbled on [Tembo](https://app.tembo.io/sign-up?utm_source=aarekaz&utm_id=aarekaz). I had been following Benja for some while and had known he was working on Tembo. I signed up and gave it a shot. You get $50 worth of credit as soon as you join, so it was plenty for me to try this concept of cloud agents out. It was pleasantly surprising. I just prompt it as I generally do via a website and it does everything in the cloud and opens a PR in your repo. And if you have proper CI/CD setup (my goat Vercel) you automatically get a preview link of that PR. And everything happens in the background. ![My recent PRs using Tembo](/blog/tembo_tasks.png) One instance which blew my mind was, I once asked Tembo to do a complete redesign of my writing web app flowwrite, a zen like writing app where you cant delete anything. I just gave it a basic prompt and I let it go as I was in the metro returning home. It had it completely done by the time I was home. ![My flowwrite task in Tembo](/blog/flowwrite_prompt.jpg) It did a pretty awesome job. You can try it out [here](https://flowwrite.anuragd.me/). After this ordeal, I kept thinking what else I could do. Now, Tembo acts as my CMS as well, where I will just tell to add my blog post(like this) or some photos for my /photos page and it does it. It also has regular scheduled automations where it scours my linked sources via MCP and regularly updates my different projects based on a set of predefined tasks. Right now, I am experimenting with how much I can push cloud agents. I am creating a minesweeper game completely by cloud agents. You can try it [here](https://minesweeper.anuragd.me/). I plan to only do this when I cant code and plan to over engineer it with multi player setups and AI bots. Excited to see how much I can push LLMs. ![Minesweeper completely made by background agents](/blog/minesweeper_game.png) I do see the future of how many of these cloud agents are gonna surround us doing things in multiple domains for us and for that I am very excited. Of course there are some limitations, mainly it going onto a hallucination hell because its not constantly connected to the same stream that was doing the work earlier, but its already an awesome start. If you want to try Tembo out you can check them out [here](https://app.tembo.io/sign-up?utm_source=aarekaz&utm_id=aarekaz). They just had a really huge release with MCP supports, Multi agent support, and task template which I am playing around with a lot. The team is really great and is so responsive + insanely fast with responding to feedbacks and feature request. The future looks promising and is gonna unlock a lot of things for us. *Thank you so much for reading!* --- ### Working at Cheers (YC S24) **Date:** 2025-08-22 | Reflecting on my transformative summer internship at Cheers, a YC S24 company building the future of customer engagement. *Source: https://www.anuragd.me/blog/working-at-cheers.md* This August, I wrapped up my internship with [Cheers (YC S24)](https://www.cheers.tech/) during what was the most transformative summer of both myself and the company. > It's been an absolute dream come true for me to work at Cheers. [Dylan](https://www.linkedin.com/in/dylan-allen/) and [Amadeus](https://www.linkedin.com/in/amadeus-peterson/) are the embodiment of YC's motto of "Make Something that people want". From every code written to every sales or business decision, it was driven by our customers in mind. The scale and velocity at which Cheers works is unmatched, and it's been a privilege to be a part of it. I've shipped what I just a year ago would've thought was impossible. I have found the enviroment where I thrive the most. I like high pressure work, I like impactful work. I like work that feels like play where there is a lot to prove. Working at Cheers was that for me. The speed at which Cheers moves is astounding, and the work keeps you so excited to build the future. I have watched and worked on the next iteration of Cheers from its initial inception to its implementation in a span of a few weeks, with our customers in mind. Check their latest launch [here](https://www.ycombinator.com/companies/cheers). I would like to thank Dylan , Amadeus, and [Abe](https://www.linkedin.com/in/abelamo/) for their support throughout my time at Cheers. I would not be where I am without them. They continue to give me advice and support me, and I am very grateful for that. I will always be rooting for them! My intention right now is to return to school life at George Washington to finish my Master's in Computer Science. I have figured out what I want to work on and do after I graduate, but now it's about the path to reach there. I'm excited to keep building, creating, learning, and doing as much good as I can. Cheers! --- ### Hello, world — this site **Date:** 2025-01-09 | A quick note about how this website is put together and why it exists. *Source: https://www.anuragd.me/blog/hello-world.md* ## Welcome to my Web I've wanted a space that feels simple, fast, and mine. Not a landing page with a thousand widgets, just a quiet corner where I can drop projects, ideas, and things I'm learning. ## Inspirations - [Hayden Bleasel](https://www.haydenbleasel.com/) - [Sumit Kumar](https://www.sumit.ml/) - [Anthony Fu](https://antfu.me/) - [Ahmet Dedeler](https://ahmetdedeler.com/) - [Ryo Lu](https://os.ryo.lu/) ## What Makes It Different I think of work in small, sharp loops: build → ship → learn. I don't want a content pipeline that slows me down. Files in a folder are enough. The site follows a minimal, monochrome aesthetic with subtle animations and motion design. It respects `prefers-reduced-motion` and stays fast with static generation where possible. ## Living Documents I've added pages that evolve over time: - **/now** - What I'm focused on right now, with reading goals and activity tracking - **/uses** - Tools and gear I use daily - **/photography** - Photo galleries with an advanced lightbox - **/projects** - Things I've built, with live GitHub and coding activity The site itself is a project - constantly iterating on the design and adding features. If you're curious about anything specific, ping me. Otherwise, I'll keep dropping pieces here until a bigger picture forms. ## The Stack - Next.js 14 with App Router - Tailwind CSS v4 with custom motion tokens - MDX for content - shadcn/ui components --- ### flockfysh - a leap for data collection **Date:** 2023-10-11 | flockfysh was the ultimate solution to the dataset problems faced by data scientists, machine learning engineers, and researchers. *Source: https://www.anuragd.me/blog/flockfysh-a-leap-for-data-collection.md* > **Update**: This project has since shutdown, but it was a lot of fun building it! We got accepted into Z Fellows, made it to YC interviews, and learned a tremendous amount about the data science ecosystem. flockfysh was the ultimate solution to the dataset problems faced by data scientists, machine learning engineers, and researchers. ## The Problem The dataset problem is one of the biggest pain points in machine learning and data science. The process of collecting, cleaning, and preparing data for machine learning models is incredibly time-consuming and tedious. Most data scientists spend 80% of their time on data preparation and only 20% on actual analysis and modeling. This is inefficient and prevents data scientists from focusing on what they do best - extracting insights from data. ## The Solution flockfysh provided an automated data collection platform that allowed data scientists to: - **Automatically collect** relevant data from multiple sources - **Clean and preprocess** data using AI-powered tools - **Version control** datasets with Git-like functionality - **Collaborate** with team members on data projects - **Deploy** models directly from the platform ## Key Features ### Automated Data Collection Our platform could automatically scrape and collect data from websites, APIs, databases, and other sources based on user specifications. ### AI-Powered Data Cleaning We used machine learning algorithms to automatically detect and fix common data quality issues like missing values, duplicates, and outliers. ### Dataset Version Control Like Git for code, we provided version control for datasets, allowing teams to track changes, branch, and merge datasets. ### Collaborative Workspace Teams could share datasets, annotations, and models in a collaborative environment designed for data science workflows. ## The Journey Building flockfysh was an incredible learning experience. We: - **Got accepted into Z Fellows** - A highly selective fellowship program - **Made it to YC interviews** - Reached the final interview stage at Y Combinator - **Built a working product** - Created a full-featured platform with paying customers - **Learned about enterprise sales** - Discovered the complexity of selling to large organizations ## Lessons Learned 1. **Product-market fit is everything** - We built a great product but struggled to find the right market fit 2. **Enterprise sales are slow** - B2B sales cycles are much longer than we anticipated 3. **Technical execution isn't enough** - Great engineering needs to be paired with strong go-to-market strategy 4. **Team dynamics matter** - Building a startup is a marathon, not a sprint ## What's Next While flockfysh didn't achieve the scale we hoped for, the experience taught us invaluable lessons about building products, finding customers, and scaling teams. The data infrastructure space continues to evolve rapidly, and many of the problems we identified are still being solved by new companies. The journey was worth it for the learning experience alone, and I'm grateful for the opportunity to have worked on such an ambitious project with an amazing team. --- ### Fundamentally to-do lists are broken **Date:** 2023-07-23 | The leverage of people, technology, and financial assets to produce results without spending additional energy, time, or effort is the way to move forward. *Source: https://www.anuragd.me/blog/fundamentally-to-do-lists-are-broken.md* ### Why I think people are using To-Do lists wrong The leverage of people, technology, and financial assets to produce results without spending additional energy, time, or effort is the way to move forward. Traditional to-do lists focus on tasks and completion, but they miss the fundamental principle that drives real productivity: **leverage**. ## The Problem with Traditional To-Do Lists Most people approach productivity by creating endless lists of tasks. They focus on doing more, working harder, and checking off items. But this approach is fundamentally flawed because it treats all tasks as equal and doesn't consider the multiplier effect of certain activities. ## Introducing Leverage Lists Instead of asking "What do I need to do?", we should ask "What can I do that will make everything else easier or unnecessary?" Leverage comes in three forms: - **People leverage**: Building systems and teams that work without your direct involvement - **Technology leverage**: Using tools and automation to multiply your output - **Financial leverage**: Investing resources that generate returns without ongoing effort ## Building Your Leverage List 1. **Identify force multipliers**: What activities create disproportionate results? 2. **Automate repetitive tasks**: What can technology handle for you? 3. **Delegate or eliminate**: What tasks can others do better or faster? 4. **Create systems**: What processes can run without your constant input? ## Examples of Leverage Thinking ### Instead of: Managing tasks manually **Leverage approach**: Build automated workflows and templates ### Instead of: Doing everything yourself **Leverage approach**: Train team members and create standard operating procedures ### Instead of: Trading time for money **Leverage approach**: Create products, content, or investments that generate passive income ## The Leverage Mindset The shift from task completion to leverage creation is profound. It means: - Focusing on systems over individual tasks - Prioritizing activities that scale - Investing time upfront to save time later - Building assets rather than just completing work ## Practical Implementation 1. **Weekly leverage review**: Ask "What did I do this week that will make next week easier?" 2. **Automation audit**: Identify three manual processes you could automate 3. **Delegation practice**: Find tasks that others can do 80% as well as you 4. **System creation**: Document your best processes so they can be repeated ## Conclusion True productivity isn't about doing more tasks—it's about creating systems that do the work for you. When you shift from a to-do list mentality to a leverage list mentality, you stop being busy and start being effective. The goal isn't to check off more boxes; it's to create a life where the important boxes check themselves. --- ### The mountain is you **Date:** 2023-07-15 | The main purpose of this blog post is to document my thoughts and takeaways from the book by Brianna Wiest. *Source: https://www.anuragd.me/blog/the-mountain-is-you.md* *Reflections on Brianna Wiest's transformative book about self-sabotage and personal growth* The main purpose of this blog post is to document my thoughts and takeaways from the book. ## Key Insights > "The objective of being human is to grow" This simple yet profound statement encapsulates the entire human experience. We are not meant to remain static; growth is not just desirable—it's our fundamental purpose. > "Your mountain is the block between you and the life you want to live" The mountain represents our internal obstacles, the self-imposed limitations that prevent us from reaching our potential. It's not external circumstances that hold us back most often—it's ourselves. ## The Nature of Self-Sabotage Self-sabotage is often a habitual response rooted in unconscious beliefs. We create patterns that keep us in our comfort zones, even when those zones no longer serve us. The book reveals that: - Our fears often masquerade as logical reasons - Comfort zones can become prisons of our own making - We sometimes choose familiar problems over unfamiliar solutions ## Understanding Your "Why" > "Don't worry about doing it well; just do it" One of the most liberating concepts from the book is the emphasis on action over perfection. Understanding **why** you want something is more important than knowing exactly **how** to achieve it. When your why is clear: - The how becomes clearer - Obstacles become stepping stones - Motivation sustains itself ## The Power of Choice Perhaps the most empowering message is that you have the power to choose and change your path. Personal transformation requires: 1. **Self-awareness**: Recognizing your patterns and beliefs 2. **Intentional change**: Making conscious decisions to act differently 3. **Persistence**: Continuing even when progress feels slow 4. **Self-compassion**: Being patient with yourself during the process ## Personal Takeaways This book serves as a catalyst for personal growth. It challenges existing self-perceptions and encourages readers to: - Question limiting beliefs - Embrace discomfort as a sign of growth - Take responsibility for their own transformation - See obstacles as opportunities for development The mountain is not something to be feared—it's something to be climbed. And the view from the top is worth every difficult step along the way. --- ## Pages - [Home](https://www.anuragd.me/index.md): site overview, featured projects, and recent writing - [Blog index](https://www.anuragd.me/blog.md): full list of published posts with summaries - [Projects](https://www.anuragd.me/projects.md): things I've built — live, in progress, and archived - [Photography](https://www.anuragd.me/photography.md): photo gallery - [Resume](https://www.anuragd.me/resume.md): work experience, education, and skills - [Now](https://www.anuragd.me/now.md): what I'm currently focused on - [Uses](https://www.anuragd.me/uses.md): tools, software, and hardware I use daily - [Shelf](https://www.anuragd.me/shelf.md): curated books, movies, shows, quotes, links, and visuals - [Shelf — Quotes](https://www.anuragd.me/shelf/quotes.md): collected quotes - [Shelf — Links](https://www.anuragd.me/shelf/links.md): bookmarked articles and references - [Shelf — Visuals](https://www.anuragd.me/shelf/visuals.md): images and diagrams worth keeping - [Shelf — Wallpapers](https://www.anuragd.me/shelf/wallpapers.md): wallpaper collection - [Shelf — Books](https://www.anuragd.me/shelf/books.md): read, reading, and want-to-read books - [Shelf — Movies](https://www.anuragd.me/shelf/movies.md): watched films and queued movies - [Shelf — Shows](https://www.anuragd.me/shelf/shows.md): watched series and queued shows ## Intentional exceptions - /cmd: Interactive terminal UI; its discoverable content is indexed through the other public pages. --- *Fetch any post in markdown at https://www.anuragd.me/blog/{slug}.md.*