Skip to content

Add outputSchema to ModelContextTool and RegisteredTool - #254

Open
beaufortfrancois wants to merge 3 commits into
webmachinelearning:mainfrom
beaufortfrancois:outputSchema
Open

beaufortfrancois wants to merge 3 commits into
webmachinelearning:mainfrom
beaufortfrancois:outputSchema

Conversation

@beaufortfrancois

@beaufortfrancois beaufortfrancois commented Aug 21, 2026 •

Copy link
Copy Markdown
Collaborator

This PR adds an optional outputSchema member to the ModelContextTool and RegisteredTool dictionaries to enable browser agents and in-page agents to help LLMs reliably reason about the return values of tools.

While responseConstraint was previously discussed, that name is too specific to the Built-in AI / Prompt API. TheoutputSchema name aligns directly with the MCP Tools specification outputSchema used to define expected structured outputs with JSON Schema.

FIX #9


Preview | Diff

@arnabwithab arnabwithab mentioned this pull request Sep 3, 2026
7 tasks done
arnabwithab added a commit to arnabwithab/webmcp that referenced this pull request Sep 3, 2026
Codify WebMCP JSON Schema subset (Draft 2020-12) per 2026-03-05 CG resolution.
Meta-validation in registerTool() (TypeError on invalid schema) and input
validation in executeTool() parallel block before tool execute steps
(DataError with {path,reason,schemaPath} for agent self-correction).

Spec-only per review; WPT split to web-platform-tests/wpt (tentative).
Coordinates with webmachinelearning#254 (outputSchema, same dictionaries).
@volkandkaya

Copy link
Copy Markdown

Is this still planned on being added?

@beaufortfrancois

Copy link
Copy Markdown
Collaborator Author

Is this still planned on being added?

I hope so :) 🤞

@domfarolino I've started experimenting with outputSchema in Chromium with https://chromium-review.googlesource.com/c/chromium/src/+/8398367 to test it out.

@markafoltz markafoltz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions/comments about how the serialization result is passed around (might be missing some key idea)

Comment thread index.bs Outdated
Comment thread index.bs Outdated
@@ -170,12 +170,21 @@ A <dfn>tool definition</dfn> is a [=struct=] with the following [=struct/items=]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the value if the serialization algorithm fails? Is it empty string or null?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If serialization fails, registerTool() rejects before a tool definition is created, so the value is never set. If no schema is provided, the value is the empty string. The tool definition items now say this normatively.

Comment thread index.bs Outdated
Comment thread index.bs
Comment thread index.bs
DOMString title;
required DOMString description;
object inputSchema;
object outputSchema;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make both inputSchema and outputSchema required?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd keep outputSchema optional, as it is in MCP, where tools with unstructured output don't declare one. Making inputSchema required would change existing behavior: ModelContextTool.inputSchema would need to be required too, or default to something like {"type": "object"}. I'd rather handle that in a separate issue than grow this PR. Shall I file one?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that https://chromium-review.googlesource.com/c/chromium/src/+/6850268 was the CL was made inputSchema optional

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making these values required is desirable for security; they allow agents to enforce that tool inputs and outputs are shaped as structured data and improves spotlighting defenses. It won't be possible to for them to ship as optional, and make required later.

Let's discuss further in a separate issue/PR and land this with the algorithm.

Comment thread index.bs Outdated

@markafoltz markafoltz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good % a few optional suggested edits

Comment thread index.bs

1. Return the result of [=serializing a JavaScript value to a JSON string=] given |schema|.

<div class="note">

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This note is not rendering with the Note: prefix, please check this is the right class?

Comment thread index.bs
"<code>inputSchema: { toJSON() {return HTMLDivElement;}}</code>", or
"<code>outputSchema: { toJSON() {return undefined;}}</code>".</p></li>

<li><p><i>Re-throws exceptions</i> thrown by "<code>JSON.stringify()</code>", e.g., when

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:

Re-throws exceptions thrown by JSON.stringify(), e.g. when the object value has a circular reference.

Comment thread index.bs
<div class="note">
<p>The serialization algorithm above throws exceptions in the following cases:</p>
1. Let |stringified input schema| be the result of [=serializing a tool schema=] given |tool|'s
{{ModelContextTool/inputSchema}} if it [=map/exists=], and undefined otherwise. If this threw an

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:

If [=serializing a tool schema=] threw an exception,

Comment thread index.bs
</ol>
</div>
1. Let |stringified output schema| be the result of [=serializing a tool schema=] given |tool|'s
{{ModelContextTool/outputSchema}} if it [=map/exists=], and undefined otherwise. If this threw an

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If [=serializing a tool schema=] threw an exception,

Comment thread README.md
@@ -363,6 +363,7 @@ for (const tool of tools) {
console.log(`Tool: ${tool.name} (from ${tool.origin})`);
console.log(`Description: ${tool.description}`);
console.log(`Parameters schema:`, tool.inputSchema);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps Input schema: ?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Introduce outputSchema (was: Should output also have a schema?)

3 participants