How to Parse Messy US Addresses with the API, MCP, and CLI
Real address data is rarely clean. This tutorial shows three ways to turn freeform, human-typed US addresses into clean structured fields with sthan.io: the REST API, the MCP server for AI assistants, and the CLI for your terminal. Copy-paste examples for each.
Table of Contents
What the Address Parser Does
The sthan.io Address Parser takes a single freeform US address string and returns it as clean, structured components: address number, street name and directionals, unit type and number, city, state, ZIP, ZIP+4, and county, along with a standardized full address. It is AI-powered, so it handles real-world mess: typos, abbreviations spelled out or shortened, out-of-order components, and missing pieces.
You can reach the parser three ways, all backed by the same engine and the same free API key:
- REST API for any language or backend
- MCP server so AI assistants like Claude and Cursor can parse addresses for you
- CLI for quick terminal checks and batch CSV or Excel files
Get a Free API Key
Create a key from the dashboard. The free tier includes 100 requests per month with no credit card. Keys come in two flavors: sthan_test_* for development and sthan_live_* for production. Every example below uses the same key.
Option 1: The REST API
The parser is a single authenticated GET request. Put the freeform address (URL-encoded) in the path and pass your key as a bearer token:
curl -H "Authorization: Bearer sthan_test_YOUR_KEY" \
"https://api.sthan.io/v2/address-parser/usa/325%20w%20broaddwey%20%23%20m%20ny%2010013"
The response wraps the parsed result in a small envelope:
{
"Id": "f3a1c8e2-...",
"Result": {
"inputAddress": "325 w broaddwey # m ny 10013",
"fullAddress": "325 W Broadway PH M, New York, NY 10013-1835",
"addressNumber": "325",
"streetPreDir": "W",
"streetName": "Broadway",
"unitType": "PH",
"unitNumber": "M",
"city": "New York",
"stateCode": "NY",
"state": "New York",
"zipCode": "10013",
"zip4": "1835",
"county": "New York"
},
"StatusCode": 200,
"IsError": false,
"Errors": []
}
Along with these fields, the result carries match metadata (the match mode, a match tier, and a confidence score) so you can decide how much to trust a given parse. Check IsError before reading Result, and read Errors when it is true.
Python
import requests
from urllib.parse import quote
API_KEY = "sthan_test_YOUR_KEY"
address = "apt 2b 500 broadway new york ny"
resp = requests.get(
f"https://api.sthan.io/v2/address-parser/usa/{quote(address)}",
headers={"Authorization": f"Bearer {API_KEY}"},
)
data = resp.json()
if data["IsError"]:
print("Error:", "; ".join(data["Errors"]))
else:
r = data["Result"]
print(r["fullAddress"])
print(r["streetName"], r["city"], r["stateCode"], r["zipCode"])
Node.js
const API_KEY = "sthan_test_YOUR_KEY";
const address = "apt 2b 500 broadway new york ny";
const res = await fetch(
`https://api.sthan.io/v2/address-parser/usa/${encodeURIComponent(address)}`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
const data = await res.json();
if (data.IsError) {
console.error("Error:", data.Errors.join("; "));
} else {
console.log(data.Result.fullAddress);
}
Prefer a typed SDK? The official package wraps the same endpoints:
import { SthanClient } from "@sthan/core";
const sthan = new SthanClient({ apiKey: "sthan_test_YOUR_KEY" });
const { Result } = await sthan.parseAddress("apt 2b 500 broadway new york ny");
console.log(Result.fullAddress);
Option 2: The MCP Server (for AI Assistants)
The Model Context Protocol (MCP) lets an AI assistant call tools directly. The sthan.io MCP server gives your assistant an address parsing tool (plus verification, autocomplete, and geocoding), so you can ask for a parse in plain language and get structured fields back. It works with Claude Code, Claude Desktop, Cursor, VS Code, and any MCP-compatible client.
Add the server to your client
For Claude Code or Claude Desktop, add this to your mcp.json. Cursor uses the same block in .cursor/mcp.json:
{
"mcpServers": {
"sthan": {
"command": "npx",
"args": ["-y", "@sthan/mcp-server"],
"env": { "STHAN_API_KEY": "sthan_test_YOUR_KEY" }
}
}
}
Then just ask
Once the server is connected, prompt the assistant naturally:
"Clean up and structure this customer address: 325 w broaddwey # m ny 10013"
The assistant calls the parser, reads the structured result, and can use it in whatever it builds next, all without you writing request code.
Option 3: The CLI (Terminal and Batch)
Install once, save your key, and parse from anywhere in your shell:
npm install -g @sthan/cli
sthan login --api-key sthan_test_YOUR_KEY
sthan parse "apt 2b 500 broadway new york ny"
The default output is a readable summary. Add --json to get the raw structured response for scripting:
sthan parse "apt 2b 500 broadway new york ny" --json
Parse a whole file
Point the CLI at a CSV, TSV, or Excel file and it parses every row, auto-detecting the address column:
sthan parse --input addresses.csv --output parsed.csv
This is the fastest way to clean a CRM export or a legacy data dump without writing any code. The same --input / --output pattern works for sthan verify and sthan geocode.
What You Get Back
Every method returns the same parsed fields. The most useful ones:
| Field | Description | Example |
|---|---|---|
fullAddress | Standardized, postal-formatted full address | 325 W Broadway PH M, New York, NY 10013-1835 |
addressNumber | House or building number | 325 |
streetPreDir | Directional before the street name | W |
streetName | Street name | Broadway |
unitType / unitNumber | Unit designator and value | PH / M |
city | City | New York |
stateCode / state | State code and full name | NY / New York |
zipCode / zip4 | ZIP and ZIP+4 add-on | 10013 / 1835 |
county | County | New York |
Messy Input, Clean Output
The parser is built for the addresses real users actually type. A few examples:
325 w broaddwey # m ny 10013
1199 w shaw avenue fresno
123 main st apt 1 andover ma
Try It Live
Paste any messy US address below to see the parser in action. Try a typo, a missing ZIP, or out-of-order components.
Try it live — Address Parser
Handling Errors
The API uses standard HTTP status codes. The most common ones to handle:
| Status | Meaning | What to do |
|---|---|---|
401 | Authentication failed | Check the API key and the Authorization: Bearer header |
403 | Forbidden or quota exceeded | Confirm your plan allows the call, or upgrade |
429 | Rate limited | Back off and retry; reduce request rate |
500–504 | Server error | Retry with backoff |
On a handled error the body still carries IsError: true and an Errors array with a human-readable message, so prefer checking those over the status code alone.
Which Method Should You Use?
- Use the REST API when parsing happens inside your application or backend, at any scale.
- Use the MCP server when you want an AI assistant or agent to parse addresses as part of a larger task, with no integration code.
- Use the CLI for one-off terminal checks, scripts, and cleaning whole CSV or Excel files in a single command.
All three share one key, one engine, and the same parsed fields, so you can mix them freely.
Key Takeaways
- The Address Parser turns freeform US address text into clean structured fields, handling typos, abbreviations, reordering, and missing pieces
- Reach it three ways with one free key: REST API, MCP server for AI assistants, and the CLI for the terminal
- REST is a single authenticated GET to
/v2/address-parser/usa/{address} - The MCP server lets Claude, Cursor, and other clients parse addresses with no integration code
- The CLI parses single addresses or entire CSV and Excel files with
--input/--output
Frequently Asked Questions
GET https://api.sthan.io/v2/address-parser/usa/{address} with an Authorization: Bearer header. You get back structured fields (address number, street, unit, city, state, ZIP, ZIP+4, county) plus a standardized full address.
npm install -g @sthan/cli, save your key with sthan login, then run sthan parse "apt 2b 500 broadway new york ny". Add --input file.csv --output out.csv to parse a whole file at once.
Start Parsing Addresses — Free
Get a key in under a minute. 100 requests per month, no credit card. Use it with the API, MCP, or CLI.