Типовые сценарии · Developer platform · TypeScript & Python services
Illustrative example: replacing hand-rolled engine calls with generated SDKs and an MCP server
Illustrative scenario (not a named customer) · 10 сентября 2026 г.
−1,900 lines
hand-written client code removed (illustrative)
0
contract-drift incidents per quarter (illustrative)
1 day
to first agent tool calls over MCP (illustrative)
Illustrative example. This is a composite scenario written to show how AACSearch can be used. It does not describe a named customer, and the figures are illustrative, not measured results.
The problem
Two services — a TypeScript API layer and a Python ingestion pipeline — each carried its own hand-written client for the search engine: URL building, query-string encoding, error parsing, retries. Every API change had to be discovered in production, and the two clients disagreed on parameter names. An internal support agent needed the same operations as tools, which meant a third hand-written description of the API.
The setup
AACSearch is contract-first: openapi.yaml is the source of truth, and the public contract derived from it generates the four SDKs (TypeScript, Python, Go, PHP) and the MCP server. Each SDK exposes one client property per resource and one method per operation, named after its operationId, so the same call reads the same way in every language.
import { AACSearchClient } from "aacsearch";
const client = new AACSearchClient({
baseUrl: "https://api.aacsearch.com/v1",
apiKey: process.env.NOVA_API_KEY!, // sent as X-NOVA-API-KEY
});
const results = await client.documents.searchCollection({
collectionName: "products",
searchParameters: { q: "cordless drill", query_by: "name,brand", per_page: 20 },
});
from aacsearch import AACSearchApi, SearchParameters
client = AACSearchApi(api_key=os.environ["NOVA_API_KEY"])
results = client.documents.search_collection(
"products",
search_parameters=SearchParameters(q="cordless drill", query_by="name,brand"),
)
The pipeline's imports moved to import_documents on the same client; the Go and PHP services use Collections.CreateCollection and documents->importDocuments — the same operations, the same names.
The support agent got the MCP server, generated from the same public contract with one tool per operation (searchCollection, importDocuments, createCollection, …), so a tool's description is never written by hand and cannot drift from the API.
Docs indexing runs from the CLI: aacsearch index walks a directory of .ts, .tsx, .md and .mdx files into a collection; aacsearch ingest url and ingest file hand a sitemap, a Markdown file or a JSONL export to an API-side ingest job, and --wait polls the job until it is ready or failed. Reindex completion is tracked through those ingest jobs rather than a webhook. Webhooks cover operational events — key creation and revocation, experiment lifecycle, quality regressions, fired alerts — signed with an HMAC X-AACSearch-Signature header the team verifies before acting.
What could change (illustrative figures)
- Hand-written client code removed: about 1,900 lines (illustrative) across the two services — URL building, encoding and error mapping replaced by generated methods.
- Contract-drift incidents: 0 per quarter (illustrative). A renamed parameter now fails at compile time in the TypeScript service and in the SDK's typed models in Python, instead of in production.
- First agent tool calls over MCP: one day (illustrative) — pointing the agent at the generated server instead of writing and maintaining tool schemas.
Why it matters
The team stopped maintaining three descriptions of one API. With the contract generating the SDKs and the MCP server together, an API change reaches every consumer as a typed diff, and the search integration became a dependency to upgrade rather than a client to rewrite.