SpyBara
Go Premium

Documentation 2026-10-06 22:58 UTC to 2026-10-07 13:00 UTC

9 files changed +879 −201. View all changes and history on the product overview
2026
Wed 7 13:00 Tue 6 22:58 Mon 5 22:59 Sun 4 22:58 Fri 2 23:58 Thu 1 22:59
Details

223 223 

224Use the conversation's session ID to send input. Subscribe to its [event stream](https://developers.openai.com/api/reference/resources/beta/subresources/agents/subresources/sessions/subresources/events/methods/stream) before sending the message so your application receives the turn's early events.224Use the conversation's session ID to send input. Subscribe to its [event stream](https://developers.openai.com/api/reference/resources/beta/subresources/agents/subresources/sessions/subresources/events/methods/stream) before sending the message so your application receives the turn's early events.

225 225 

226Create one idempotency key for each logical message submission. Save it with the message before sending input. In the Python example, pass your API client, session ID, message, and key to a function in your application:226Create one idempotency key for each logical message submission. Save it with the message before sending input. Use the saved key when submitting the message:

227 227 

228Send a follow-up message228Send a follow-up message

229 229 

230```javascript230```javascript

231// Pass your saved session ID and message to this helper.231// Reuse the same submission key when retrying this message.

232async function sendMessage(client, sessionId, text) {232async function sendMessage(client, sessionId, text, submissionKey) {

233 await client.beta.agents.sessions.events.create(sessionId, {233 await client.beta.agents.sessions.events.create(sessionId, {

234 "Idempotency-Key": submissionKey,

234 events: [235 events: [

235 {236 {

236 type: "agent.session.input.message",237 type: "agent.session.input.message",


286```287```

287 288 

288```go289```go

289// Pass your saved session ID and message to this helper.290// Reuse the same submission key when retrying this message.

290func sendMessage(ctx context.Context, client *openai.Client, sessionID, text string) error {291func sendMessage(ctx context.Context, client *openai.Client, sessionID, text, submissionKey string) error {

291 return client.Beta.Agents.Sessions.Events.New(ctx,292 return client.Beta.Agents.Sessions.Events.New(ctx,

292 sessionID,293 sessionID,

293 openai.BetaAgentSessionEventNewParams{294 openai.BetaAgentSessionEventNewParams{

295 IdempotencyKey: openai.String(submissionKey),

294 Events: []openai.AgentSessionInputParamUnion{296 Events: []openai.AgentSessionInputParamUnion{

295 {297 {

296 OfParamAgentSessionInputMessage: &openai.AgentSessionInputParamAgentSessionInputMessage{298 OfParamAgentSessionInputMessage: &openai.AgentSessionInputParamAgentSessionInputMessage{


311```313```

312 314 

313```java315```java

314// Pass your saved session ID and message to this helper.316// Reuse the same submission key when retrying this message.

315public static void sendMessage(OpenAIClient client, String sessionId, String text) {317public static void sendMessage(

318 OpenAIClient client, String sessionId, String text, String submissionKey) {

316 client319 client

317 .beta()320 .beta()

318 .agents()321 .agents()


321 .create(324 .create(

322 EventCreateParams.builder()325 EventCreateParams.builder()

323 .sessionId(sessionId)326 .sessionId(sessionId)

327 .idempotencyKey(submissionKey)

324 .addEvent(328 .addEvent(

325 AgentSessionInputParam.AgentSessionInputMessage.builder()329 AgentSessionInputParam.AgentSessionInputMessage.builder()

326 .addInput(330 .addInput(


333```337```

334 338 

335```ruby339```ruby

336# Pass your saved session ID and message to this helper.340# Reuse the same submission key when retrying this message.

337def send_message(client, session_id, text)341def send_message(client, session_id, text, submission_key)

338 client.beta.agents.sessions.events.create(342 client.beta.agents.sessions.events.create(

339 session_id,343 session_id,

344 idempotency_key: submission_key,

340 events: [345 events: [

341 {346 {

342 type: "agent.session.input.message",347 type: "agent.session.input.message",


362 "https://api.openai.com/v1/agents/sessions/$session_id/events" \367 "https://api.openai.com/v1/agents/sessions/$session_id/events" \

363 -H "OpenAI-Beta: agents=v1" \368 -H "OpenAI-Beta: agents=v1" \

364 -H "Authorization: Bearer $OPENAI_API_KEY" \369 -H "Authorization: Bearer $OPENAI_API_KEY" \

370 -H "Idempotency-Key: $submission_key" \

365 -H "Content-Type: application/json" \371 -H "Content-Type: application/json" \

366 -d '{372 -d '{

367 "events": [373 "events": [


384```390```

385 391 

386 392 

387The Python SDK sends `idempotency_key` as the `Idempotency-Key` header and reuses it for automatic retries. If your application retries after a timeout or lost response, reuse the same key, session ID, and message. Generate a different key for each distinct submission, even when the message text is identical.393Send the key in the `Idempotency-Key` header, and reuse it for automatic retries. If your application retries after a timeout or lost response, reuse the same key, session ID, and message. Generate a different key for each distinct submission, even when the message text is identical.

388 394 

389For a combined send-and-stream example, see [Events and Items](https://developers.openai.com/api/docs/guides/agents-api/sessions/events#send-and-stream-a-task).395For a combined send-and-stream example, see [Events and Items](https://developers.openai.com/api/docs/guides/agents-api/sessions/events#send-and-stream-a-task).

390 396 

Details

10 `gpt-6-luna` is the only model currently available. Use the dedicated `POST10 `gpt-6-luna` is the only model currently available. Use the dedicated `POST

11 /v1/decisions` endpoint.11 /v1/decisions` endpoint.

12 12 

13To run the SDK examples below, use these OpenAI SDK versions or later: Python 3.26.0, JavaScript 7.30.0, Go 3.73.0, Ruby 0.101.0, and Java 4.78.0. See [OpenAI SDK](https://developers.openai.com/api/docs/libraries) for installation instructions.

14 

13## How decisions work15## How decisions work

14 16 

15A request has three parts:17A request has three parts:


40 42 

41 43 

42 44 

45Check an image for visible damage

46 

43```bash47```bash

44IMAGE_BASE64="$(base64 < product.png | tr -d '\r\n')"48IMAGE_BASE64="$(base64 < product.png | tr -d '\r\n')"

45 49 


65JSON69JSON

66```70```

67 71 

72```javascript

73import { readFile } from "node:fs/promises";

74import OpenAI from "openai";

75 

76const client = new OpenAI();

77const imageBase64 = (await readFile("product.png")).toString("base64");

78const decision = await client.decisions.create({

79 model: "gpt-6-luna",

80 input: [

81 {

82 role: "user",

83 content: [

84 { type: "input_text", text: "Inspect the product in this photo." },

85 {

86 type: "input_image",

87 image_url: `data:image/png;base64,${imageBase64}`,

88 },

89 ],

90 },

91 ],

92 questions: [

93 {

94 type: "predicate",

95 name: "visible_damage",

96 instructions:

97 "Does the product have visible damage, such as a crack, tear, or dent? Ignore shadows and damage to the packaging.",

98 },

99 ],

100});

101 

102const answer = decision.answers[0];

103if (answer.type === "refusal") {

104 console.log(`Refused: ${answer.name}`);

105} else if (answer.type === "predicate") {

106 console.log(`Visible damage probability: ${answer.probability}`);

107}

108```

109 

110```python

111import base64

112from pathlib import Path

113 

114from openai import OpenAI

115 

116client = OpenAI()

117image_base64 = base64.b64encode(Path("product.png").read_bytes()).decode("ascii")

118 

119decision = client.decisions.create(

120 model="gpt-6-luna",

121 input=[

122 {

123 "role": "user",

124 "content": [

125 {"type": "input_text", "text": "Inspect the product in this photo."},

126 {

127 "type": "input_image",

128 "image_url": f"data:image/png;base64,{image_base64}",

129 },

130 ],

131 }

132 ],

133 questions=[

134 {

135 "type": "predicate",

136 "name": "visible_damage",

137 "instructions": (

138 "Does the product have visible damage, such as a crack, tear, or dent? "

139 "Ignore shadows and damage to the packaging."

140 ),

141 }

142 ],

143)

144 

145answer = decision.answers[0]

146if answer.type == "refusal":

147 print(f"Refused: {answer.name}")

148elif answer.type == "predicate":

149 print(f"Visible damage probability: {answer.probability}")

150```

151 

152```go

153package main

154 

155import (

156 "context"

157 "encoding/base64"

158 "fmt"

159 "os"

160 

161 "github.com/openai/openai-go/v3"

162)

163 

164func main() {

165 image, err := os.ReadFile("product.png")

166 if err != nil {

167 panic(err)

168 }

169 client := openai.NewClient()

170 decision, err := client.Decisions.New(context.Background(), openai.DecisionNewParams{

171 Model: "gpt-6-luna",

172 Input: openai.DecisionNewParamsInputUnion{

173 OfDecisionInputMessageArray: []openai.DecisionInputMessageParam{{

174 Content: openai.DecisionInputMessageContentUnionParam{

175 OfParts: []openai.DecisionInputPartUnionParam{

176 {OfInputText: &openai.DecisionInputTextParam{Text: "Inspect the product in this photo."}},

177 {OfInputImage: &openai.DecisionInputImageParam{

178 ImageURL: "data:image/png;base64," + base64.StdEncoding.EncodeToString(image),

179 }},

180 },

181 },

182 }},

183 },

184 Questions: []openai.DecisionNewParamsQuestionUnion{{

185 OfPredicate: &openai.DecisionNewParamsQuestionPredicate{

186 Name: openai.String("visible_damage"),

187 Instructions: "Does the product have visible damage, such as a crack, tear, or dent? Ignore shadows and damage to the packaging.",

188 },

189 }},

190 })

191 if err != nil {

192 panic(err)

193 }

194 switch answer := decision.Answers[0].AsAny().(type) {

195 case openai.DecisionAnswerPredicate:

196 fmt.Println(answer.Probability)

197 case openai.DecisionAnswerRefusal:

198 fmt.Printf("Decision refused for %s\n", answer.Name)

199 default:

200 panic("unexpected answer type")

201 }

202}

203```

204 

205```java

206import com.openai.models.decisions.DecisionCreateParams;

207import com.openai.models.decisions.DecisionInputImage;

208import com.openai.models.decisions.DecisionInputMessage;

209import com.openai.models.decisions.DecisionInputPart;

210import com.openai.models.decisions.DecisionInputText;

211import java.nio.file.Files;

212import java.nio.file.Path;

213import java.util.Base64;

214import java.util.List;

215 

216String imageBase64 =

217 Base64.getEncoder().encodeToString(Files.readAllBytes(Path.of("product.png")));

218var message =

219 DecisionInputMessage.builder()

220 .contentOfParts(

221 List.of(

222 DecisionInputPart.ofInputText(

223 DecisionInputText.builder()

224 .text("Inspect the product in this photo.")

225 .build()),

226 DecisionInputPart.ofInputImage(

227 DecisionInputImage.builder()

228 .imageUrl("data:image/png;base64," + imageBase64)

229 .build())))

230 .build();

231var decision =

232 client

233 .decisions()

234 .create(

235 DecisionCreateParams.builder()

236 .model("gpt-6-luna")

237 .inputOfDecisionInputMessages(List.of(message))

238 .addQuestion(

239 DecisionCreateParams.Question.Predicate.builder()

240 .name("visible_damage")

241 .instructions(

242 "Does the product have visible damage, such as a crack, tear, or"

243 + " dent? Ignore shadows and damage to the packaging.")

244 .build())

245 .build());

246 

247var answer = decision.answers().get(0);

248if (answer.isRefusal()) {

249 System.out.println("Refused: " + answer.asRefusal().name().orElse("visible_damage"));

250} else {

251 System.out.println(answer.asPredicate().probability());

252}

253```

254 

255```ruby

256require "base64"

257require "openai"

258 

259image_base64 = Base64.strict_encode64(File.binread("product.png"))

260client = OpenAI::Client.new

261 

262decision = client.decisions.create(

263 model: "gpt-6-luna",

264 input: [

265 {

266 role: :user,

267 content: [

268 {

269 type: :input_text,

270 text: "Inspect the product in this photo."

271 },

272 {

273 type: :input_image,

274 image_url: "data:image/png;base64,#{image_base64}"

275 }

276 ]

277 }

278 ],

279 questions: [

280 {

281 type: :predicate,

282 name: "visible_damage",

283 instructions: "Does the product have visible damage, such as a crack, tear, or dent? Ignore shadows and damage to the packaging."

284 }

285 ]

286)

287 

288answer = decision.answers.fetch(0)

289case answer

290when OpenAI::Models::Decision::Answer::Predicate

291 puts(answer.probability)

292when OpenAI::Models::Decision::Answer::Refusal

293 warn("Decision refused for #{answer.name}")

294else

295 raise("Unexpected answer type: #{answer.type}")

296end

297```

298 

299 

68An illustrative response excerpt:300An illustrative response excerpt:

69 301 

70```json302```json


91 323 

92This request routes a customer complaint:324This request routes a customer complaint:

93 325 

326Route a customer complaint

327 

94```bash328```bash

95curl https://api.openai.com/v1/decisions \329curl https://api.openai.com/v1/decisions \

96 -H "Authorization: Bearer $OPENAI_API_KEY" \330 -H "Authorization: Bearer $OPENAI_API_KEY" \


112 }'346 }'

113```347```

114 348 

349```javascript

350import OpenAI from "openai";

351 

352const client = new OpenAI();

353const decision = await client.decisions.create({

354 model: "gpt-6-luna",

355 input: "I was charged twice for my order.",

356 questions: [

357 {

358 type: "choice",

359 name: "department",

360 instructions: "Which department should handle this complaint?",

361 choices: [

362 { value: "billing", description: "Payments, invoices, and refunds." },

363 { value: "technical", description: "Problems using the product." },

364 { value: "shipping", description: "Delivery and tracking." },

365 { value: "other", description: "Requests outside these categories." },

366 ],

367 },

368 ],

369});

370 

371const answer = decision.answers[0];

372if (answer.type === "refusal") {

373 console.log(`Refused: ${answer.name}`);

374} else if (answer.type === "choice") {

375 console.log(

376 `Department: ${answer.choice} (confidence: ${answer.confidence})`

377 );

378}

379```

380 

381```python

382from openai import OpenAI

383 

384client = OpenAI()

385decision = client.decisions.create(

386 model="gpt-6-luna",

387 input="I was charged twice for my order.",

388 questions=[

389 {

390 "type": "choice",

391 "name": "department",

392 "instructions": "Which department should handle this complaint?",

393 "choices": [

394 {"value": "billing", "description": "Payments, invoices, and refunds."},

395 {"value": "technical", "description": "Problems using the product."},

396 {"value": "shipping", "description": "Delivery and tracking."},

397 {"value": "other", "description": "Requests outside these categories."},

398 ],

399 }

400 ],

401)

402 

403answer = decision.answers[0]

404if answer.type == "refusal":

405 print(f"Refused: {answer.name}")

406elif answer.type == "choice":

407 print(f"Department: {answer.choice} (confidence: {answer.confidence})")

408```

409 

410```go

411package main

412 

413import (

414 "context"

415 "fmt"

416 

417 "github.com/openai/openai-go/v3"

418)

419 

420func main() {

421 client := openai.NewClient()

422 decision, err := client.Decisions.New(context.Background(), openai.DecisionNewParams{

423 Model: "gpt-6-luna",

424 Input: openai.DecisionNewParamsInputUnion{OfString: openai.String("I was charged twice for my order.")},

425 Questions: []openai.DecisionNewParamsQuestionUnion{{

426 OfChoice: &openai.DecisionNewParamsQuestionChoice{

427 Name: openai.String("department"),

428 Instructions: "Which department should handle this complaint?",

429 Choices: []openai.DecisionNewParamsQuestionChoiceChoice{

430 {

431 Value: openai.DecisionNewParamsQuestionChoiceChoiceValueUnion{OfString: openai.String("billing")},

432 Description: openai.String("Payments, invoices, and refunds."),

433 },

434 {

435 Value: openai.DecisionNewParamsQuestionChoiceChoiceValueUnion{OfString: openai.String("technical")},

436 Description: openai.String("Problems using the product."),

437 },

438 {

439 Value: openai.DecisionNewParamsQuestionChoiceChoiceValueUnion{OfString: openai.String("shipping")},

440 Description: openai.String("Delivery and tracking."),

441 },

442 {

443 Value: openai.DecisionNewParamsQuestionChoiceChoiceValueUnion{OfString: openai.String("other")},

444 Description: openai.String("Requests outside these categories."),

445 },

446 },

447 },

448 }},

449 })

450 if err != nil {

451 panic(err)

452 }

453 switch answer := decision.Answers[0].AsAny().(type) {

454 case openai.DecisionAnswerChoice:

455 fmt.Println(answer.Choice.AsString(), answer.Confidence, answer.Probabilities)

456 case openai.DecisionAnswerRefusal:

457 fmt.Printf("Decision refused for %s\n", answer.Name)

458 default:

459 panic("unexpected answer type")

460 }

461}

462```

463 

464```java

465import com.openai.models.decisions.DecisionChoiceOption;

466import com.openai.models.decisions.DecisionCreateParams;

467import com.openai.models.decisions.DecisionCreateParams.Question.Choice;

468 

469var decision =

470 client

471 .decisions()

472 .create(

473 DecisionCreateParams.builder()

474 .model("gpt-6-luna")

475 .input("I was charged twice for my order.")

476 .addQuestion(

477 Choice.builder()

478 .name("department")

479 .instructions("Which department should handle this complaint?")

480 .addChoice(

481 DecisionChoiceOption.builder()

482 .value("billing")

483 .description("Payments, invoices, and refunds.")

484 .build())

485 .addChoice(

486 DecisionChoiceOption.builder()

487 .value("technical")

488 .description("Problems using the product.")

489 .build())

490 .addChoice(

491 DecisionChoiceOption.builder()

492 .value("shipping")

493 .description("Delivery and tracking.")

494 .build())

495 .addChoice(

496 DecisionChoiceOption.builder()

497 .value("other")

498 .description("Requests outside these categories.")

499 .build())

500 .build())

501 .build());

502 

503var answer = decision.answers().get(0);

504if (answer.isRefusal()) {

505 System.out.println("Refused: " + answer.asRefusal().name().orElse("department"));

506} else {

507 var choice = answer.asChoice();

508 System.out.println(choice.choice().asString());

509 System.out.println(choice.probabilities());

510 System.out.println(choice.confidence());

511}

512```

513 

514```ruby

515require "openai"

516 

517client = OpenAI::Client.new

518decision = client.decisions.create(

519 model: "gpt-6-luna",

520 input: "I was charged twice for my order.",

521 questions: [

522 {

523 type: :choice,

524 name: "department",

525 instructions: "Which department should handle this complaint?",

526 choices: [

527 {

528 value: "billing",

529 description: "Payments, invoices, and refunds."

530 },

531 {

532 value: "technical",

533 description: "Problems using the product."

534 },

535 {

536 value: "shipping",

537 description: "Delivery and tracking."

538 },

539 {

540 value: "other",

541 description: "Requests outside these categories."

542 }

543 ]

544 }

545 ]

546)

547 

548answer = decision.answers.fetch(0)

549case answer

550when OpenAI::Models::Decision::Answer::Choice

551 puts(answer.choice, answer.confidence, answer.probabilities)

552when OpenAI::Models::Decision::Answer::Refusal

553 warn("Decision refused for #{answer.name}")

554else

555 raise("Unexpected answer type: #{answer.type}")

556end

557```

558 

559 

115An illustrative response excerpt:560An illustrative response excerpt:

116 561 

117```json562```json


143 588 

144 589 

145 590 

591Score an issue against severity levels

592 

146```bash593```bash

147curl https://api.openai.com/v1/decisions \594curl https://api.openai.com/v1/decisions \

148 -H "Authorization: Bearer $OPENAI_API_KEY" \595 -H "Authorization: Bearer $OPENAI_API_KEY" \


163 }'610 }'

164```611```

165 612 

613```javascript

614import OpenAI from "openai";

615 

616const client = new OpenAI();

617const decision = await client.decisions.create({

618 model: "gpt-6-luna",

619 input: "Export fails in Safari but works in Chrome.",

620 questions: [

621 {

622 type: "score",

623 name: "severity",

624 instructions: "How severe is this issue?",

625 levels: [

626 {

627 label: "Cosmetic",

628 description: "Appearance only; no lost functionality.",

629 },

630 {

631 label: "Workaround available",

632 description: "A task fails, but another way works.",

633 },

634 {

635 label: "Fully blocked",

636 description: "A task fails with no workaround.",

637 },

638 ],

639 },

640 ],

641});

642 

643const answer = decision.answers[0];

644if (answer.type === "refusal") {

645 console.log(`Refused: ${answer.name}`);

646} else if (answer.type === "score") {

647 console.log(`Severity: ${answer.score} (confidence: ${answer.confidence})`);

648}

649```

650 

651```python

652from openai import OpenAI

653 

654client = OpenAI()

655decision = client.decisions.create(

656 model="gpt-6-luna",

657 input="Export fails in Safari but works in Chrome.",

658 questions=[

659 {

660 "type": "score",

661 "name": "severity",

662 "instructions": "How severe is this issue?",

663 "levels": [

664 {

665 "label": "Cosmetic",

666 "description": "Appearance only; no lost functionality.",

667 },

668 {

669 "label": "Workaround available",

670 "description": "A task fails, but another way works.",

671 },

672 {

673 "label": "Fully blocked",

674 "description": "A task fails with no workaround.",

675 },

676 ],

677 }

678 ],

679)

680 

681answer = decision.answers[0]

682if answer.type == "refusal":

683 print(f"Refused: {answer.name}")

684elif answer.type == "score":

685 print(f"Severity: {answer.score} (confidence: {answer.confidence})")

686```

687 

688```go

689package main

690 

691import (

692 "context"

693 "fmt"

694 

695 "github.com/openai/openai-go/v3"

696)

697 

698func main() {

699 client := openai.NewClient()

700 decision, err := client.Decisions.New(context.Background(), openai.DecisionNewParams{

701 Model: "gpt-6-luna",

702 Input: openai.DecisionNewParamsInputUnion{OfString: openai.String("Export fails in Safari but works in Chrome.")},

703 Questions: []openai.DecisionNewParamsQuestionUnion{{

704 OfScore: &openai.DecisionNewParamsQuestionScore{

705 Name: openai.String("severity"),

706 Instructions: "How severe is this issue?",

707 Levels: []openai.DecisionNewParamsQuestionScoreLevel{

708 {Label: "Cosmetic", Description: openai.String("Appearance only; no lost functionality.")},

709 {Label: "Workaround available", Description: openai.String("A task fails, but another way works.")},

710 {Label: "Fully blocked", Description: openai.String("A task fails with no workaround.")},

711 },

712 },

713 }},

714 })

715 if err != nil {

716 panic(err)

717 }

718 switch answer := decision.Answers[0].AsAny().(type) {

719 case openai.DecisionAnswerScore:

720 fmt.Println(answer.Score, answer.Confidence, answer.Probabilities)

721 case openai.DecisionAnswerRefusal:

722 fmt.Printf("Decision refused for %s\n", answer.Name)

723 default:

724 panic("unexpected answer type")

725 }

726}

727```

728 

729```java

730import com.openai.models.decisions.DecisionCreateParams;

731import com.openai.models.decisions.DecisionCreateParams.Question.Score;

732 

733var decision =

734 client

735 .decisions()

736 .create(

737 DecisionCreateParams.builder()

738 .model("gpt-6-luna")

739 .input("Export fails in Safari but works in Chrome.")

740 .addQuestion(

741 Score.builder()

742 .name("severity")

743 .instructions("How severe is this issue?")

744 .addLevel(

745 Score.Level.builder()

746 .label("Cosmetic")

747 .description("Appearance only; no lost functionality.")

748 .build())

749 .addLevel(

750 Score.Level.builder()

751 .label("Workaround available")

752 .description("A task fails, but another way works.")

753 .build())

754 .addLevel(

755 Score.Level.builder()

756 .label("Fully blocked")

757 .description("A task fails with no workaround.")

758 .build())

759 .build())

760 .build());

761 

762var answer = decision.answers().get(0);

763if (answer.isRefusal()) {

764 System.out.println("Refused: " + answer.asRefusal().name().orElse("severity"));

765} else {

766 var score = answer.asScore();

767 System.out.println(score.score());

768 System.out.println(score.probabilities());

769 System.out.println(score.confidence());

770}

771```

772 

773```ruby

774require "openai"

775 

776client = OpenAI::Client.new

777decision = client.decisions.create(

778 model: "gpt-6-luna",

779 input: "Export fails in Safari but works in Chrome.",

780 questions: [

781 {

782 type: :score,

783 name: "severity",

784 instructions: "How severe is this issue?",

785 levels: [

786 {

787 label: "Cosmetic",

788 description: "Appearance only; no lost functionality."

789 },

790 {

791 label: "Workaround available",

792 description: "A task fails, but another way works."

793 },

794 {

795 label: "Fully blocked",

796 description: "A task fails with no workaround."

797 }

798 ]

799 }

800 ]

801)

802 

803answer = decision.answers.fetch(0)

804case answer

805when OpenAI::Models::Decision::Answer::Score

806 puts(answer.score, answer.confidence, answer.probabilities)

807when OpenAI::Models::Decision::Answer::Refusal

808 warn("Decision refused for #{answer.name}")

809else

810 raise("Unexpected answer type: #{answer.type}")

811end

812```

813 

814 

166An illustrative response excerpt:815An illustrative response excerpt:

167 816 

168```json817```json

Details

1800The JavaScript sample uses `npm install openai@^7.10.0 ws`.1800The JavaScript sample uses `npm install openai@^7.10.0 ws`.

1801The Ruby sample uses `gem install openai async-websocket`.1801The Ruby sample uses `gem install openai async-websocket`.

1802 1802 

1803For Go, run `go get github.com/openai/openai-go/v3@v3.70.0`.1803For Go, run `go get github.com/openai/openai-go/v3@v3.73.0`.

1804For Java, add the Maven dependency `com.openai:openai-java:4.75.1`.1804For Java, add the Maven dependency `com.openai:openai-java:4.78.0`.

1805These Go and Java SDK versions provide native Responses WebSocket support.1805These Go and Java SDK versions provide native Responses WebSocket support.

1806 1806 

1807Start a Responses API WebSocket session1807Start a Responses API WebSocket session

guides/tools.md +29 −29

Details

841 "tools": [841 "tools": [

842 {842 {

843 "type": "mcp",843 "type": "mcp",

844 "server_label": "dmcp",844 "server_label": "openai_docs",

845 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",845 "server_description": "Search and read the public OpenAI documentation.",

846 "server_url": "https://dmcp-server.deno.dev/mcp",846 "server_url": "https://developers.openai.com/mcp",

847 "require_approval": "never"847 "require_approval": "never"

848 }848 }

849 ],849 ],

850 "input": "Roll 2d4+1"850 "input": "Search the OpenAI docs for Responses API streaming and return the relevant links."

851 }'851 }'

852```852```

853 853 


860 tools: [860 tools: [

861 {861 {

862 type: "mcp",862 type: "mcp",

863 server_label: "dmcp",863 server_label: "openai_docs",

864 server_description:864 server_description: "Search and read the public OpenAI documentation.",

865 "A Dungeons and Dragons MCP server to assist with dice rolling.",865 server_url: "https://developers.openai.com/mcp",

866 server_url: "https://dmcp-server.deno.dev/mcp",

867 require_approval: "never",866 require_approval: "never",

868 },867 },

869 ],868 ],

870 input: "Roll 2d4+1",869 input:

870 "Search the OpenAI docs for Responses API streaming and return the relevant links.",

871});871});

872 872 

873console.log(resp.output_text);873console.log(resp.output_text);


883 tools=[883 tools=[

884 {884 {

885 "type": "mcp",885 "type": "mcp",

886 "server_label": "dmcp",886 "server_label": "openai_docs",

887 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",887 "server_description": "Search and read the public OpenAI documentation.",

888 "server_url": "https://dmcp-server.deno.dev/mcp",888 "server_url": "https://developers.openai.com/mcp",

889 "require_approval": "never",889 "require_approval": "never",

890 },890 },

891 ],891 ],

892 input="Roll 2d4+1",892 input="Search the OpenAI docs for Responses API streaming and return the relevant links.",

893)893)

894 894 

895print(resp.output_text)895print(resp.output_text)


908 908 

909func main() {909func main() {

910 client := openai.NewClient()910 client := openai.NewClient()

911 tool := responses.ToolParamOfMcp("dmcp")911 tool := responses.ToolParamOfMcp("openai_docs")

912 tool.OfMcp.ServerDescription = openai.String("A Dungeons and Dragons MCP server to assist with dice rolling.")912 tool.OfMcp.ServerDescription = openai.String("Search and read the public OpenAI documentation.")

913 tool.OfMcp.ServerURL = openai.String("https://dmcp-server.deno.dev/mcp")913 tool.OfMcp.ServerURL = openai.String("https://developers.openai.com/mcp")

914 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}914 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}

915 915 

916 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{916 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{

917 Model: "gpt-6-astra",917 Model: "gpt-6-astra",

918 Tools: []responses.ToolUnionParam{tool},918 Tools: []responses.ToolUnionParam{tool},

919 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Roll 2d4+1")},919 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Search the OpenAI docs for Responses API streaming and return the relevant links.")},

920 })920 })

921 if err != nil {921 if err != nil {

922 panic(err)922 panic(err)


934ResponseCreateParams params =934ResponseCreateParams params =

935 ResponseCreateParams.builder()935 ResponseCreateParams.builder()

936 .model("gpt-6-astra")936 .model("gpt-6-astra")

937 .input("Roll 2d4+1")937 .input(

938 "Search the OpenAI docs for Responses API streaming and return the relevant links.")

938 .addTool(939 .addTool(

939 Tool.Mcp.builder()940 Tool.Mcp.builder()

940 .serverLabel("dmcp")941 .serverLabel("openai_docs")

941 .serverDescription(942 .serverDescription("Search and read the public OpenAI documentation.")

942 "A Dungeons and Dragons MCP server to assist with dice rolling.")943 .serverUrl("https://developers.openai.com/mcp")

943 .serverUrl("https://dmcp-server.deno.dev/mcp")

944 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)944 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)

945 .build())945 .build())

946 .build();946 .build();


962CreateResponseOptions options = new() { Model = "gpt-6-astra" };962CreateResponseOptions options = new() { Model = "gpt-6-astra" };

963options.Tools.Add(963options.Tools.Add(

964 ResponseTool.CreateMcpTool(964 ResponseTool.CreateMcpTool(

965 serverLabel: "dmcp",965 serverLabel: "openai_docs",

966 serverUri: new Uri("https://dmcp-server.deno.dev/mcp"),966 serverUri: new Uri("https://developers.openai.com/mcp"),

967 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval967 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval

968 )968 )

969);969);

970options.InputItems.Add(ResponseItem.CreateUserMessageItem("Roll 2d4+1"));970options.InputItems.Add(ResponseItem.CreateUserMessageItem("Search the OpenAI docs for Responses API streaming and return the relevant links."));

971 971 

972ResponseResult response = await client.CreateResponseAsync(options);972ResponseResult response = await client.CreateResponseAsync(options);

973 973 


984 tools: [984 tools: [

985 {985 {

986 type: "mcp",986 type: "mcp",

987 server_label: "dmcp",987 server_label: "openai_docs",

988 server_description: "A Dungeons and Dragons MCP server to assist with dice rolling.",988 server_description: "Search and read the public OpenAI documentation.",

989 server_url: "https://dmcp-server.deno.dev/mcp",989 server_url: "https://developers.openai.com/mcp",

990 require_approval: "never"990 require_approval: "never"

991 }991 }

992 ],992 ],

993 input: "Roll 2d4+1"993 input: "Search the OpenAI docs for Responses API streaming and return the relevant links."

994)994)

995 995 

996puts(response.output_text)996puts(response.output_text)

Details

18 18 

19Use the `mcp` tool type in the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create). Set `server_url` for a remote MCP server, or use `tunnel_id` for a local MCP server through [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels). Depending on the server, you may also need an OAuth access token in the `authorization` parameter.19Use the `mcp` tool type in the [Responses API](https://developers.openai.com/api/reference/resources/responses/methods/create). Set `server_url` for a remote MCP server, or use `tunnel_id` for a local MCP server through [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels). Depending on the server, you may also need an OAuth access token in the `authorization` parameter.

20 20 

21The following example uses the public [OpenAI Docs MCP server](https://developers.openai.com/resources/docs-mcp) to find documentation about streaming Responses API output. This server provides read-only documentation tools and does not require authentication. The example skips tool-call approvals for this public documentation query; use approvals when sharing sensitive data.

22 

21Using a remote MCP server in the Responses API23Using a remote MCP server in the Responses API

22 24 

23```bash25```bash


29 "tools": [31 "tools": [

30 {32 {

31 "type": "mcp",33 "type": "mcp",

32 "server_label": "dmcp",34 "server_label": "openai_docs",

33 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",35 "server_description": "Search and read the public OpenAI documentation.",

34 "server_url": "https://dmcp-server.deno.dev/mcp",36 "server_url": "https://developers.openai.com/mcp",

35 "require_approval": "never"37 "require_approval": "never"

36 }38 }

37 ],39 ],

38 "input": "Roll 2d4+1"40 "input": "Search the OpenAI docs for Responses API streaming and return the relevant links."

39 }'41 }'

40```42```

41 43 


48 tools: [50 tools: [

49 {51 {

50 type: "mcp",52 type: "mcp",

51 server_label: "dmcp",53 server_label: "openai_docs",

52 server_description:54 server_description: "Search and read the public OpenAI documentation.",

53 "A Dungeons and Dragons MCP server to assist with dice rolling.",55 server_url: "https://developers.openai.com/mcp",

54 server_url: "https://dmcp-server.deno.dev/mcp",

55 require_approval: "never",56 require_approval: "never",

56 },57 },

57 ],58 ],

58 input: "Roll 2d4+1",59 input:

60 "Search the OpenAI docs for Responses API streaming and return the relevant links.",

59});61});

60 62 

61console.log(resp.output_text);63console.log(resp.output_text);


71 tools=[73 tools=[

72 {74 {

73 "type": "mcp",75 "type": "mcp",

74 "server_label": "dmcp",76 "server_label": "openai_docs",

75 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",77 "server_description": "Search and read the public OpenAI documentation.",

76 "server_url": "https://dmcp-server.deno.dev/mcp",78 "server_url": "https://developers.openai.com/mcp",

77 "require_approval": "never",79 "require_approval": "never",

78 },80 },

79 ],81 ],

80 input="Roll 2d4+1",82 input="Search the OpenAI docs for Responses API streaming and return the relevant links.",

81)83)

82 84 

83print(resp.output_text)85print(resp.output_text)


96 98 

97func main() {99func main() {

98 client := openai.NewClient()100 client := openai.NewClient()

99 tool := responses.ToolParamOfMcp("dmcp")101 tool := responses.ToolParamOfMcp("openai_docs")

100 tool.OfMcp.ServerDescription = openai.String("A Dungeons and Dragons MCP server to assist with dice rolling.")102 tool.OfMcp.ServerDescription = openai.String("Search and read the public OpenAI documentation.")

101 tool.OfMcp.ServerURL = openai.String("https://dmcp-server.deno.dev/mcp")103 tool.OfMcp.ServerURL = openai.String("https://developers.openai.com/mcp")

102 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}104 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}

103 105 

104 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{106 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{

105 Model: "gpt-6-astra",107 Model: "gpt-6-astra",

106 Tools: []responses.ToolUnionParam{tool},108 Tools: []responses.ToolUnionParam{tool},

107 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Roll 2d4+1")},109 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Search the OpenAI docs for Responses API streaming and return the relevant links.")},

108 })110 })

109 if err != nil {111 if err != nil {

110 panic(err)112 panic(err)


122ResponseCreateParams params =124ResponseCreateParams params =

123 ResponseCreateParams.builder()125 ResponseCreateParams.builder()

124 .model("gpt-6-astra")126 .model("gpt-6-astra")

125 .input("Roll 2d4+1")127 .input(

128 "Search the OpenAI docs for Responses API streaming and return the relevant links.")

126 .addTool(129 .addTool(

127 Tool.Mcp.builder()130 Tool.Mcp.builder()

128 .serverLabel("dmcp")131 .serverLabel("openai_docs")

129 .serverDescription(132 .serverDescription("Search and read the public OpenAI documentation.")

130 "A Dungeons and Dragons MCP server to assist with dice rolling.")133 .serverUrl("https://developers.openai.com/mcp")

131 .serverUrl("https://dmcp-server.deno.dev/mcp")

132 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)134 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)

133 .build())135 .build())

134 .build();136 .build();


150CreateResponseOptions options = new() { Model = "gpt-6-astra" };152CreateResponseOptions options = new() { Model = "gpt-6-astra" };

151options.Tools.Add(153options.Tools.Add(

152 ResponseTool.CreateMcpTool(154 ResponseTool.CreateMcpTool(

153 serverLabel: "dmcp",155 serverLabel: "openai_docs",

154 serverUri: new Uri("https://dmcp-server.deno.dev/mcp"),156 serverUri: new Uri("https://developers.openai.com/mcp"),

155 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval157 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval

156 )158 )

157);159);

158options.InputItems.Add(ResponseItem.CreateUserMessageItem("Roll 2d4+1"));160options.InputItems.Add(ResponseItem.CreateUserMessageItem("Search the OpenAI docs for Responses API streaming and return the relevant links."));

159 161 

160ResponseResult response = await client.CreateResponseAsync(options);162ResponseResult response = await client.CreateResponseAsync(options);

161 163 


172 tools: [174 tools: [

173 {175 {

174 type: "mcp",176 type: "mcp",

175 server_label: "dmcp",177 server_label: "openai_docs",

176 server_description: "A Dungeons and Dragons MCP server to assist with dice rolling.",178 server_description: "Search and read the public OpenAI documentation.",

177 server_url: "https://dmcp-server.deno.dev/mcp",179 server_url: "https://developers.openai.com/mcp",

178 require_approval: "never"180 require_approval: "never"

179 }181 }

180 ],182 ],

181 input: "Roll 2d4+1"183 input: "Search the OpenAI docs for Responses API streaming and return the relevant links."

182)184)

183 185 

184puts(response.output_text)186puts(response.output_text)


190 anything that enters the model's context. Carefully review the 192 anything that enters the model's context. Carefully review the

191 **Risks and Safety** section below before using this tool.193 **Risks and Safety** section below before using this tool.

192 194 

193The API will return new items in the `output` array of the model response. If the model decides to use an MCP server, it will first make a request to list available tools from the server, which will create a `mcp_list_tools` output item. From the remote MCP server example above, it contains only one tool definition:195The API will return new items in the `output` array of the model response. If the model decides to use an MCP server, it will first make a request to list available tools from the server, which will create a `mcp_list_tools` output item. The following illustrative output shows only the search tool, with its description shortened. The server also exposes other documentation tools.

194 196 

195```json197```json

196{198{

197 "id": "mcpl_68a6102a4968819c8177b05584dd627b0679e572a900e618",199 "id": "mcpl_68a6102a4968819c8177b05584dd627b0679e572a900e618",

198 "type": "mcp_list_tools",200 "type": "mcp_list_tools",

199 "server_label": "dmcp",201 "server_label": "openai_docs",

200 "tools": [202 "tools": [

201 {203 {

202 "annotations": null,204 "annotations": {

203 "description": "Given a string of text describing a dice roll...",205 "readOnlyHint": true,

206 "destructiveHint": false

207 },

208 "description": "Search the public OpenAI documentation.",

204 "input_schema": {209 "input_schema": {

205 "$schema": "https://json-schema.org/draft/2020-12/schema",210 "$schema": "http://json-schema.org/draft-07/schema#",

206 "type": "object",211 "type": "object",

207 "properties": {212 "properties": {

208 "diceRollExpression": {213 "query": {

214 "type": "string",

215 "minLength": 1

216 },

217 "limit": {

218 "type": "integer",

219 "minimum": 1,

220 "maximum": 50

221 },

222 "cursor": {

209 "type": "string"223 "type": "string"

210 }224 }

211 },225 },

212 "required": ["diceRollExpression"],226 "required": ["query"]

213 "additionalProperties": false

214 },227 },

215 "name": "roll"228 "name": "search_openai_docs"

216 }229 }

217 ]230 ]

218}231}


225 "id": "mcp_68a6102d8948819c9b1490d36d5ffa4a0679e572a900e618",238 "id": "mcp_68a6102d8948819c9b1490d36d5ffa4a0679e572a900e618",

226 "type": "mcp_call",239 "type": "mcp_call",

227 "approval_request_id": null,240 "approval_request_id": null,

228 "arguments": "{\"diceRollExpression\":\"2d4 + 1\"}",241 "arguments": "{\"query\":\"Responses API streaming\",\"limit\":1}",

229 "error": null,242 "error": null,

230 "name": "roll",243 "name": "search_openai_docs",

231 "output": "4",244 "output": "{\"hits\":[{\"url\":\"https://developers.openai.com/api/docs/guides/streaming-responses\"}]}",

232 "server_label": "dmcp"245 "server_label": "openai_docs"

233}246}

234```247```

235 248 


245 258 

246When you specify a remote MCP server in the `tools` parameter, the API will attempt to get a list of tools from the server. The Responses API works with remote MCP servers that support either the Streamable HTTP or the HTTP/SSE transport protocols.259When you specify a remote MCP server in the `tools` parameter, the API will attempt to get a list of tools from the server. The Responses API works with remote MCP servers that support either the Streamable HTTP or the HTTP/SSE transport protocols.

247 260 

248If successful in retrieving the list of tools, a new `mcp_list_tools` output item will appear in the model response output. The `tools` property of this object will show the tools that were successfully imported.261If successful in retrieving the list of tools, a new `mcp_list_tools` output item will appear in the model response output. The `tools` property of this object will show the tools that were successfully imported. This illustrative excerpt shows only the search tool, with its description shortened.

249 262 

250```json263```json

251{264{

252 "id": "mcpl_68a6102a4968819c8177b05584dd627b0679e572a900e618",265 "id": "mcpl_68a6102a4968819c8177b05584dd627b0679e572a900e618",

253 "type": "mcp_list_tools",266 "type": "mcp_list_tools",

254 "server_label": "dmcp",267 "server_label": "openai_docs",

255 "tools": [268 "tools": [

256 {269 {

257 "annotations": null,270 "annotations": {

258 "description": "Given a string of text describing a dice roll...",271 "readOnlyHint": true,

272 "destructiveHint": false

273 },

274 "description": "Search the public OpenAI documentation.",

259 "input_schema": {275 "input_schema": {

260 "$schema": "https://json-schema.org/draft/2020-12/schema",276 "$schema": "http://json-schema.org/draft-07/schema#",

261 "type": "object",277 "type": "object",

262 "properties": {278 "properties": {

263 "diceRollExpression": {279 "query": {

280 "type": "string",

281 "minLength": 1

282 },

283 "limit": {

284 "type": "integer",

285 "minimum": 1,

286 "maximum": 50

287 },

288 "cursor": {

264 "type": "string"289 "type": "string"

265 }290 }

266 },291 },

267 "required": ["diceRollExpression"],292 "required": ["query"]

268 "additionalProperties": false

269 },293 },

270 "name": "roll"294 "name": "search_openai_docs"

271 }295 }

272 ]296 ]

273}297}


281 305 

282#### Filtering tools306#### Filtering tools

283 307 

284Some MCP servers can have dozens of tools, and exposing many tools to the model can result in high cost and latency. If you're only interested in a subset of tools an MCP server exposes, you can use the `allowed_tools` parameter to only import those tools.308Some MCP servers can have dozens of tools, and exposing many tools to the model can result in high cost and latency. If you're only interested in a subset of tools an MCP server exposes, you can use the `allowed_tools` parameter to only import those tools. This example imports only `search_openai_docs` to find documentation links.

285 309 

286Constrain allowed tools310Constrain allowed tools

287 311 


294 "tools": [318 "tools": [

295 {319 {

296 "type": "mcp",320 "type": "mcp",

297 "server_label": "dmcp",321 "server_label": "openai_docs",

298 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",322 "server_description": "Search and read the public OpenAI documentation.",

299 "server_url": "https://dmcp-server.deno.dev/mcp",323 "server_url": "https://developers.openai.com/mcp",

300 "require_approval": "never",324 "require_approval": "never",

301 "allowed_tools": ["roll"]325 "allowed_tools": ["search_openai_docs"]

302 }326 }

303 ],327 ],

304 "input": "Roll 2d4+1"328 "input": "Search the OpenAI docs for Responses API streaming and return the relevant links."

305 }'329 }'

306```330```

307 331 


314 tools: [338 tools: [

315 {339 {

316 type: "mcp",340 type: "mcp",

317 server_label: "dmcp",341 server_label: "openai_docs",

318 server_description:342 server_description: "Search and read the public OpenAI documentation.",

319 "A Dungeons and Dragons MCP server to assist with dice rolling.",343 server_url: "https://developers.openai.com/mcp",

320 server_url: "https://dmcp-server.deno.dev/mcp",

321 require_approval: "never",344 require_approval: "never",

322 allowed_tools: ["roll"],345 allowed_tools: ["search_openai_docs"],

323 },346 },

324 ],347 ],

325 input: "Roll 2d4+1",348 input:

349 "Search the OpenAI docs for Responses API streaming and return the relevant links.",

326});350});

327 351 

328console.log(resp.output_text);352console.log(resp.output_text);


338 tools=[362 tools=[

339 {363 {

340 "type": "mcp",364 "type": "mcp",

341 "server_label": "dmcp",365 "server_label": "openai_docs",

342 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",366 "server_description": "Search and read the public OpenAI documentation.",

343 "server_url": "https://dmcp-server.deno.dev/mcp",367 "server_url": "https://developers.openai.com/mcp",

344 "require_approval": "never",368 "require_approval": "never",

345 "allowed_tools": ["roll"],369 "allowed_tools": ["search_openai_docs"],

346 }370 }

347 ],371 ],

348 input="Roll 2d4+1",372 input="Search the OpenAI docs for Responses API streaming and return the relevant links.",

349)373)

350 374 

351print(resp.output_text)375print(resp.output_text)


364 388 

365func main() {389func main() {

366 client := openai.NewClient()390 client := openai.NewClient()

367 tool := responses.ToolParamOfMcp("dmcp")391 tool := responses.ToolParamOfMcp("openai_docs")

368 tool.OfMcp.ServerDescription = openai.String("A Dungeons and Dragons MCP server to assist with dice rolling.")392 tool.OfMcp.ServerDescription = openai.String("Search and read the public OpenAI documentation.")

369 tool.OfMcp.ServerURL = openai.String("https://dmcp-server.deno.dev/mcp")393 tool.OfMcp.ServerURL = openai.String("https://developers.openai.com/mcp")

370 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}394 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}

371 tool.OfMcp.AllowedTools = responses.ToolMcpAllowedToolsUnionParam{OfMcpAllowedTools: []string{"roll"}}395 tool.OfMcp.AllowedTools = responses.ToolMcpAllowedToolsUnionParam{OfMcpAllowedTools: []string{"search_openai_docs"}}

372 396 

373 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{397 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{

374 Model: "gpt-6-astra",398 Model: "gpt-6-astra",

375 Tools: []responses.ToolUnionParam{tool},399 Tools: []responses.ToolUnionParam{tool},

376 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Roll 2d4+1")},400 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Search the OpenAI docs for Responses API streaming and return the relevant links.")},

377 })401 })

378 if err != nil {402 if err != nil {

379 panic(err)403 panic(err)


392ResponseCreateParams params =416ResponseCreateParams params =

393 ResponseCreateParams.builder()417 ResponseCreateParams.builder()

394 .model("gpt-6-astra")418 .model("gpt-6-astra")

395 .input("Roll 2d4+1")419 .input(

420 "Search the OpenAI docs for Responses API streaming and return the relevant links.")

396 .addTool(421 .addTool(

397 Tool.Mcp.builder()422 Tool.Mcp.builder()

398 .serverLabel("dmcp")423 .serverLabel("openai_docs")

399 .serverDescription(424 .serverDescription("Search and read the public OpenAI documentation.")

400 "A Dungeons and Dragons MCP server to assist with dice rolling.")425 .serverUrl("https://developers.openai.com/mcp")

401 .serverUrl("https://dmcp-server.deno.dev/mcp")

402 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)426 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)

403 .allowedToolsOfMcp(List.of("roll"))427 .allowedToolsOfMcp(List.of("search_openai_docs"))

404 .build())428 .build())

405 .build();429 .build();

406 430 


421CreateResponseOptions options = new() { Model = "gpt-6-astra" };445CreateResponseOptions options = new() { Model = "gpt-6-astra" };

422options.Tools.Add(446options.Tools.Add(

423 ResponseTool.CreateMcpTool(447 ResponseTool.CreateMcpTool(

424 serverLabel: "dmcp",448 serverLabel: "openai_docs",

425 serverUri: new Uri("https://dmcp-server.deno.dev/mcp"),449 serverUri: new Uri("https://developers.openai.com/mcp"),

426 allowedTools: new McpToolFilter() { ToolNames = { "roll" } },450 allowedTools: new McpToolFilter() { ToolNames = { "search_openai_docs" } },

427 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval451 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval

428 )452 )

429);453);

430options.InputItems.Add(ResponseItem.CreateUserMessageItem("Roll 2d4+1"));454options.InputItems.Add(ResponseItem.CreateUserMessageItem("Search the OpenAI docs for Responses API streaming and return the relevant links."));

431 455 

432ResponseResult response = await client.CreateResponseAsync(options);456ResponseResult response = await client.CreateResponseAsync(options);

433 457 


441 465 

442response = client.responses.create(466response = client.responses.create(

443 model: "gpt-6-astra",467 model: "gpt-6-astra",

444 input: "Roll 2d4+1",468 input: "Search the OpenAI docs for Responses API streaming and return the relevant links.",

445 tools: [469 tools: [

446 {470 {

447 type: :mcp,471 type: :mcp,

448 server_label: "dmcp",472 server_label: "openai_docs",

449 server_description: "A Dungeons and Dragons MCP server to assist with dice rolling.",473 server_description: "Search and read the public OpenAI documentation.",

450 server_url: "https://dmcp-server.deno.dev/mcp",474 server_url: "https://developers.openai.com/mcp",

451 require_approval: :never,475 require_approval: :never,

452 allowed_tools: ["roll"]476 allowed_tools: ["search_openai_docs"]

453 }477 }

454 ]478 ]

455)479)


460 484 

461### Step 2: Calling tools485### Step 2: Calling tools

462 486 

463Once the model has access to these tool definitions, it may choose to call them depending on what's in the model's context. When the model decides to call an MCP tool, the API will make an request to the remote MCP server to call the tool and put its output into the model's context. This creates an `mcp_call` item which looks like this:487Once the model has access to these tool definitions, it may choose to call them depending on what's in the model's context. When the model decides to call an MCP tool, the API will make a request to the remote MCP server to call the tool and put its output into the model's context. This creates an `mcp_call` item. The following illustrative output omits search-result metadata for brevity:

464 488 

465```json489```json

466{490{

467 "id": "mcp_68a6102d8948819c9b1490d36d5ffa4a0679e572a900e618",491 "id": "mcp_68a6102d8948819c9b1490d36d5ffa4a0679e572a900e618",

468 "type": "mcp_call",492 "type": "mcp_call",

469 "approval_request_id": null,493 "approval_request_id": null,

470 "arguments": "{\"diceRollExpression\":\"2d4 + 1\"}",494 "arguments": "{\"query\":\"Responses API streaming\",\"limit\":1}",

471 "error": null,495 "error": null,

472 "name": "roll",496 "name": "search_openai_docs",

473 "output": "4",497 "output": "{\"hits\":[{\"url\":\"https://developers.openai.com/api/docs/guides/streaming-responses\"}]}",

474 "server_label": "dmcp"498 "server_label": "openai_docs"

475}499}

476```500```

477 501 


481 505 

482#### Approvals506#### Approvals

483 507 

484By default, OpenAI will request your approval before any data is shared with a connector or remote MCP server. Approvals help you maintain control and visibility over what data is being sent to an MCP server. We highly recommend that you carefully review (and optionally log) all data being shared with a remote MCP server. A request for an approval to make an MCP tool call creates a `mcp_approval_request` item in the Response's output that looks like this:508By default, OpenAI will request your approval before any data is shared with a connector or remote MCP server. Approvals help you maintain control and visibility over what data is being sent to an MCP server. We highly recommend that you carefully review (and optionally log) all data being shared with a remote MCP server. To try the approval flow, run the quickstart example with `require_approval` set to `"always"` instead of `"never"`. A request for an approval to make an MCP tool call creates a `mcp_approval_request` item in the Response's output. The following example is illustrative:

485 509 

486```json510```json

487{511{

488 "id": "mcpr_68a619e1d82c8190b50c1ccba7ad18ef0d2d23a86136d339",512 "id": "mcpr_682d498e3bd4819196a0ce1664f8e77b04ad1e533afccbfa",

489 "type": "mcp_approval_request",513 "type": "mcp_approval_request",

490 "arguments": "{\"diceRollExpression\":\"2d4 + 1\"}",514 "arguments": "{\"query\":\"Responses API streaming\",\"limit\":1}",

491 "name": "roll",515 "name": "search_openai_docs",

492 "server_label": "dmcp"516 "server_label": "openai_docs"

493}517}

494```518```

495 519 

496You can then respond to this by creating a new Response object and appending an `mcp_approval_response` item to it.520Review the requested tool and its arguments before approving. You can then respond by creating a new Response object and appending an `mcp_approval_response` item to it. Replace the illustrative response and approval-request IDs in the following examples with the IDs returned by your request. The .NET example obtains these IDs from its initial response. Each approval applies to one tool call; handle any subsequent approval requests in the same way.

497 521 

498Approving the use of tools in an API request522Approving the use of tools in an API request

499 523 


506 "tools": [530 "tools": [

507 {531 {

508 "type": "mcp",532 "type": "mcp",

509 "server_label": "dmcp",533 "server_label": "openai_docs",

510 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",534 "server_description": "Search and read the public OpenAI documentation.",

511 "server_url": "https://dmcp-server.deno.dev/mcp",535 "server_url": "https://developers.openai.com/mcp",

512 "require_approval": "always",536 "require_approval": "always"

513 }537 }

514 ],538 ],

515 "previous_response_id": "resp_682d498bdefc81918b4a6aa477bfafd904ad1e533afccbfa",539 "previous_response_id": "resp_682d498bdefc81918b4a6aa477bfafd904ad1e533afccbfa",


530 tools: [554 tools: [

531 {555 {

532 type: "mcp",556 type: "mcp",

533 server_label: "dmcp",557 server_label: "openai_docs",

534 server_description:558 server_description: "Search and read the public OpenAI documentation.",

535 "A Dungeons and Dragons MCP server to assist with dice rolling.",559 server_url: "https://developers.openai.com/mcp",

536 server_url: "https://dmcp-server.deno.dev/mcp",

537 require_approval: "always",560 require_approval: "always",

538 },561 },

539 ],562 ],


561 tools=[584 tools=[

562 {585 {

563 "type": "mcp",586 "type": "mcp",

564 "server_label": "dmcp",587 "server_label": "openai_docs",

565 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",588 "server_description": "Search and read the public OpenAI documentation.",

566 "server_url": "https://dmcp-server.deno.dev/mcp",589 "server_url": "https://developers.openai.com/mcp",

567 "require_approval": "always",590 "require_approval": "always",

568 }591 }

569 ],592 ],


593 616 

594func main() {617func main() {

595 client := openai.NewClient()618 client := openai.NewClient()

596 tool := responses.ToolParamOfMcp("dmcp")619 tool := responses.ToolParamOfMcp("openai_docs")

597 tool.OfMcp.ServerDescription = openai.String("A Dungeons and Dragons MCP server to assist with dice rolling.")620 tool.OfMcp.ServerDescription = openai.String("Search and read the public OpenAI documentation.")

598 tool.OfMcp.ServerURL = openai.String("https://dmcp-server.deno.dev/mcp")621 tool.OfMcp.ServerURL = openai.String("https://developers.openai.com/mcp")

599 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("always")}622 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("always")}

600 623 

601 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{624 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{


639 .previousResponseId(responseId)662 .previousResponseId(responseId)

640 .addTool(663 .addTool(

641 Tool.Mcp.builder()664 Tool.Mcp.builder()

642 .serverLabel("dmcp")665 .serverLabel("openai_docs")

643 .serverDescription("A Dungeons and Dragons MCP server.")666 .serverDescription("Search and read the public OpenAI documentation.")

644 .serverUrl("https://dmcp-server.deno.dev/mcp")667 .serverUrl("https://developers.openai.com/mcp")

645 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.ALWAYS)668 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.ALWAYS)

646 .build())669 .build())

647 .build();670 .build();


663CreateResponseOptions options = new() { Model = "gpt-6-astra" };686CreateResponseOptions options = new() { Model = "gpt-6-astra" };

664options.Tools.Add(687options.Tools.Add(

665 ResponseTool.CreateMcpTool(688 ResponseTool.CreateMcpTool(

666 serverLabel: "dmcp",689 serverLabel: "openai_docs",

667 serverUri: new Uri("https://dmcp-server.deno.dev/mcp"),690 serverUri: new Uri("https://developers.openai.com/mcp"),

668 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.AlwaysRequireApproval691 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.AlwaysRequireApproval

669 )692 )

670);693);

671 694 

672// Step 1: Create a response that requests tool-call approval.695// Step 1: Create a response that requests tool-call approval.

673options.InputItems.Add(ResponseItem.CreateUserMessageItem("Roll 2d4+1"));696options.InputItems.Add(ResponseItem.CreateUserMessageItem("Search the OpenAI docs for Responses API streaming and return the relevant links."));

674ResponseResult response1 = await client.CreateResponseAsync(options);697ResponseResult response1 = await client.CreateResponseAsync(options);

675 698 

676McpToolCallApprovalRequestItem approvalRequest =699McpToolCallApprovalRequestItem approvalRequest =


704 tools: [727 tools: [

705 {728 {

706 type: :mcp,729 type: :mcp,

707 server_label: "dmcp",730 server_label: "openai_docs",

708 server_url: "https://dmcp-server.deno.dev/mcp",731 server_url: "https://developers.openai.com/mcp",

709 server_description: "A Dungeons and Dragons MCP server.",732 server_description: "Search and read the public OpenAI documentation.",

710 require_approval: :always733 require_approval: :always

711 }734 }

712 ]735 ]


917 940 

918## Authentication941## Authentication

919 942 

920Unlike the [example MCP server we used above](https://dash.deno.com/playground/dmcp-server), most other MCP servers require authentication. The most common scheme is an OAuth access token. Provide this token using the `authorization` field of the MCP tool:943The [OpenAI Docs MCP server](https://developers.openai.com/resources/docs-mcp) does not require authentication. Other MCP servers may require authentication. The most common scheme is an OAuth access token. Provide this token using the `authorization` field of the MCP tool:

921 944 

922Use Stripe MCP tool945Use Stripe MCP tool

923 946 


1851```json1874```json

1852{1875{

1853 "type": "mcp",1876 "type": "mcp",

1854 "server_label": "dmcp",1877 "server_label": "openai_docs",

1855 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",1878 "server_description": "Search and read the public OpenAI documentation.",

1856 "server_url": "https://dmcp-server.deno.dev/mcp",1879 "server_url": "https://developers.openai.com/mcp",

1857// highlight-start:subtle1880// highlight-start:subtle

1858 "defer_loading": true,1881 "defer_loading": true,

1859// highlight-end1882// highlight-end

Details

16 16 

17Install the WebSocket dependencies with `pip install "openai[realtime]>=3.8.0"` for Python, `npm install openai@^7.10.0 ws` for JavaScript, or `gem install openai async-websocket` for Ruby.17Install the WebSocket dependencies with `pip install "openai[realtime]>=3.8.0"` for Python, `npm install openai@^7.10.0 ws` for JavaScript, or `gem install openai async-websocket` for Ruby.

18 18 

19For Go, run `go get github.com/openai/openai-go/v3@v3.70.0`.19For Go, run `go get github.com/openai/openai-go/v3@v3.73.0`.

20For Java, add the Maven dependency `com.openai:openai-java:4.75.1`.20For Java, add the Maven dependency `com.openai:openai-java:4.78.0`.

21These Go and Java SDK versions provide native Responses WebSocket support.21These Go and Java SDK versions provide native Responses WebSocket support.

22 22 

23In WebSocket mode, start each turn by sending a `response.create` event from the client. The payload mirrors the normal [Responses create body](https://developers.openai.com/api/reference/resources/responses/methods/create), except that transport-specific fields like `stream` and `background` are not used.23In WebSocket mode, start each turn by sending a `response.create` event from the client. The payload mirrors the normal [Responses create body](https://developers.openai.com/api/reference/resources/responses/methods/create), except that transport-specific fields like `stream` and `background` are not used.

libraries.md +1 −1

Details

173<dependency>173<dependency>

174 <groupId>com.openai</groupId>174 <groupId>com.openai</groupId>

175 <artifactId>openai-java</artifactId>175 <artifactId>openai-java</artifactId>

176 <version>4.77.0</version>176 <version>4.78.0</version>

177</dependency>177</dependency>

178```178```

179 179 

quickstart.md +30 −30

Details

190<dependency>190<dependency>

191 <groupId>com.openai</groupId>191 <groupId>com.openai</groupId>

192 <artifactId>openai-java</artifactId>192 <artifactId>openai-java</artifactId>

193 <version>4.77.0</version>193 <version>4.78.0</version>

194</dependency>194</dependency>

195```195```

196 196 


1836 "tools": [1836 "tools": [

1837 {1837 {

1838 "type": "mcp",1838 "type": "mcp",

1839 "server_label": "dmcp",1839 "server_label": "openai_docs",

1840 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",1840 "server_description": "Search and read the public OpenAI documentation.",

1841 "server_url": "https://dmcp-server.deno.dev/mcp",1841 "server_url": "https://developers.openai.com/mcp",

1842 "require_approval": "never"1842 "require_approval": "never"

1843 }1843 }

1844 ],1844 ],

1845 "input": "Roll 2d4+1"1845 "input": "Search the OpenAI docs for Responses API streaming and return the relevant links."

1846 }'1846 }'

1847```1847```

1848 1848 


1855 tools: [1855 tools: [

1856 {1856 {

1857 type: "mcp",1857 type: "mcp",

1858 server_label: "dmcp",1858 server_label: "openai_docs",

1859 server_description:1859 server_description: "Search and read the public OpenAI documentation.",

1860 "A Dungeons and Dragons MCP server to assist with dice rolling.",1860 server_url: "https://developers.openai.com/mcp",

1861 server_url: "https://dmcp-server.deno.dev/mcp",

1862 require_approval: "never",1861 require_approval: "never",

1863 },1862 },

1864 ],1863 ],

1865 input: "Roll 2d4+1",1864 input:

1865 "Search the OpenAI docs for Responses API streaming and return the relevant links.",

1866});1866});

1867 1867 

1868console.log(resp.output_text);1868console.log(resp.output_text);


1878 tools=[1878 tools=[

1879 {1879 {

1880 "type": "mcp",1880 "type": "mcp",

1881 "server_label": "dmcp",1881 "server_label": "openai_docs",

1882 "server_description": "A Dungeons and Dragons MCP server to assist with dice rolling.",1882 "server_description": "Search and read the public OpenAI documentation.",

1883 "server_url": "https://dmcp-server.deno.dev/mcp",1883 "server_url": "https://developers.openai.com/mcp",

1884 "require_approval": "never",1884 "require_approval": "never",

1885 },1885 },

1886 ],1886 ],

1887 input="Roll 2d4+1",1887 input="Search the OpenAI docs for Responses API streaming and return the relevant links.",

1888)1888)

1889 1889 

1890print(resp.output_text)1890print(resp.output_text)


1903 1903 

1904func main() {1904func main() {

1905 client := openai.NewClient()1905 client := openai.NewClient()

1906 tool := responses.ToolParamOfMcp("dmcp")1906 tool := responses.ToolParamOfMcp("openai_docs")

1907 tool.OfMcp.ServerDescription = openai.String("A Dungeons and Dragons MCP server to assist with dice rolling.")1907 tool.OfMcp.ServerDescription = openai.String("Search and read the public OpenAI documentation.")

1908 tool.OfMcp.ServerURL = openai.String("https://dmcp-server.deno.dev/mcp")1908 tool.OfMcp.ServerURL = openai.String("https://developers.openai.com/mcp")

1909 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}1909 tool.OfMcp.RequireApproval = responses.ToolMcpRequireApprovalUnionParam{OfMcpToolApprovalSetting: openai.String("never")}

1910 1910 

1911 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{1911 response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{

1912 Model: "gpt-6-astra",1912 Model: "gpt-6-astra",

1913 Tools: []responses.ToolUnionParam{tool},1913 Tools: []responses.ToolUnionParam{tool},

1914 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Roll 2d4+1")},1914 Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("Search the OpenAI docs for Responses API streaming and return the relevant links.")},

1915 })1915 })

1916 if err != nil {1916 if err != nil {

1917 panic(err)1917 panic(err)


1929ResponseCreateParams params =1929ResponseCreateParams params =

1930 ResponseCreateParams.builder()1930 ResponseCreateParams.builder()

1931 .model("gpt-6-astra")1931 .model("gpt-6-astra")

1932 .input("Roll 2d4+1")1932 .input(

1933 "Search the OpenAI docs for Responses API streaming and return the relevant links.")

1933 .addTool(1934 .addTool(

1934 Tool.Mcp.builder()1935 Tool.Mcp.builder()

1935 .serverLabel("dmcp")1936 .serverLabel("openai_docs")

1936 .serverDescription(1937 .serverDescription("Search and read the public OpenAI documentation.")

1937 "A Dungeons and Dragons MCP server to assist with dice rolling.")1938 .serverUrl("https://developers.openai.com/mcp")

1938 .serverUrl("https://dmcp-server.deno.dev/mcp")

1939 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)1939 .requireApproval(Tool.Mcp.RequireApproval.McpToolApprovalSetting.NEVER)

1940 .build())1940 .build())

1941 .build();1941 .build();


1957CreateResponseOptions options = new() { Model = "gpt-6-astra" };1957CreateResponseOptions options = new() { Model = "gpt-6-astra" };

1958options.Tools.Add(1958options.Tools.Add(

1959 ResponseTool.CreateMcpTool(1959 ResponseTool.CreateMcpTool(

1960 serverLabel: "dmcp",1960 serverLabel: "openai_docs",

1961 serverUri: new Uri("https://dmcp-server.deno.dev/mcp"),1961 serverUri: new Uri("https://developers.openai.com/mcp"),

1962 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval1962 toolCallApprovalPolicy: DefaultMcpToolCallApprovalPolicy.NeverRequireApproval

1963 )1963 )

1964);1964);

1965options.InputItems.Add(ResponseItem.CreateUserMessageItem("Roll 2d4+1"));1965options.InputItems.Add(ResponseItem.CreateUserMessageItem("Search the OpenAI docs for Responses API streaming and return the relevant links."));

1966 1966 

1967ResponseResult response = await client.CreateResponseAsync(options);1967ResponseResult response = await client.CreateResponseAsync(options);

1968 1968 


1979 tools: [1979 tools: [

1980 {1980 {

1981 type: "mcp",1981 type: "mcp",

1982 server_label: "dmcp",1982 server_label: "openai_docs",

1983 server_description: "A Dungeons and Dragons MCP server to assist with dice rolling.",1983 server_description: "Search and read the public OpenAI documentation.",

1984 server_url: "https://dmcp-server.deno.dev/mcp",1984 server_url: "https://developers.openai.com/mcp",

1985 require_approval: "never"1985 require_approval: "never"

1986 }1986 }

1987 ],1987 ],

1988 input: "Roll 2d4+1"1988 input: "Search the OpenAI docs for Responses API streaming and return the relevant links."

1989)1989)

1990 1990 

1991puts(response.output_text)1991puts(response.output_text)