โ† Back to blog
Trends

After OpenAI DevDay 2026, what changes for Agent development?

Published 2026-09-02 Updated 2026-09-02 About 12 min JSON Toolbox

How this article is organized

OpenAI DevDay 2026 is set for 2026-09-29. This piece was written before the event and does not treat unannounced model names as news. What has already changed: Responses API is the main entry for the tool loop, GPT-5.6 shipped Programmatic Tool Calling, and MCP and Connectors sit in the same tools array. Below: separate the two APIs, then how to pick direct / programmatic, then land the tool contract in a validatable JSON Schema.

"After DevDay" in the title is easy to write as a keynote forecast. Agent development already changed before the event: tool calling grew from "the model says one call per turn" to "the model writes orchestration code"; MCP went from an editor plugin to a first-class tool type on the Responses API. What the event is more likely to lock down is how these contracts are written, who approves, and how results are validated.

What you can confirm about DevDay 2026 now

The official event page says: 2026-09-29, Fort Mason, San Francisco, keynote at 10:00 PT, opened by Sam Altman. On-site registration is closed; the keynote will be livestreamed. OpenAI has not listed any product names on the event page. GPT-6, Astra, and the next Codex are still hallway talk โ€” they don't go on the schedule.

Platform changes you can already treat as fact before the event:

  • 2026-07-09, GPT-5.6 (Sol / Terra / Luna) GA. The flagship alias gpt-5.6 points to gpt-5.6-sol.
  • Responses API shipped Programmatic Tool Calling, multi-agent beta, and persisted reasoning across turns at the same time.
  • Remote MCP and Connectors share the same mcp tool type; billing is tokens for imported definitions and actual calls, with no per-call surcharge.
  • Agents SDK still owns the loop, handoff, session, and tracing; custom loops still belong on the Responses API.

Lock the boundary. This piece only covers APIs already in OpenAI docs. If DevDay ships a new model or hosted tool that day, follow the official announcement. Don't use this as a launch checklist.

Two paths: Responses API and Agents SDK

Pick who runs the loop first, then talk tool JSON. Official docs draw the split cleanly: run the loop yourself, use Responses API; let the SDK run the loop, use Agents SDK.

What you want Responses API Agents SDK
Who runs the loop You write it SDK runner
Where tools come from function / MCP / hosted tools The same set, plus agent-as-tool and local MCP
Multi-agent You route; there is also a multi-agent beta Built-in handoff
State previous_response_id, reasoning.context session + resumable run
Fits Custom product features Conversational / transactional flows with clear bounds

Don't write two tool definitions. Function parameters / output_schema and the MCP input schema should be the same JSON contract. The SDK is only the shell that runs the loop.

Four steps from a task to validatable JSON A task enters Responses or Agents SDK, is called via direct or programmatic, produces tool JSON, then is validated against a Schema. Task Query / orchestration API / SDK Who runs the loop direct / PTC + MCP App JSON Schema check
You can swap the loop shell; don't swap the tool contract. Schema closes the shape. It does not pick the API for you.

Tool Calling: direct and programmatic

Before mid-2026, the default Agent shape was: the model emits a function_call, you execute it, you stuff the result back, and the next turn decides. Four tool calls meant four turns. GPT-5.6 made the second path a first-class Responses API capability.

1. One call per turn: still the default path

direct calls are still the default. Official guidance: don't turn on programmatic when:

  • One lookup is enough.
  • Intermediate results are small; wrapping them in a program has no payoff.
  • Each step's result changes the next judgment (adaptive search, semantic evaluation).
  • Writes, transfers, deletes, or actions that need human approval.
  • The final answer must keep citations or native artifacts.

In one line: judgment stays with the model, execution stays with you, and the approval boundary has to be visible.

2. The model writes JS: Programmatic Tool Calling

Programmatic Tool Calling (PTC) lets the model write a JavaScript snippet and run it in a fresh, isolated V8. The program can await, loop, branch, and call authorized tools concurrently, then emit a reduced result via text(...) or image(...). The runtime has no Node, no package install, no direct network, and no general filesystem. The only path out of the sandbox is the tools you turned on in the request.

To turn it on, do both: add {"type": "programmatic_tool_calling"} to the tool list; set allowed_callers on tools the program should call.

allowed_callers Who can call
omit or ["direct"] Model direct calls only
["programmatic"] Only code inside the program can call
["direct", "programmatic"] Both paths work

Types that can be called from a program today: function, custom, mcp, apply_patch, local / hosted shell, code_interpreter. Tool Search is still a top-level tool: a running program cannot discover defer_loading: true tools itself. The model must load them first; the next-turn program can then use them.

The response has three item types. Don't mash them into one object:

  • program: generated JS, call_id, and a fingerprint used to resume
  • function_call issued by the program: its own call_id; caller.caller_id points at that program
  • program_output: the program's final result; status is completed or incomplete

Official docs also warn: program_output and the last assistant message are two outputs. The program may have already computed the right record while the final message drops a required field or a citation. Test both.

MCP is no longer "a separate protocol you bolt on"

After MCP landed on the Responses API, remote MCP and Connectors are both type: "mcp". The only difference is whether you pass server_url or connector_id. When the model decides to call, the API hits the remote and the output includes mcp_call. Approval is required by default (mcp_approval_request); for low-latency cases you can set require_approval to never per tool.

Stacked with PTC, MCP can also set allowed_callers: ["programmatic"]. Existing MCP servers don't need a protocol change to be driven by generated JS. Approval policy still applies: for writes across a trust boundary, let require_approval pause the program. If you can't state the approval boundary, don't grant programmatic.

More tools means imported definitions eat tokens. Official docs give you allowed_tools: import only the few you need. The shape that will be more common after DevDay is not "dump the whole MCP server into context," but "a short list + Tool Search when needed."

Don't treat MCP as an unchecked pipe. The remote server sees the arguments. Log approval requests. Connector inputs and returns are JSON strings โ€” parse first, then validate against your Schema before you land them.

The contract is JSON: parameters and output_schema

PTC raises the stakes on Schema. Generated JS cannot see the conventions in your head; it only sees tool descriptions and field types. Official docs are explicit: parameters describe inputs; when a tool returns predictable structured data, also use output_schema to describe the JSON string in function_call_output.output. Write both, or the program cannot read return fields reliably.

So the Agent side actually has three JSON layers. Don't crush them into one:

  1. Tool input: parameters / MCP input schema. Filled by the model and by the program.
  2. Tool output: output_schema. Used by the program to filter, join, and dedupe.
  3. Final reply: Structured Output / text.format. For humans or a downstream system. This is the second close.

How to infer the third layer from a sample is in the previous Structured Output guide. This piece covers the first two: the tool contract.

A tool sample that is enough to generate a Schema

Below is a common "fits PTC" shape for inventory checks. Keep numbers as number. Compute shortage as a field. Don't let the model narrate "about 3 units short."

{
  "sku": "SKU-1024",
  "available_units": 12,
  "requested_units": 15,
  "shortage_units": 3,
  "source": {
    "inventory": "get_inventory",
    "demand": "get_demand"
  }
}

Matching tool-definition structure (illustrative โ€” not a complete authenticated request):

{
  "model": "gpt-5.6",
  "tools": [
    {
      "type": "function",
      "name": "get_inventory",
      "description": "Return inventory by SKU. Returns sku and available_units.",
      "parameters": {
        "type": "object",
        "properties": {
          "sku": { "type": "string" }
        },
        "required": ["sku"],
        "additionalProperties": false
      },
      "output_schema": {
        "type": "object",
        "properties": {
          "sku": { "type": "string" },
          "available_units": { "type": "number" }
        },
        "required": ["sku", "available_units"],
        "additionalProperties": false
      },
      "allowed_callers": ["programmatic"]
    },
    {
      "type": "programmatic_tool_calling"
    }
  ]
}

With this site's inference rules, that business sample yields:

Field Infer types What to do after generate
sku string Add pattern if you need to lock the format
available_units / requested_units / shortage_units number Must be numbers in the sample; "12" becomes string
source object Can stay out of required if it is audit-only
shortage_units number This is a computed result. Don't mark it as "model freeform"

Once the sample is ready, open Function Calling or Structured Output to generate each platform wrapper, then review required and additionalProperties by hand. MCP tools go through MCP Tool โ€” don't copy the same fields twice.

Three things that will actually change after DevDay

Don't guess product names. Look at the contract layer. After the event, these three are more likely to be amplified than overturned.

  1. Orchestration moves from the prompt into the runtime. Loops, filters, and joins no longer hang on empty lines like "please use tools efficiently." PTC writes control flow as JS; what you write is allowed_callers, stop conditions, and structured errors on failure.
  2. MCP goes from plugin to platform tool. An MCP server in the editor can hang directly on the Responses API. The cost: approval, logging, and allowed_tools have to be designed in the product. Don't wait for the model to converge on its own.
  3. Schema grows from "final reply" to "tool input and output." Validating only the assistant JSON is not enough. If the program misreads one field type, every aggregation after it is wrong. Keep input, output, and final reply as three Schemas, grown from the same sample.

The multi-agent beta and Codex ultra / sub-agents are a different line: split independent reasoning to a sub-agent. PTC is "orchestrate tools with code"; multi-agent is "orchestrate models with models." If the task isn't large enough, don't turn either on.

How to accept it in JSON Toolbox

  1. Paste tool input / output samples into JSON Format and confirm they parse.
  2. Generate definitions with Function Calling or MCP Tool; final reply goes through Structured Output.
  3. Take a second set of real tool results to Schema validation. The first sample is always optimistic.
  4. When program_output and the final message don't line up, use JSON Diff to see whether a field dropped or a type drifted.
  5. Convert to Zod when the frontend needs checks, and to OpenAPI 3.1 when you need API docs.

Everything stays in the browser and is never uploaded.

FAQ

When is OpenAI DevDay 2026?

The official page says 2026-09-29, Fort Mason, San Francisco, keynote at 10:00 PT. This piece was written 2026-09-02 and does not treat unannounced model names as fact.

How does Programmatic Tool Calling differ from ordinary Function Calling?

direct is one tool call per model turn. programmatic is the model writing JS that orchestrates authorized tools in an isolated V8, then returns a reduced result. Writes and approvals still default to direct.

Can MCP tools be called by Programmatic Tool Calling?

Yes. Set allowed_callers: ["programmatic"] on MCP. require_approval still pauses the program.

Should I use Responses API or Agents SDK?

Run the loop yourself: Responses API. Want a ready loop / handoff / session: Agents SDK. Maintain one tool JSON contract.

Are output_schema and Structured Output the same thing?

No. output_schema constrains a single tool return; Structured Output constrains the final reply. Both layers need a Schema.

Summary

DevDay 2026 will put the narrative on stage; the structural change in Agent development already happened. The loop can go to the SDK or you write it. Tool calling starts with picking direct or programmatic. Treat MCP as a normal tool and own the approvals. The core is three Schemas: input, output, and final reply. Grow them from the same sample. Validate, Zod, and OpenAPI all follow it.