How AI is applied across API Evangelist and APIs.io. Read my AI disclosure →
API Evangelist API Evangelist
Discovery
Learnings
Guidance
Toolbox
Alignment
API Evangelist LLC

Arazzo Functions Are Still a Proposal, and That Is the Point

September 22nd, 2026 · Kin Lane
Arazzo Functions Are Still a Proposal, and That Is the Point

The four pull requests I have written about this week share a trait: each one points a workflow step at something that already has a description. An OpenAPI. An AsyncAPI. A WSDL. A .proto. A GraphQL schema. The proposal I want to talk about today is about the step that points at something with no description at all, and it is not a pull request yet — it is issue #523, a long design document from Kevin Duffey that has been open since July, has drawn substantive responses from three people, and was the one item on last week’s Arazzo call that everyone agreed needs more time in the room before anyone writes the code. That makes it the best reason on the list to actually show up.

The problem is easy to state. Real workflows call things that are not APIs. An MCP tool, which has a JSON Schema contract but no OpenAPI. A command-line program that runs between two API calls. A small deterministic transform — reshape a payload, normalize a date. A WebAssembly module. Today the options are to write a fake OpenAPI that fronts the thing through a local shim, or to hang x- extensions off a step, and both mean every runtime invents its own convention. Kevin’s proposal adds a top-level functions section, a sibling of workflows. Each Function Object has a functionId, an inputSchema, an outputSchema, MCP-style annotations like readOnlyHint and idempotentHint, and a list of bindings — each one a claim about how the function can be invoked, such as type: mcp with a server name and a tool. A step then says functionId: resolveUser with arguments, and reads the result as $result. The example in the issue resolves a directory user from a free-form name through an MCP tool, with a fallback binding to a second server.

What makes the proposal worth reading even if you disagree with it is rule zero: two independent implementations, given the same document and equivalent support and policy, make identical decisions at every observable point. Everything else in the design serves that — the contract is portable while the invocation is environmental, nothing in the document grants authority to invoke anything, binding selection is deterministic and happens before execution, and a function with no eligible binding fails during preparation rather than at step seven of twelve. That is the discipline a workflow specification needs if two runners are ever going to agree, and it connects directly to the conformance conversation I will get to tomorrow.

Now the pushback, which is the interesting part. Frank Kilcommins’ response asks whether functions should exist as a top-level construct at all, or whether the emerging formats around MCP and CLIs should be handled as source description types — the same way OpenAPI, AsyncAPI and now WSDL are. For MCP, the natural candidate is the Server Cards proposal, which currently omits tool declarations but has an open issue to bring them back — Frank has said so in that thread. Cisco’s mcpdesc.org is a possible interim. For CLIs, he points at the Open CLI Specification. His concern with the functions approach is dual authoring: if an MCP server already ships a server card and a CLI already has a description, functions makes you describe the same thing twice. His counter-proposal is an inline source description — a sourceDescriptions entry where the description is embedded rather than referenced — so that steps always reference operations through source descriptions, external or inline, and the authoring model stays consistent. He also asks whether function steps can reuse parameters rather than adding arguments.

Then Sébastien B. widens it further. Every protocol Arazzo has absorbed has added its own fields to the step object — operationId and operationPath, then channelPath, then operationName, and next rpcMethod, graphqlOperation and functionId. He argues the step object is fragmenting, and proposes a polymorphic step with type discrimination: protocol-agnostic orchestration concerns in one place, protocol-specific interface details in another. He is upfront that it is a breaking change. Kevin’s reply is the one that tells you how open this still is — he is not opposed to an Arazzo 2.0 if the breaking issues justify it, and floats keeping 1.2 to SOAP and pushing functions and actor in the loop to a 2.0. Dmitry Anansky adds the practical question nobody has answered yet: MCP tool outputs are often unstructured text, so what does outputSchema mean for a function bound to one?

On the call, the group’s position was that functions come after 1.3 — Frank said the proposal needs “more advanced sessions” before anyone is comfortable enough to bite off the pull request, and Kevin’s sequencing put it after actor in the loop and GraphQL so that tooling vendors are not asked to absorb functions and interactions in the same release. He also mentioned that the MCP question — whether Arazzo can point at a tool a server advertises — was parked in this same conversation. So the MCP door into Arazzo runs through this issue, and the design is not decided.

That is why this is the post in the series with the clearest reason to attend rather than review. A pull request wants a reader. A proposal wants a participant. If you build MCP servers, you have an opinion about whether your tools should be reachable by a server card or by an inline function, and about what a runtime should do with your unstructured text output. If you build CLIs, you have an opinion about whether opencli.org describes yours. If you have lived through a specification’s 2.0, you have an opinion about Sébastien’s question. Put it in issue #523, or bring it to the Arazzo call — every other Wednesday at 09:00 Pacific, details in discussion #5, #arazzo on the OpenAPI Slack between calls. The next one is Wednesday, September 30, and this is the topic where a new voice changes the outcome.

Tomorrow, the six-month-old issue with zero comments that decides whether any of this works the same way twice.