
Last month, I sat down in the morning and by the end of the day had a working MCP server with 710 tools covering the entire VTEX API surface. 68 API domains: catalog, orders, pricing, logistics, payments, promotions, marketplace, and the rest. Typed inputs, Zod validation, authentication, retries. The same approach works for any platform that publishes an OpenAPI spec.
VTEX publishes OpenAPI specifications for all of their APIs in a public GitHub repository. 68 schema files, each one describing every endpoint, parameter type, and request body for a given API domain. Catalog, orders, logistics, intelligent search, marketplace, payments, all of it.
The key insight: these specs already contain everything an MCP tool needs. Endpoint, parameters, types, descriptions. I wrote a pipeline that reads them and generates MCP tools directly. Write the pipeline once, run it against any spec.
A script queries the VTEX GitHub repo via the GitHub API and discovers all spec files dynamically. No hardcoded list. It validates each is a proper OpenAPI spec, normalizes the naming, and pulls down all 68 schemas. When VTEX adds a new API, the script picks it up on the next run.
Using @hey-api/openapi-ts, each schema gets processed to generate typed SDK functions for every operation, Zod validation schemas for every request, and HTTP client setup with auth. 68 schemas in, 68 fully typed modules out.
OpenAPI structures parameters into nested groups: path, query, headers, body. MCP tools take flat input. The adapter layer flattens these schemas, handles numeric coercion (tool UIs often send numbers as strings), strips headers (auth is injected by client interceptors), and adds retry logic with exponential backoff.
Each SDK operation becomes an MCP tool via a single declarative call: an ID, a description, the Zod schema, and the SDK function. 710 entries, grouped by API domain.
The bridge between the generated SDK and MCP is a single function. Here's what each tool definition looks like in the registry:
createToolFromOperation({
id: "VTEX_GET_BRAND",
description: "Get brand details by ID.",
annotations: { readOnlyHint: true },
requestSchema: catalogZod.zGetBrandData,
sdkFn: catalogSdk.getBrand,
})createToolFromOperation does several things with that config. It takes the generated Zod request schema, which has the nested OpenAPI structure ({ path: { brandId: number }, query: { fields: string }, body: {...} }), and flattens it into a single-level input schema. An agent just sends { brandId: 123, fields: "name,slug" }. The function rewrites the schema to accept that flat version, validates the input through Zod, then un-flattens it back into the structured { path, query, body } shape the SDK expects before making the call.
The flattening rules: path params stay required. Query params become optional. If the body is a JSON object, its fields get promoted to top level. If it's something else (an array, a primitive), it stays nested under a body key. Headers are stripped entirely because the client interceptor injects X-VTEX-API-AppKey and X-VTEX-API-AppToken automatically.
There's a numeric coercion layer too. Tool UIs and agent frameworks often serialize numbers as strings. The adapter detects numeric Zod fields and wraps them in a union type that accepts both 123 and "123", then normalizes to the correct type before the SDK call. Without this, half the tools would fail on valid input.
Every tool also runs with retry logic: exponential backoff starting at 500ms, up to 3 retries, triggered on network errors, timeouts, 429 rate limits, and 5xx responses. Jitter is added to prevent thundering herds when multiple tools hit VTEX concurrently.
Every tool validates input through Zod before making any HTTP call. The agent gets a clear validation error instead of a cryptic 400 from the VTEX API. When agents chain multiple tool calls, early validation prevents cascading failures.
Brands, categories, products, SKUs, specifications, attachments, trade policies. Full CRUD on the product catalog.
Order management, invoicing, shipping notifications, tracking, feed processing. Order creation through delivery.
Price tables, fixed prices, pricing rules. Promotions, coupons, gift cards, tax configurations.
Warehouses, loading docks, carriers, shipping rates, inventory, reservation tracking, pickup points, SLA calculations.
Payment provider protocols, transaction management, anti-fraud integrations, payment conditions, installment rules.
Seller management, offer matching, Intelligent Search, facets, autocomplete, search analytics.
The pipeline reads OpenAPI, not VTEX. Most platforms already publish specs: AWS, Stripe, Shopify, Twilio, Salesforce, GitHub. Swap the schemas and the same pipeline produces a working MCP server for a different platform. OpenAPI specs already contain everything an MCP tool needs: endpoint, parameters, types, descriptions. The generation step is mechanical.
We built this because we needed it. Our agents work with VTEX stores daily, and typed access to the full platform API makes them more reliable. The generated output is 68 domain modules, 1,100+ files, 14 MB of typed SDK code, none of it maintained by hand. Update the spec, re-run the pipeline.
This VTEX MCP is live in the deco Studio MCP marketplace. Connect your VTEX store, authenticate with your API credentials, and your agents get typed access to all 710 operations across the full platform.
Subscribe to our newsletter and get the latest updates, tips, and exclusive content delivered straight to your inbox.

