case studies calendar_today

Case study — How AI CMS ships a chat-to-edit website builder on Nimblesite

AI CMS is a website builder for Australian tradies — electricians, plumbers, carpenters. A new customer signs up, describes their business in plain English ("Smith Electrical, 0412 345 678, Parramatta NSW"), picks their trade, and in minutes they have a live, SEO-optimised website. From then on they edit it by chatting: "change my phone number," "add a services page," "make the hero blue."

Behind the scenes, AI CMS uses Nimblesite as its AI brain. Here's the full architecture.

The stack

  • Frontend: React SPA
  • Backend: C# Minimal APIs (orchestration, auth, site data, chat routing)
  • Agent platform: Nimblesite (chat loop, memory, tool contract)
  • Tool executor: Ephemeral Fly.io containers (filesystem, Eleventy build, git)
  • Escalation path: Claude Code CLI for complex tasks (new pages, redesigns)

The critical separation: Nimblesite owns the agent; AI CMS owns the tools.

The agent config

AI CMS created one Nimblesite config for the editing assistant:

{
  "name": "Tradie Site Editor",
  "system_prompt": "You are a website editor for {tenant_name}, a {trade_type} business in {location}. Common services: {services}. When a user asks for a simple change (text, phone numbers, small CSS tweaks), use read_file, write_file, and replace_in_file. For complex work (new pages, redesigns), use escalate_to_claude_code.",
  "model_config": {
    "provider": "anthropic",
    "model": "claude-haiku-4-5"
  },
  "tools_config": [
    "read_file",
    "write_file",
    "replace_in_file",
    "list_files",
    "build_site",
    "escalate_to_claude_code"
  ]
}

None of those tools live inside Nimblesite. They live inside AI CMS's own backend, which proxies calls to Fly.io containers.

The tool proxy

When Nimblesite returns a tool_calls array, AI CMS's C# backend does something like:

public async Task<ChatResult> HandleChatAsync(string message, Guid? conversationId)
{
    var response = await _nimblesite.ChatAsync(ConfigId, new ChatRequest
    {
        Message = message,
        ConversationId = conversationId,
    });

    while (response.ToolCalls.Any())
    {
        var results = new List<ToolResult>();
        foreach (var call in response.ToolCalls)
        {
            var output = await _flyContainer.RunToolAsync(
                response.ConversationId, call.Name, call.Arguments);
            results.Add(new ToolResult(call.Name, output));
        }

        response = await _nimblesite.ChatAsync(ConfigId, new ChatRequest
        {
            ConversationId = response.ConversationId,
            ToolResults = results,
        });
    }

    return new ChatResult(response.Response);
}

Nimblesite never touches the website files. Never has SSH access to the container. Never holds credentials for the customer's site. The agent decides what to call; AI CMS's backend runs it.

The two-tier cost model

Most edits are trivial ("change my phone number"). Those go through the base config with claude-haiku-4-5 and cost a few cents.

For complex tasks the agent calls escalate_to_claude_code, which triggers a Fly.io container to launch the Claude Code CLI with the full site context. That's a $0.50–$2.00 operation, but it handles things like "redesign the services page" end-to-end, committing the result to git.

Two tiers, one config, one agent. The agent itself decides which tier to use based on the task.

The numbers

  • Cost per chat edit: cents (basic agent handles 80%+ of edits)
  • Cost per full site generation: low single-digit dollars (Claude Code handles the initial build)
  • Customer subscription: $49/month
  • Gross margin: 50–80%

AI CMS didn't build a conversation table. Didn't build a prompt template engine. Didn't build multi-tenancy. Didn't manage provider API keys per customer. Didn't write an agent loop. All of that came free with Nimblesite.

What AI CMS still owns

  • The trade-specific knowledge injected into the system prompt
  • The tool implementations (file reads, writes, builds)
  • The Fly.io container lifecycle and scaling
  • The customer dashboard and subscription billing
  • The domain routing and SSL

That's the right split. AI CMS owns their product. Nimblesite owns the agent infrastructure they'd otherwise be forced to build.

The takeaway

AI CMS is a reference architecture for any SaaS that wants to drop a chat-to-edit or chat-to-operate experience into their product:

  1. Configure one Nimblesite agent with your system prompt and tool list
  2. Write your tools as normal functions in your backend
  3. Proxy tool calls between Nimblesite and your tool runtime
  4. Ship it

No framework. No loop code. No messages table. No multi-tenant scaffolding.

That's what "Agents as a Service" means in practice.

#case-studies #ai cms #production