In March 2026, we shipped the Knock Agent: an AI agent for managing all your customer messaging resources in Knock. It can create and update workflows, templates, and audiences, help segment users, and answer questions about how your customer messaging is performing. The agent can be invoked from the Knock dashboard, a connected Slack workspace, the API, or our MCP server.
In this post, we'll take a look behind the scenes at how we architected and built our agent using bash, a virtual file system, and our management API.
Defining the vision for our agent
Our vision was to create an agent that could manage everything that can be accessed from the Knock dashboard. We wanted the agent to create messaging that uses your company's design system, matches the tone of voice, and understands how your data is modeled.
To bring this vision to life, we needed to create a rich agent harness that could access the full breadth of data in your Knock account and use that context while creating your messaging and answering any questions.
We built our first prototype to operate exclusively on workflows, which is a deep domain with plenty of nuance around how it works. We used a tool-per-type pattern, where each tool exposed a primitive from our management API, such as adding a delay step to a workflow, or building an email template using our visual blocks language. The tool description encoded the idiosyncrasies of working with that tool and gave examples, while the tool input described the field types and what was required.
While this worked and led to good results, we realized that this approach would not scale: we'd be exposing a tool per resource in the management API, which would bloat the context window of the agent without us implementing a more sophisticated tool routing layer or introducing a scripting language for the agent to use.
We found a blog from the team at Vercel, "How to build agents with filesystems and bash", where they describe building an agent for d0, their internal data tool. They explain how the filesystem is a great way for an agent to discover the context it needs, and how you can map a domain to a filesystem to power this context layer.
At Knock, we've long had a CLI which enables teams to pull down their Knock resources, such as messaging templates and components, and operate on them locally via the filesystem.
The idea here was simple: instead of exposing tools that mirror our management API, we give the agent a filesystem with the contents of your account, and the ability to use bash to script on top of that filesystem. That way, the agent can explore the filesystem to gather context, using bash to efficiently write scripts as needed.
... continue reading