Customer Success

Account health that doesn't depend on gut feel

Customer success runs on signals scattered across Slack threads, warehouse tables, and audit logs. The data exists — it just isn't readable on a Tuesday morning before a QBR. These plans turn that scatter into scheduled, structured reporting.

What breaks when you do this by hand

  • The real state of an account lives in Slack threads nobody has a repeatable way to read.

  • Health conversations rely on gut feel because adoption and reliability data sits in tables no one queries by hand.

  • Tenant reviews mean a dozen ad-hoc queries reassembled into a deck, every time.

What you get instead

  • A single source of truth across usage, audit, and error data

  • Scheduled health reporting instead of pre-meeting scrambles

  • Relationship signals read consistently across every account

This is the whole thing

The opening of Customer Health Report — the system prompt, its typed parameters, and the tools it's allowed to reach, all declared up front. No canvas, no hidden nodes. 221 lines of source you can review in a pull request.

Read all 221 lines →

customer-analytics.fml

Copy
system("You are a CS and DevOps analyst generating a customer health report.")

parameter("tenant_id", type=string, title="Tenant ID")
parameter("customer_name", type=string, title="Customer Name")

require mcp BigQuery

components {
    schema("ServerStats") {
        mcp_name: string
        status: string
        total_tool_calls: int
        total_errors: int
        error_rate: float
        active_users: int
        distinct_tools_called: int
        active_days: int
        first_call: string
        last_call: string
        days_since_last_call: int
        connected_but_never_called: bool
    }

What every plan here guarantees

Zero prompt drift

Every plan is a versioned contract. Run 1 and run 10,000 behave identically.

Scoped sessions

Each LLM call sees only the context it needs — no one giant prompt, no context rot.

Typed output

Plans return validated objects pinned to a schema, not text you have to parse.

Reusable like an API

Parameterise once and call it from anywhere — versioned, auditable, shareable.