compile_events · live
awaiting first compile…
Docs · Integration

Flatland in LangChain
and LangGraph.

Flatland is a remote MCP server. LangChain's official langchain-mcp-adapters library converts any MCP server into LangChain-compatible tools — so Flatland works inside any LangGraph agent with no custom adapter code. The agent handles language. Flatland handles the math.

01

Prerequisites

pip install langchain-mcp-adapters langgraph langchain-anthropic

Get a Flatland API key at /install — no card required (50 answers/month free). Your key starts with fl_live_.

Requires Python 3.11+ · langchain-mcp-adapters 0.1+ · any Anthropic or OpenAI key
02

Connect to Flatland

Pass Flatland's endpoint and your API key to MultiServerMCPClient. The client queries the server and converts each MCP tool into a LangChain StructuredTool:

from langchain_mcp_adapters.client import MultiServerMCPClient

client = MultiServerMCPClient({
    "flatland": {
        "transport": "streamable_http",
        "url": "https://api.flatlandfi.com/mcp",
        "headers": {"X-API-Key": "fl_live_YOUR_KEY_HERE"},
    }
})

tools = await client.get_tools()
# flatland_init, flatland_create_model, flatland_bulk_add,
# flatland_compile, flatland_create_scenario, flatland_diff_scenarios,
# flatland_sensitivity, flatland_save_model, flatland_load_model, ...
The auth header is X-API-Key — not Authorization: Bearer. A 401 almost always means the wrong header name.
03

First agent: SaaS P&L

This agent takes a business description and returns a compiled, typed P&L with assertions and a sensitivity ranking. It follows the standard Flatland session pattern: flatland_init flatland_create_model flatland_bulk_add flatland_compile flatland_sensitivity.

import asyncio
from langchain_anthropic import ChatAnthropic
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent

async def build_model(description: str):
    client = MultiServerMCPClient({
        "flatland": {
            "transport": "streamable_http",
            "url": "https://api.flatlandfi.com/mcp",
            "headers": {"X-API-Key": "fl_live_YOUR_KEY_HERE"},
        }
    })
    tools = await client.get_tools()
    agent = create_react_agent(
        ChatAnthropic(model="claude-opus-4-5"),
        tools,
    )
    return await agent.ainvoke({
        "messages": [{
            "role": "user",
            "content": f"""
                Call flatland_init first.

                Build a financial model for this business:
                {description}

                1. flatland_create_model
                2. flatland_bulk_add — all typed drivers, with
                   assertions on key metrics
                3. flatland_compile
                4. flatland_sensitivity on the primary output driver
                5. Return compiled results and sensitivity ranking
            """,
        }]
    })

result = asyncio.run(build_model(
    "SaaS. $18K MRR, 12% monthly growth, 6% monthly churn. "
    "$900 CAC, 18-month payback target. 4 engineers at $160K/yr. "
    "Build a 12-month P&L with unit economics."
))

The agent calls all five tools in sequence and returns compiled output: typed driver values, pass/fail assertion results, and a tornado ranking of which assumptions move your primary KPI most.

04

Scenario analysis

After building a base model, add a scenario to answer “what if?” questions. Only the changed assumptions differ from the base — the rest of the graph inherits unchanged.

async def run_scenario(base: str, question: str):
    client = MultiServerMCPClient({
        "flatland": {
            "transport": "streamable_http",
            "url": "https://api.flatlandfi.com/mcp",
            "headers": {"X-API-Key": "fl_live_YOUR_KEY_HERE"},
        }
    })
    tools = await client.get_tools()
    agent = create_react_agent(
        ChatAnthropic(model="claude-opus-4-5"),
        tools,
    )
    return await agent.ainvoke({
        "messages": [{
            "role": "user",
            "content": f"""
                flatland_init, then build this base model: {base}

                Then answer: {question}

                1. flatland_create_model + flatland_bulk_add + flatland_compile
                2. flatland_create_scenario — override only the
                   assumptions that change to answer the question
                3. flatland_compile_scenario
                4. flatland_diff_scenarios — return which drivers
                   changed and by how much each output moved
            """,
        }]
    })

result = asyncio.run(run_scenario(
    base="E-commerce. $50K/mo ad spend, 2.8% CVR, $85 AOV, 28% repeat rate.",
    question="What happens if CVR drops to 1.4% and we cut ad spend 30%?",
))

flatland_diff_scenariosreturns attribution: which changed driver caused which output delta, traced through the full dependency graph. Your agent can explain the “why” behind every number.

05

Persistent models across sessions

Flatland saves models server-side, scoped to your API key, in ~/.flatland/models/ on the Flatland server. Within the lifetime of a server instance you can reload a previously built model by name instead of rebuilding from scratch — but durable cross-deploy storage is not yet available, so treat saved models as a session-spanning cache, not a system of record, and keep the prompt that built them:

# Session 1 — build and save
await agent.ainvoke({"messages": [{"role": "user", "content":
    "flatland_init, build a headcount model for a 12-person eng team "
    "with loaded costs and runway assertion, then "
    "flatland_save_model name='headcount-q3'"
}]})

# Session 2 — load and update
await agent.ainvoke({"messages": [{"role": "user", "content":
    "flatland_init, flatland_load_model name='headcount-q3', "
    "add 2 engineers at $175K/yr, recompile, "
    "run sensitivity on total_headcount_cost"
}]})
Saved models live on the Flatland server, scoped to your API key — the agent runs on your machine, but the tools (and their storage) run on api.flatlandfi.com. Any session with the same key can reload them by name within the current server instance's lifetime; cross-deploy durability is not yet guaranteed.
06

Metered tools

Tool
Metered
What it does
flatland_compile
Toposort DAG, evaluate all drivers, run type checks and assertions
flatland_compile_scenario
Compile a scenario overlay; compare output to base
flatland_sensitivity
Perturb each assumption, rank by elasticity on a target KPI
flatland_init
Load skills library into agent context. Call first, every session
flatland_create_model
Initialize a model with name, currency, period config
flatland_bulk_add
Add 3+ typed drivers atomically
flatland_create_scenario
Define a named sparse overlay on the base model
flatland_diff_scenarios
Attribute output deltas to specific driver changes
flatland_save_model
Persist model to ~/.flatland/models/
flatland_load_model
Resume a previously saved model
flatland_get_graph
Return full DAG as adjacency list
flatland_trace_upstream
Walk backward: all causal ancestors of a driver

Metered tools each count as one “answer.” A sensitivity sweep across 50 drivers is one answer, not 50. Everything else — construction, inspection, saving, loading — is always free.

50 free answers per calendar month. Beyond that, $0.10 per answer with a default $50/month cap. Check current usage: GET api.flatlandfi.com/api/usage with your API key. Full detail at /pricing.

HTTP 402 means quota exhausted or spend cap reached — not a server error. Add a payment method at /pricing to continue.
07

Notes

No LLM on Flatland's serverYou bring the AI. Flatland is pure computation — the agent generates model structure, Flatland compiles it deterministically.
Same IR, same outputGiven identical inputs, Flatland always returns identical outputs. The non-determinism in your agent stops at the tool call boundary.
Models live server-sideSaved models live in ~/.flatland/models/ on the Flatland server, scoped to your API key — not on the machine running the agent. Any session with the same key loads them back by name.
MCP and HTTP are the same engineapi.flatlandfi.com/mcp and the HTTP API run identical computation. Use MCP for agents; curl the HTTP API for one-off checks.
Assertions are non-fatalA failed assertion returns pass: false alongside the compiled results — it does not prevent compilation from completing.
08

Where to go next

QuickstartClaude Code and Cursor setup in 5 minutes
Agents pageFull MCP tool catalog with return shapes
ProofBenchmarks — 87ns sensitivity, bit-identical compilation
Get an API keyNo card required. 50 answers/month free.
PricingMetered billing, spend caps, usage API
Flatland · index of everything
© 2026 Flatland · made for systems of record · live pulse · awaiting first compile