Skip to main content
Glama
9mp96ygnbk-alt

FactLot MCP Server

README.md
# FactLot

**The open fact layer for commercial real estate AI agents.**

**Install in one line** (v0.1.0; no API key, no network calls; listed in the
[official MCP Registry](https://registry.modelcontextprotocol.io/v0.1/servers?search=factlot) as
`io.github.9mp96ygnbk-alt/factlot`):

```bash
# Any MCP client (stdio). For Claude Code: claude mcp add factlot -- npx -y <this URL>
npx -y https://github.com/9mp96ygnbk-alt/factlot/releases/download/v0.1.0/factlot-mcp-standalone-0.1.0.tgz
```

Claude Desktop: open [`factlot-0.1.0.mcpb`](https://github.com/9mp96ygnbk-alt/factlot/releases/download/v0.1.0/factlot-0.1.0.mcpb).
REST, OpenAPI and remote MCP: `docker run -p 8787:8787 ghcr.io/9mp96ygnbk-alt/factlot:0.1.0`.
Python: `pip install "git+https://github.com/9mp96ygnbk-alt/factlot.git@v0.1.0#subdirectory=python"`.

**Hosted registry early access:** teams that want cited parcel-to-owner-to-entity lookups without self-hosting can email [contact@factlot.com](mailto:contact@factlot.com?subject=FactLot%20hosted%20registry%20early%20access). The hosted service is not yet public, and early-access teams help set pricing. Questions and bug reports go in [GitHub Discussions](https://github.com/9mp96ygnbk-alt/factlot/discussions) and Issues.

Agents doing CRE work get stuck in the same places. They can't trust their own
arithmetic, they can't cite where a number came from, and they can't tell that
"Suite 400, 123 Main LLC" in one system is the same thing as a parcel number in
another.

FactLot gives every agent three things it can use by default:

| Package                              | What it does                                                                                                                                                                                                                                                                                                                        | License    |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| [`@factlot/calc`](packages/calc)     | Deterministic CRE calculators: rent schedules, net effective rent, proposal comparison, percentage rent, CAM reconciliation, loan sizing, ASC 842 lease remeasurement, prepayment and defeasance, WALT, IRR/NPV, lease vs. own, renew vs. relocate, hotel metrics. Every result includes an audit trail and a versioned formula ID. | Apache-2.0 |
| [`@factlot/id`](packages/id)         | **FactLot ID** gives canonical IDs for parcels, legal entities, buildings, spaces, leases, and documents. IDs are deterministic wherever the world already has a key, so any agent can compute them offline.                                                                                                                        | Apache-2.0 |
| [`@factlot/schema`](packages/schema) | The FactLot data model. A fact is one atomic claim with **provenance** (source document, page, clause, method) and **rights** (whether an AI may use or redistribute it).                                                                                                                                                           | MIT        |
| [`@factlot/tools`](packages/tools)   | The tool catalog, with native tool definitions for Claude, OpenAI, Gemini, Amazon Bedrock, Mistral, and OpenAPI platforms, plus one `runTool` dispatcher.                                                                                                                                                                           | MIT        |
| [`@factlot/server`](packages/server) | The remote connector: Streamable HTTP MCP at `/mcp`, REST at `/v1`, and OpenAPI. Runs in Docker.                                                                                                                                                                                                                                    | Apache-2.0 |
| [`@factlot/mcp`](packages/mcp)       | An MCP server that exposes all of the above to Claude and any other MCP-capable agent. It runs locally and needs no API key.                                                                                                                                                                                                        | Apache-2.0 |

## Why

In a [simulated survey of 165 CRE agent personas](docs/research/2026-11-agent-survey) across 20 roles:

- The highest-rated offerings were document-to-facts (3.52/5), deterministic calculators (3.24), and canonical IDs and entity resolution (3.12).
- 95% asked for citations, 51% reported that LLM math was wrong, and 35% said data licensing stops them using data they already pay for.
- Agent-to-agent negotiation scored 0.35/5. Agents want facts they can trust, not more autonomy.

That survey is a hypothesis generator, not market research. The [customer discovery plan](docs/customer-discovery.md) describes how we validate it. The same personas later [reviewed v0.1 as built](docs/research/2026-11-product-feedback) (also simulated): the calculators, IDs, and the quote-on-page verifier were praised wherever they applied, and most personas were blocked by coverage, which is what the section below is honest about.

## What FactLot covers today

Be clear about scope before adopting it:

- **Calculators, IDs, and the fact model work anywhere.** They need no data and no API key, and
  they run offline in both SDKs with identical results.
- **The registry covers the largest metros, unevenly.** Real public-record rolls are loaded for
  Harris, Dallas, Tarrant, Travis and Collin (Texas), New York City, Los Angeles, Boston, San
  Francisco, Denver, Charlotte, Minneapolis and the District of Columbia: 708,538 commercial,
  industrial and multifamily parcels, with 12.9 million registered entities from Texas, New York,
  Colorado, Pennsylvania and DC for owner resolution. A second tier of 28 more counties is
  verified with adapters (Monroe, Suffolk, Nassau, Westchester and Erie NY; three Maryland
  counties; four Massachusetts counties; Denton, Williamson and Fort Bend; Milwaukee, Marion,
  Oakland, Wake, Davidson, DeKalb, Sacramento, Salt Lake, Utah County, Pierce, Multnomah, and two
  Pennsylvania counties) and loads through the collector. Cook County, Florida, Fulton, Maricopa,
  Wayne, Fairfax, King and much of California wait on a licence decision, a form or a purchase.
  Commercial, industrial and multifamily parcels only; several public files omit owner names; no
  sales prices, tenants, debt, zoning, or building specs beyond area and year built. See
  [the registry](docs/registry/README.md), the [Tier 1 catalog](docs/registry/sources/README.md)
  and the [Tier 2 index](docs/registry/tier2/README.md).
- **One rules pack**, the Texas property-tax protest deadline, verified against the official
  statute text. Other jurisdictions follow only after a person verifies them.
- **Lease ingestion is a prototype**: deterministic quote-on-page and value-in-quote checks, OCR
  for scanned pages through a pluggable backend, but no published accuracy number yet.
- **Not yet on npm or PyPI**, and no hosted public endpoint. Install from the
  [v0.1.0 release](https://github.com/9mp96ygnbk-alt/factlot/releases/tag/v0.1.0), from git, from
  source, or with Docker ([getting started](docs/getting-started.md)).

## Connect FactLot to any AI platform

| Platform                                      | How to connect                                                                                                                                                                                |
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Claude**                                    | Add a custom connector with `https://<host>/mcp`, install the one-click Desktop extension (`factlot.mcpb`), use Claude Code, or call it from the Claude API                                   |
| **ChatGPT and OpenAI**                        | Create a ChatGPT app in developer mode (`search`/`fetch` make deep research work), import `/openapi.json` as a Custom GPT Action, use the Responses API's remote MCP, or use function calling |
| **Google Gemini**                             | Use Gemini API function declarations, Gemini CLI over MCP, or Vertex AI                                                                                                                       |
| **Microsoft Copilot**                         | Add an MCP tool in Copilot Studio, use the Power Platform connector, or build a Microsoft 365 API plugin                                                                                      |
| **Amazon Bedrock**                            | Use the Converse API `toolConfig`, or a Bedrock Agents action group backed by the Lambda handler                                                                                              |
| **Mistral, xAI, Llama, DeepSeek, and others** | Use OpenAI-compatible function calling or MCP clients                                                                                                                                         |

Every surface serves the same tools, generated from one catalog. See **[connectors/](connectors/README.md)**.

## Quick start: use FactLot from an agent

FactLot is not on npm or PyPI yet. These work without either: they run the stdio MCP server
from a GitHub release, from a clone, or in Docker. Each was run end to end
([install verification](docs/install-verification.md)).

```bash
# From the GitHub release: one file, dependencies bundled
claude mcp add factlot -- npx -y https://github.com/9mp96ygnbk-alt/factlot/releases/download/v0.1.0/factlot-mcp-standalone-0.1.0.tgz

# From a clone
git clone https://github.com/9mp96ygnbk-alt/factlot.git && cd factlot
npm install && npm run build
claude mcp add factlot -- node "$PWD/packages/mcp/dist/bin.js"

# Remote connector (Streamable HTTP MCP at /mcp, REST at /v1, OpenAPI)
docker run --rm -p 8787:8787 ghcr.io/9mp96ygnbk-alt/factlot:0.1.0
```

Claude Desktop users can install `factlot-0.1.0.mcpb` from the
[release](https://github.com/9mp96ygnbk-alt/factlot/releases). For any other MCP client, use the
same command in its config:

```json
{
  "mcpServers": {
    "factlot": {
      "command": "node",
      "args": ["/absolute/path/to/factlot/packages/mcp/dist/bin.js"]
    }
  }
}
```

After first publish to npm: `claude mcp add factlot -- npx -y @factlot/mcp`.
[Getting started](docs/getting-started.md) has every option, including the TypeScript libraries
as release tarballs.

The server provides these tools: `calc_rent_schedule`, `calc_net_effective_rent`,
`calc_compare_proposals`, `calc_percentage_rent`, `calc_cam_reconciliation`,
`calc_debt_sizing`, `calc_lease_remeasurement_asc842`, `calc_prepayment_and_defeasance`,
`calc_walt`, `calc_npv`, `calc_irr`, `calc_lease_vs_own`,
`calc_renew_vs_relocate`, `calc_hotel_metrics`,
`rules_tx_property_tax_protest_deadline`,
`id_parcel`, `id_entity`, `id_space`, `id_document`, `id_parse`, `fact_validate`,
`search`, `fetch`, and `schema_get`, plus the six `registry_*` lookups when a registry database is configured
(`FACTLOT_REGISTRY_DB`).

> Release files, the GHCR image, and `git+https` installs need the repository to be public and a
> release (here `v0.1.0`) to exist; from a clone works now.

## Quick start: Python agents

```bash
pip install "git+https://github.com/9mp96ygnbk-alt/factlot.git#subdirectory=python"
# after first publish to PyPI: pip install factlot
```

```python
import factlot

tools = factlot.anthropic_tools()  # or factlot.openai_tools(); pass these to your model
# When the model calls a tool, run it by name with the model's arguments:
result = factlot.run_tool("calc_npv", {"cash_flows": [-1000, 600, 600], "rate": 0.08})
result["value"]["npv"]  # 69.96
```

The Python SDK has no dependencies and passes the same [conformance vectors](spec) as the
TypeScript packages. A differential test runs random inputs through both SDKs in CI and fails on
any difference, down to the last digit. See [python/README.md](python/README.md).

## Quick start: use the libraries

```ts
import { debtSizing } from "@factlot/calc";
import { parcelId } from "@factlot/id";

const loan = debtSizing({
  noi: 1_000_000,
  value: 15_000_000,
  rate_annual: 0.06,
  amortization_years: 30,
  max_ltv: 0.65,
  min_dscr: 1.25,
  min_debt_yield: 0.09,
});
loan.value.max_loan; // 9750000
loan.value.binding_constraint; // "ltv"
loan.steps; // every intermediate value, with formulas
loan.formula; // { id: "calc.debt_sizing", version: 2 }

parcelId({ stateFips: "06", countyFips: "037", apn: "5432-001-012" });
// { kind: "parcel", urn: "fl:parcel:us-06037:5432001012", short: "flp_..." }
```

## Develop

This requires Node.js 22.6 or newer.

```bash
npm install
npm run check   # lint, format check, typecheck, tests, build
```

## How FactLot is built and funded

FactLot follows the [Supabase](https://github.com/supabase/supabase) model:

- **Open source.** The platform code is Apache-2.0. Client-facing schemas and SDKs are MIT. Everything here can be self-hosted, which matters when leases are confidential.
- **FactLot Cloud (planned).** These are hosted services that cost real money to run:
  - the **FactLot Registry**: ID resolution, ownership graph, crosswalks, change webhooks
  - **Ingest**: documents to cited facts
  - **Rules packs**: property tax, zoning, building-performance law

  Pricing is usage-based with a free tier.

See [docs/business-model.md](docs/business-model.md) and [docs/roadmap.md](docs/roadmap.md).

## Docs

- [Agent guide: which tool to call when](docs/agents.md) · [llms.txt](llms.txt)
- [Rules packs](docs/rules.md) · [Lease ingestion](docs/ingest.md) · [Registry](docs/registry/README.md)
- [FactLot ID specification](docs/id-spec.md)
- [Fact model: provenance and rights](docs/fact-model.md)
- [Backlog: everything not finished yet](docs/BACKLOG.md)
- [Roadmap](docs/roadmap.md)
- [Business model](docs/business-model.md)
- [Customer discovery plan](docs/customer-discovery.md)
- [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md)

"FactLot" and the FactLot logo are trademarks of their owner. The open-source licenses
cover the code, not the name.