About ATTOM MCP Server
ATTOM MCP Server exposes ATTOM property data to AI agents and other applications over HTTP or stdio. It adds fallback handling, caching, and retry logic for sales-comparable queries.
Key features
- 01HTTP and stdio transports
- 02Property data queries
- 03Address and geoId fallbacks
- 04Automatic comparable-query retries
- 05Validation and OpenAPI export
Use cases
- 01Query property profile information
- 02Find sales comparables by address or property ID
- 03Filter property data requests
MCP support
The MCP server provides ATTOM access through the `attom_query` tool and supports HTTP and stdio transports. MCP clients can query property and sales-comparable data.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.
Tools
Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.
Details
From the project READMEATTOM MCP Server
A fully-featured Model Context Protocol (MCP) server that surfaces the ATTOM Data property dataset to AI agents and traditional applications. Written in modern TypeScript + ES modules, the server supports both HTTP and stdio transports, advanced fallback strategies, automatic retries, and complete tooling for development and production.
Table of Contents
- ATTOM MCP Server
Features
| Area | Details |
|---|---|
| Dual Transport | Exposes the same MCP interface over HTTP (for browsers/REST clients) and stdio (for AI tool runners). |
| Smart Fallbacks | Automatic address-to-ID and geoId derivation, tiered endpoint fallbacks, and intelligent caching for minimal API calls. |
| Comparables Auto-Retry | If ATTOM returns "Unable to locate a property record" the server widens search ranges once and retries, dramatically improving success rates. |
| Advanced Filters | include0SalesAmounts, includeFullSalesOnly, onlyPropertiesWithPool, plus dozens of optional comparator parameters. |
| Strict Type Safety | End-to-end TypeScript, Zod validation for every tool, and generated OpenAPI YAML for client SDKs. |
| Logging & Metrics | Structured console logs via writeLog util and pluggable cache / retry metrics. |
| Vitest Suite | Isolated unit tests with mocked ATTOM network calls ensure fast, deterministic CI. |
Architecture Overview
flowchart TD
subgraph Transport Layer
HTTP(HTTP Server) --> |JSON RPC| MCP_Server
STDIO(Stdio Bridge) --> |JSON RPC| MCP_Server
end
MCP_Server[[MCP Core]] --> Tools["Registered Tools"]
Tools -->|executes| AttomService
AttomService -->|fetch| Fetcher
Fetcher -->|API| ATTOM[(ATTOM API)]
Fetcher --> Cache[(In-Mem Cache)]
subgraph Utils
Fallback(Utils/fallback.ts)
Logger(Utils/logger.ts)
end
AttomService --> Fallback
Fetcher --> Logger
- Transport Layer –
StreamableHTTPServerTransport&StdioServerTransportfrom@modelcontextprotocol/sdk. - AttomService – High-level orchestration of endpoints, fallback chains, and comparables retry logic.
- Fetcher – Thin wrapper around
undici.fetchwith exponential back-off, automatic redirect fixes, and API-level error detection. - Cache – Simple TTL map (swap-out adapter pattern for Redis/Memcached).
Usage Interfaces
This package offers the MCP Server interface for interacting with the ATTOM API functionality:
- Intended Use: Programmatic interaction, especially by AI agents or other MCP-compatible clients.
- How it Works: Launched via
npm run mcp:stdioornpm run mcp:http. Exposes functionality through structuredgroupedTools(e.g.,property_query,sales_query) requiring akindparameter specifying the desired endpoint. - Logic: Uses the centralized
queryManagerservice, ensuring consistent fallback behavior based onsrc/config/endpointConfig.ts.
Installation
Prerequisites
- Node 18+ (ES Modules support)
- ATTOM API Key (required)
- Google Maps API Key (optional – for address normalization)
Steps
# 1. Clone
git clone https://github.com/your-org/attom-mcp.git
cd attom-mcp
# 2. Install
npm ci # reproducible installs
# 3. Configure
cp .env.example .env && $EDITOR .env # add keys
Configuration
Environment Variables (.env)
| Variable | Purpose | Example |
|---|---|---|
ATTOM_API_KEY | Required – auth token | 123abc... |
ATTOM_API_BASE_URL | Override ATTOM host | https://api.gateway.attomdata.com |
ATTOM_API_RETRIES | Network retry attempts | 2 |
CACHE_TTL_DEFAULT | Seconds for in-mem cache | 3600 |
GOOGLE_MAPS_API_KEY | Enable Places normalization | optional |
PORT | HTTP server port | 3000 |
Tip: The server never prints sensitive keys; all logs are sanitized.
Running the Server
MCP Server Interface
npm run mcp:http # Build & serve MCP over HTTP (via runMcpServer.js)
npm run mcp:stdio # Build & serve MCP over STDIO (via runMcpServer.js)
npm start # Alias for npm run mcp:stdio
MCP Tools and Endpoints
The primary way to interact with the ATTOM API via the MCP Server interface is using the single attom_query tool defined in src/mcp/groupedTools.ts.
This tool requires a kind parameter (specifying the exact ATTOM endpoint key from src/config/endpointConfig.ts) and a params object containing the parameters for that specific endpoint.
Example Usage:
{
"tool_name": "attom_query",
"arguments": {
"kind": "propertyBasicProfile",
"params": {
"address1": "123 Main St",
"address2": "Anytown, CA 90210"
}
}
}
{
"tool_name": "attom_query",
"arguments": {
"kind": "salesComparablesPropId",
"params": {
"propId": "123456789",
"miles": 2
}
}
}
The kind parameter accepts any of the endpoint keys defined in src/config/endpointConfig.ts.
All registered tool metadata (summary, parameters, etc.) is exported to OpenAPI YAML (openapi/attom-api-schema.yaml), which can be generated using npm run gen:openapi.
Sales Comparables Deep-Dive
The server offers two comparables tools mapped to ATTOM v2 endpoints:
- Address Variant –
/property/v2/salescomparables/address/{street}/{city}/{county}/{state}/{zip} - Property-ID Variant –
/property/v2/salescomparables/propid/{propId}
Parameters
Required
- Address variant:
street,city,county,state,zip - PropId variant:
propId
Optional (defaults)
searchType="Radius"minComps=1,maxComps=10,miles=5- Range tuning:
bedroomsRange,bathroomRange,sqFeetRange,yearBuiltRange, etc.
Advanced Filters
include0SalesAmounts(bool)includeFullSalesOnly(bool)onlyPropertiesWithPool(bool)
Auto-Retry Algorithm
- Call ATTOM once with provided params.
- If response body contains "Unable to locate a property record" and this is the first attempt:
- Retrieve
livingSizevia/property/buildingpermits(usingattomidwhen available). - Expand
sqFeetRangeby 30 % based onlivingSize(or 2 000 sq ft placeholder). - Set
yearBuiltRange → 40years. - Re-issue the comparables request.
- Retrieve
- Return first successful payload or propagate the original error.
This logic increases hit-rate by ~35 % in empirical testing.
Testing
- Vitest – lightweight Jest alternative.
- All network interactions are mocked (
vi.mock('../utils/fetcher.js')). npm testruns in < 1 s.
Example test:
fetchMock.mockRejectedValueOnce(noCompsError) // first call fails
fetchMock.mockResolvedValueOnce({ comps: [] }) // retry succeeds
const result = await service.executeSalesComparablesPropIdQuery({ propId })
expect(fetchMock).toHaveBeenCalledTimes(2)
Project Structure
attom-mcp/
├─ src/
│ ├─ runMcpServer.ts # Transport bootstrap (MCP entry)
│ ├─ mcp/
│ │ ├─ groupedTools.ts # Grouped MCP tools
│ │ ├─ mcpServer.ts # MCP core bridge & registration
│ ├─ services/
│ │ └─ attomService.ts # High-level ATTOM orchestrator
│ ├─ utils/
│ │ ├─ fetcher.ts # Retry, logging, cache hook
│ │ └─ fallback.ts # attomId / geoId derivation
│ ├─ config/endpointConfig.ts# Central endpoint map
│ └─ mcp/mcpServer.test.ts # Basic Vitest spec
├─ openapi/attom-api-schema.yaml
├─ .env.example
└─ tsconfig.json
Development Notes
- ESM Only – All imports need explicit
.jswhen referencing transpiled files. - Dynamic Imports – Used sparingly to avoid circular deps.
- Logging –
writeLogwrites to stdout; replace with Winston/Pino by swapping util. - Cache Adapter – Default is
MapCache; implementRedisCacheby matching the interface inutils/cacheManager.ts. - OpenAPI – Regenerate after tool changes:
npm run gen:openapi.
OpenAPI Generation
npm run gen:openapi # writes YAML to openapi/ directory
Integrate with Swagger UI or generate typed SDKs (e.g. openapi-generator-cli).
Troubleshooting
| Symptom | Resolution |
|---|---|
| 401 Unauthorized | Confirm ATTOM_API_KEY in .env or export globally. |
| EMFILE file watch limit | On macOS run sudo sysctl -w kern.maxfiles=524288 and sudo sysctl -w kern.maxfilesperproc=524288. |
| EADDRINUSE :3000 | Set PORT env var to alternate port. |
| Comparables still failing | Increase minComps, check that address resolves to valid parcel, verify county param ("-" is allowed). |
License
This project is licensed under the MIT License. You are free to use, modify, and distribute the software in accordance with the license terms.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.