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. Your key starts with fl_live_.

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

Connect to Flatland

Point MultiServerMCPClient at the local Flatland MCP bridge (flatland-client mcp), passing your API key via the FLATLAND_API_KEY env var. The bridge holds your model on your own disk and computes against the hosted engine; the client converts each MCP tool into a LangChain StructuredTool:

from langchain_mcp_adapters.client import MultiServerMCPClient

client = MultiServerMCPClient({
    "flatland": {
        "transport": "stdio",
        "command": "npx",
        "args": ["-y", "flatland-client", "mcp"],
        "env": {"FLATLAND_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 bridge reads your key from FLATLAND_API_KEY (or ~/.flatland/config.json, written by flatland-setup). If the bridge exits immediately, the key is missing or malformed.
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_initflatland_create_model flatland_bulk_addflatland_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": "stdio",
            "command": "npx",
            "args": ["-y", "flatland-client", "mcp"],
            "env": {"FLATLAND_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": "stdio",
            "command": "npx",
            "args": ["-y", "flatland-client", "mcp"],
            "env": {"FLATLAND_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_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_scenarios returns 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

# 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"
}]})
06

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.
Your model is a file you ownThe bridge saves each model to ~/.flatland/models/ on YOUR machine — it survives sessions/restarts and you can commit it to git.
MCP and HTTP are the same engineThe local MCP bridge and the per-call HTTP API (/api/v2) run identical computation. Use MCP for agents; curl /api/v2 for one-off checks. The old hosted /mcp URL is retired (HTTP 410).
Assertions are non-fatalA failed assertion returns pass: false alongside the compiled results — it does not prevent compilation from completing.
07

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.
PricingPricing detail
Flatland · index of everything
© 2026 Flatland · Financial Reasoning Infrastructure · live pulse · awaiting first compile