Reliable address suggestions for checkout and onboarding. Built on Effect so you can compose providers, control reliability, and keep behavior deterministic.
Česká verze:
README.cs.md
packages/core(@smart-address/core): domain types, provider planning, dedupe, and error collection.packages/integrations(@smart-address/integrations): provider adapters (e.g. Nominatim, Radar Autocomplete, HERE Discover) + HTTP/RL helpers.packages/rpc(@smart-address/rpc): Effect RPC contract + client helpers.packages/sdk(@smart-address/sdk): tiny browser client (ESM module).apps/service-bun(@smart-address/service-bun): Bun service exposing HTTP + MCP + RPC endpoints, caching, and SQLite persistence.apps/docs: Rspress documentation site (Diataxis, EN + CS).
Prereqs: pnpm + bun.
Optional: set RADAR_API_KEY to enable Radar Autocomplete or HERE_API_KEY to enable HERE Discover.
pnpm install
NOMINATIM_USER_AGENT="smart-address-dev" \
NOMINATIM_EMAIL="you@example.com" \
RADAR_API_KEY="your-radar-api-key" \
HERE_API_KEY="your-here-api-key" \
pnpm --filter @smart-address/service-bun devRequest suggestions:
curl "http://localhost:8787/suggest?q=Prague&limit=5&countryCode=CZ"Log an accepted suggestion:
curl -X POST "http://localhost:8787/accept" \
-H "content-type: application/json" \
-d '{"text":"Prague","strategy":"reliable","resultIndex":0,"resultCount":5,"suggestion":{"id":"nominatim:123","label":"Prague, CZ","address":{"city":"Prague","countryCode":"CZ"},"source":{"provider":"nominatim","kind":"public"}}}'Health check:
curl "http://localhost:8787/health"Metrics snapshot (cache + provider health):
curl "http://localhost:8787/metrics"Smart Address emits one wide event per request and traces via Effect + OpenTelemetry.
Run a local OTEL backend (Grafana + Tempo + Loki + Prometheus + Pyroscope):
docker compose -f deploy/compose/obs.yaml up -dRecommended env vars:
SMART_ADDRESS_OTEL_ENABLED(default:true)OTEL_EXPORTER_OTLP_ENDPOINT(default:http://localhost:4318)OTEL_SERVICE_NAME(default:smart-address-service)OTEL_SERVICE_VERSION(optional)SMART_ADDRESS_WIDE_EVENT_SAMPLE_RATE(default:1)SMART_ADDRESS_WIDE_EVENT_SLOW_MS(default:2000)SMART_ADDRESS_LOG_RAW_QUERY(default:truein dev,falsein production)
Incoming traceparent headers are honored to continue upstream traces.
Ship JSON logs + Prometheus metrics to LGTM via Alloy:
docker compose -f deploy/compose/obs.yaml -f deploy/compose/app.yaml -f deploy/compose/alloy.yaml up -dLinux eBPF (Beyla) runbook: see apps/docs/content/en/how-to/ebpf.md (Linux-only).
<script type="module">
import { createClient } from "https://api.example.com/demo/sdk.js"
const client = createClient({
baseUrl: "https://api.example.com",
key: "YOUR_KEY"
})
client
.suggest({ text: "Prague", limit: 5, countryCode: "CZ", strategy: "reliable" })
.then((result) => console.log(result.suggestions))
</script>Build the image:
docker build -t smart-address-service .Tagging tip (recommended for production):
docker build -t smart-address-service:$(git rev-parse --short HEAD) .Run with Docker Compose (service only):
NOMINATIM_USER_AGENT="your-app-name" \
NOMINATIM_EMAIL="you@example.com" \
RADAR_API_KEY="your-radar-api-key" \
HERE_API_KEY="your-here-api-key" \
docker compose -f deploy/compose/app.yaml up -dTip: docker compose reads .env in the repo root, so you can set
NOMINATIM_USER_AGENT, NOMINATIM_EMAIL, RADAR_API_KEY, and HERE_API_KEY there instead of inline.
Persist the SQLite DB:
- Compose mounts the
smart-address-datavolume to/app/data. - The default DB path is
data/smart-address.db(relative to/app). - Override with
SMART_ADDRESS_DB_PATH(for example/app/data/custom.db).
Run full local observability (service + LGTM):
NOMINATIM_USER_AGENT="your-app-name" \
NOMINATIM_EMAIL="you@example.com" \
RADAR_API_KEY="your-radar-api-key" \
HERE_API_KEY="your-here-api-key" \
docker compose -f deploy/compose/obs.yaml -f deploy/compose/app.yaml up -dRecommended env vars (Nominatim usage policy):
NOMINATIM_USER_AGENT(default:smart-address-servicewhen unset/blank)NOMINATIM_EMAIL(optional, recommended for production use)
Optional env vars:
- Radar Autocomplete:
RADAR_API_KEY,RADAR_AUTOCOMPLETE_BASE_URL,RADAR_AUTOCOMPLETE_DEFAULT_LIMIT,RADAR_AUTOCOMPLETE_LAYERS,RADAR_AUTOCOMPLETE_NEAR,RADAR_AUTOCOMPLETE_COUNTRY_CODE,RADAR_AUTOCOMPLETE_RATE_LIMIT_MS - HERE Discover:
HERE_API_KEY,HERE_DISCOVER_BASE_URL,HERE_DISCOVER_DEFAULT_LIMIT,HERE_DISCOVER_LANGUAGE,HERE_DISCOVER_IN_AREA,HERE_DISCOVER_AT,HERE_DEFAULT_LAT,HERE_DEFAULT_LNG,HERE_DISCOVER_RATE_LIMIT_MS - Nominatim:
NOMINATIM_BASE_URL,NOMINATIM_REFERER,NOMINATIM_DEFAULT_LIMIT,NOMINATIM_RATE_LIMIT_MS PORT(default8787),PROVIDER_TIMEOUT_MS- Cache:
CACHE_L1_CAPACITY,CACHE_L1_TTL_MS,CACHE_L2_BASE_TTL_MS,CACHE_L2_MIN_TTL_MS,CACHE_L2_MAX_TTL_MS,CACHE_L2_SWR_MS - DB path override:
SMART_ADDRESS_DB_PATH
- Website source:
apps/docs - Content:
apps/docs/content/enandapps/docs/content/cs - Structure: tutorials / how-to / reference / explanation (Diataxis)
Start docs locally:
pnpm --filter docs devThe service exposes an MCP tool named suggest-address on http://localhost:8787/mcp.
Reference: apps/docs/content/en/reference/mcp-tool.md