Private beta
Alpha lifts your SDK into an IR, generates five idiomatic SDKs and an MCP server, then diffs all six against the source at the wire.
Request access
The Alpha console on 127.0.0.1:4400. Six targets, one IR, nothing leaving your machine.
The IR carries auth, pagination, retries and errors, so each generator writes what a senior engineer would write.
func (c *Client) ListWidgets(ctx context.Context, params *ListWidgetsParams) ([]Widget, error) {
path := "/v1/widgets"
q := url.Values{}
if params != nil && params.Limit != nil {
q.Set("limit", strconv.FormatInt(*params.Limit, 10))
}
var cursor *paginationCursor
if params != nil && params.After != nil {
cursor = (*paginationCursor)(params.After)
}
all := []Widget{}
pages := 0
for {
pages++
out/ui-jobs/muu8p8lwwcdxz/go/client.go
/**
* List all widgets, following cursor pagination transparently.
*/
async listWidgets(params?: ListWidgetsParams, request?: RequestOptions): Promise<Widget[]> {
const query = new URLSearchParams();
if (params?.limit !== undefined) query.set("limit", String(params.limit));
const headers: Record<string, string> = {};
let cursor = params?.after;
const all: Widget[] = [];
let pages = 0;
for (;;) {
out/ui-jobs/muu8p8lwwcdxz/typescript/client.ts
def list_widgets(self, *, limit: typing.Optional[int] = None, after: typing.Optional[str] = None, request_timeout: typing.Optional[float] = None, hooks: typing.Optional["Hooks"] = None) -> typing.List[Widget]:
"""List all widgets, following cursor pagination transparently."""
_p_path = "/v1/widgets"
_p_query: typing.List[typing.Tuple[str, str]] = []
if limit is not None:
_p_query.append(("limit", str(limit)))
_p_headers: typing.Dict[str, str] = {}
_cursor = after
_all_items: typing.List[Widget] = []
_pages = 0
while True:
_pages += 1
out/ui-jobs/muu8p8lwwcdxz/python/petstore/client.py
public final List<Widget> listWidgets(ListWidgetsParams params, Duration requestTimeout, Hooks __callHooks) {
String __path = "/v1/widgets";
List<String[]> __q = new ArrayList<>();
if (params.limit() != null) {
__q.add(new String[] { "limit", String.valueOf(params.limit()) });
}
Map<String, String> __h = new LinkedHashMap<>();
byte[] __payload = null;
String __cursor = params == null ? null : params.after();
List<Widget> __all = new ArrayList<>();
int __pages = 0;
while (true) {
out/ui-jobs/muu8p8lwwcdxz/java/src/main/java/petstore/PetstoreClient.java
/// <summary>
/// List all widgets, following cursor pagination transparently.
/// </summary>
public async Task<IReadOnlyList<Widget>?> ListWidgetsAsync(ListWidgetsParams? @params = null, CancellationToken cancellationToken = default)
{
@params ??= new ListWidgetsParams();
var __h = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var __q = new List<KeyValuePair<string, string>>();
if (@params.Limit != null) __q.Add(new KeyValuePair<string, string>("limit", AlphaRt.Wire.Scalar(@params.Limit)));
if (!string.IsNullOrEmpty(_token)) __h["Authorization"] = "Bearer " + _token;
string __path = "/v1/widgets";
string __url = _baseUrl + __path + AlphaRt.Wire.QueryString(__q);
out/ui-jobs/muu8p8lwwcdxz/csharp/src/PetstoreClient.cs
One operation, list_widgets, lowered five times from one sdk.ir.json in one build.
Zero LLM calls on this build. One code unit shipped as a loud stub.
Fern and Stainless were both acquired in 2026. Alpha lifts the SDKs they generated, by watching them run.
webflow 105 operations, from Fern. lumaai 13 and arcadepy 19, from Stainless. Run of record, 2026-10-04.
Wire-identical against each SDK's own traffic: 10/10 scenarios for all three, on Go, TypeScript and Java.
node tests/corpus/run.mjs --only webflow
One IR, five lowerings. Every generated client is diffed against the source, and against every other target.

petstore, 15 pairs, 3 scenarios per pair. The source SDK against each of five targets, plus every generated pair.
Adding the sixth surface takes the same run to 28.
On AWS Lambda, Go, TypeScript and Python each go 5 of 5 wire-identical against real boto3. AWS's own SDK is the oracle.
Every client refuses a response that does not match the model, with one named error per language.
Go *json.UnmarshalTypeError · Java DecodeException · TypeScript and Python DecodeError · C# FormatException.
A missing or explicitly null required member is tolerated in all five, and decodes to the zero or absent value.
An MCP server from the same semantic model, shipped through the same bar: one tool per operation, wire-diffed like the rest, over both its transports.
Idiomatic on the surface, identical on the wire. That now holds for all six surfaces: parity is exact equality on canonical requests, so it is transitive: every surface proven against your source SDK is proven against every other.
petstore, eight runs. The source, five languages, the MCP server over stdio and HTTP: 28 pairs, all wire-identical, per committed scenario. The two transports are byte-identical to each other. Slack: 311 tools, 311 docs resources, every refusal receipted.
Rename, describe or hide any tool in config, and the choice survives every regeneration. The server never starts on ambient AWS credentials: you name the source.
We pointed our extractor at seven real OSS Python SDKs. Reading their source lifted zero operations from all seven.
So we stopped reading the code and started watching it run. Same seven SDKs: 229 operations.
All seven match the real SDK on a call with real arguments. Four match on every committed scenario; todoist, posthog and resend have gaps the report names. Run of record, 2026-10-04.
The seven-zeros columns of docs/OSS-CONVERSIONS.md. We published this before we published the fix.
context.Context.Reads your source, or watches it run. Lowers to five languages and an MCP server. Diffs every surface at the wire.
Records real traffic, then diffs every regeneration against the committed IR.
Zero runtime dependencies in all five languages. Read the go.mod yourself.

The fidelity report names what did not lift, with a file and a line. This one is from the petstore example.
module example.com/slacksdkweb go 1.23
Generated alongside the client, in Go, TypeScript, Python and Java.
Docstrings land as godoc, TSDoc, Python docstrings and javadoc. Every package ships a README.
What a hand-written SDK gets wrong in year two ships on day one.
C# sends all of these except SigV4. Java and C# refuse server-sent events rather than buffer them.
Already maintaining SDKs by hand? Alpha will not overwrite an edit it can see. It stops, or merges it forward.
$ alpha regen --config alpha.config.json --deterministic refusing: handEdit 1. Move the change into an overlay: copy the file to overlays/go/<path> and edit it there. 3. Never silently overwritten: before this guard existed, this run would have rewritten these files and the only trace would have been the PR diff. $ alpha regen --config alpha.config.json --deterministic --api-only --merge track: patchCarried 1. Nothing is required this run: the edit was re-applied on top of the new generation and your output has it.
Real output after a three-line edit to the generated client.go, trimmed.
A hand edit to a generated file stops the run and names the file, the lines and the remedy.
With --merge, a three-way merge carries it onto the new generation. Conflicts go to the review packet, never into your tree.
alpha verify --source-sdk drives your hand-written Go or Java v1 against the generated v2, over the same recorded traffic.
Reading an existing hand-written Go or Java SDK is a managed bring-up today, not self-serve.
Stop budgeting a year per language. Early access gets a white-glove conversion of your first SDK.