echolocate.app — EchoLocate is a music discovery system powered by MCP (Model Context Protocol), Google Cloud Run, DuckDB, and audio vector search. It exposes sonic similarity search and playlist generation via an MCP server, backed by a high-performance vector search service.
mcp/: Remote MCP server exposing 6 EchoLocate tools (echolocate_*). Handles OAuth2/JWT authentication and proxies requests to the vector service using Google Cloud ID tokens.vector/: Python vector search service using DuckDB. Serves audio embeddings and supports sonic interpolation. Used as a build dependency for the Rust service.vector-rs/: Rust/Axum vector search service (primary deployment). Baked-index architecture — DuckDB index is embedded in the container image, eliminating cold-start latency.frontend/: Browser UI for exploring tracks with semantic search and interpolation. Publicly accessible at echolocate.app.embeddings/: Scripts for processing audio files, generating MERT and CLAP embeddings, and building the DuckDB database.fma-ingest/: Cloud Run job for ingesting Free Music Archive data from GCS.firestore/: Firestore security rules and deployment config (used by the semantic search cache).
- Sonic Search: Find similar tracks based on audio embeddings (MERT model, 768-dim).
- Semantic Search: Text-to-audio search using CLAP embeddings (512-dim). Queries are expanded by Vertex AI before embedding to improve recall on short or terse descriptions.
- Sonic Interpolation: Generate smooth playlists between two tracks using recursive bisection — each step finds the nearest real track to the vector midpoint of the current segment, producing a gradual sonic path between two very different starting points. Supports an optional steering track to bend the path via Bézier interpolation.
- Frontend Explorer: Browser UI with text search, semantic search, and interpolation playlist builder.
Cold start was reduced from ~45–60s to ~10–15s through: baked-index architecture (DuckDB index embedded in the container image), parallelised HNSW index warming with ONNX model loading, and migration to Rust for the vector service.
| Metric | Value |
|---|---|
| Cold start | ~10–15s |
| Semantic search p50 | ~250ms |
| Semantic search p99 | ~600ms |
| Compute cost | ~$0–$0.10/user/day (Cloud Run, min 0 instances) |
| Audio storage | ~$0.30/day (~1TB FMA audio, GCS nearline) |
No load balancer — each service is accessed directly via its Cloud Run URL:
- Frontend: Public (
--allow-unauthenticated,--no-iap). Custom domainecholocate.appvia Cloud Run domain mapping. - Vector service: Public (
--allow-unauthenticated) — read-only search. CORS restricted tohttps://echolocate.app. The MCP server hasroles/run.invokerfor service-to-service calls. - MCP server: Publicly reachable for the OAuth2 handshake (
/authorize,/token). All sensitive routes protected byAuthMiddleware.
The entire stack deploys to Google Cloud Run.
- Google Cloud SDK (
gcloud) with beta component, authenticated. - A Google Cloud Project with Cloud Run and Secret Manager enabled.
- A GCS bucket containing your DuckDB file (for the vector service), or a baked
data/index.duckdbfor the Rust service.
./deploy.shThis deploys in order: vector service → MCP server → frontend.
After deploying, map the custom domain:
gcloud beta run domain-mappings create \
--service=cloud-crate-frontend \
--domain=echolocate.app \
--region=us-central1 \
--project=<YOUR_PROJECT>Add the A/AAAA records shown by gcloud beta run domain-mappings describe --domain=echolocate.app --region=us-central1 at your domain registrar. Cloud Run provisions a managed TLS certificate automatically.
./teardown_lb.sh# EchoLocate MCP Server (port 8080)
cd mcp && python main.py
# Vector Service — Rust (port 8080)
cd vector-rs && INDEX_DB_PATH=../data/index.duckdb cargo run
# Vector Service — Python legacy (port 8000)
cd vector && uvicorn main:app --reloadThe frontend automatically uses http://localhost:8001 as the vector API base when served from localhost.
python vector/verify_service.py <VECTOR_URL>
python mcp/verify_auth.py <MCP_URL>
# Frontend (expect 200)
curl -s -o /dev/null -w '%{http_code}' https://echolocate.app/Cause: CORS_ALLOW_ORIGINS on the vector service doesn't include the frontend origin.
Fix: Verify the vector service has CORS_ALLOW_ORIGINS=https://echolocate.app. Redeploy with cd vector && ./deploy.sh if needed.
- Asymmetric phase matching — Score transitions using the delta between outro and intro segment vectors, treating similarity as directional rather than symmetric.
- k-NN shortest path — Build a nearest-neighbor graph and find actual shortest paths rather than recursive bisection.
- Maximum marginal relevance — Balance similarity to the target path with diversity to avoid repetitive track selections.
- Audio-to-text generation — Generate natural language descriptions from audio embeddings to explain why tracks are considered similar.
- Wider audio sampling — Average embeddings across multiple windows per track rather than a single 5-second segment.
- CLAP for interpolation — Explore using CLAP embeddings alongside MERT for the interpolation path.
- Free Music Archive (FMA) — audio dataset used for indexing.
- MERT: Acoustic Music Understanding Model with Large-Scale Self-Supervised Training — audio embedding model for sonic similarity.
- CLAP: Learning Audio Concepts from Natural Language Supervision — text-to-audio embedding model for semantic search.
- HNSW: Efficient and Robust Approximate Nearest Neighbor Search — algorithm powering the DuckDB vector indexes.