Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ A <dfn>tool definition</dfn> is a [=struct=] with the following [=struct/items=]
:: a [=string=] uniquely identifying a tool registered within a [=model context=]'s [=model
context/tool map=]; it is the same as the [=map/key=] identifying this object.

The [=tool definition/name=] SHOULD:
* Have a [=string/length=] between 1 and 128, inclusive.
* Be considered case-sensitive.
* Only consist of [=ASCII alphanumeric=] [=code points=], U+005F LOW LINE (_), U+002D HYPHEN-MINUS (-), and U+002E FULL STOP (.).

: <dfn>title</dfn>
:: A [=string=] representing a human-readable title of the tool to be used in the user interface
to represent the tool.

: <dfn>description</dfn>
:: a [=string=].

Expand Down Expand Up @@ -206,12 +215,18 @@ The <dfn method for=ModelContext>registerTool(<var>tool</var>)</dfn> method step

1. Let |tool name| be |tool|'s {{ModelContextTool/name}}.

1. Let |tool title| be |tool|'s {{ModelContextTool/title}}.

1. If |tool map|[|tool name|] [=map/exists=], then [=exception/throw=] an {{InvalidStateError}}
{{DOMException}}.

1. If either |tool name| or {{ModelContextTool/description}} is the empty string, then
1. If |tool name|, |tool title| or {{ModelContextTool/description}} is an empty string, then
[=exception/throw=] an {{InvalidStateError}} {{DOMException}}.

1. If |tool name|'s [=string/length=] is greater than 128, or if |tool name| contains a
[=code point=] that is not an [=ASCII alphanumeric=], U+005F (_), U+002D (-), or U+002E (.),
then [=exception/throw=] an {{InvalidStateError}}.

1. Let |stringified input schema| be the empty string.

1. If |tool|'s {{ModelContextTool/inputSchema}} [=map/exists=], then set |stringified input schema|
Expand Down Expand Up @@ -240,6 +255,9 @@ The <dfn method for=ModelContext>registerTool(<var>tool</var>)</dfn> method step
: [=tool definition/name=]
:: |tool name|

: [=tool definition/title=]
:: |tool title|

: [=tool definition/description=]
:: |tool|'s {{ModelContextTool/description}}

Expand Down Expand Up @@ -275,6 +293,7 @@ The {{ModelContextTool}} dictionary describes a tool that can be invoked by [=ag
<xmp class="idl">
dictionary ModelContextTool {
required DOMString name;
required DOMString title;
Copy link
Copy Markdown
Collaborator

@domfarolino domfarolino Mar 24, 2026

Choose a reason for hiding this comment

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

I'm still a little iffy on this. In #133 (comment) you justified this by saying actual MCP made this optional specifically for backwards compatibility, implying that if they could, they'd make it mandatory. But is that definitely true? Is MCP not versioned in any way? Maybe it's not and it has to evolve just like the web platform, in which case we can make this mandatory without the compat risk since we haven't shipped yet.

On the other hand, I can also see why title would be optional, since it isn't strictly required to make the tool useful. Plus it does feel funny to deviate from MCP requirements just because we showed up later and have no compat risk.

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Some useful information and some thoughts:

First of all, you're correct, MCP does support versioning, but they seem to care a lot about backwards compatibility regardless (I think none of their releases have been backwards compatibility breaking as of yet). Here are the relevant PRs:

  1. ToolAnnotations modelcontextprotocol/modelcontextprotocol#185
    introduces tool.annotations.title
  2. Encourage title properties/usage for objects/resources likely t… modelcontextprotocol/modelcontextprotocol#663
    introduces tool.title, explicity notes that tool.title -> tool.annotations.title -> tool.name is the order of preference
  3. fix: deduplicate title definition in tools modelcontextprotocol/modelcontextprotocol#813
    open PR that suggests removing tool.annotations.title, but is kept open due to backwards compatibility concerns awaiting an MCP release that will be backwards incompatible

The big question is how the UI is going to look. Most - but not all - agentic UIs I have seen will refer to tools and visualize tool calls in some way (typically to give a sense of what's going on and/or to get approval from the Human and/or to give the Human control over which tools the agent has access to). If title is not required then browsers are likely to fall back on name, which simply isn't meant for human consumption (especially with the character restrictions outlined here, and additionally I presume name will typically not be localized to the user's language). MCP's original target audience was very much developers who don't mind seeing deleteNodeTool, but that target audience is shifting especially with WebMCP.

There is I think also a risk where different browsers will implement different UIs, and thus a developer using a browser that shows 'tool.title' less prominently (or not at all) might just leave it empty. Making it required would give a guaranteed set of information to browser implementors.

And lastly: anything that's required in v1 can be made optional in v2, but anything that's optional in v1 will have to be optional forever 😅.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tool.annotations.title seems out of the equation. Thanks for sharing links!

Now, the question is should we make it tool.title optional or not? Having played with a lot of WebMCP demos lately, I'm not convinced yet a mandatory title would actually help users since some of them tend to be opaque things that are there to help the agent, not necessarily the user in their quest.

I also feel like the agent can come up with a better wording when invoking those, and presenting them to the user given they have more context.

For this reason, I'd lean towards making it optional. Note that this a not a strong objection.

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.

I think I tend to agree. Since these are basically just JavaScript functions, providing a name might be useful but it doesn't seem mandatory. I think it's unlikely these things will be on display to users too much, similarly to how JavaScript documentation on event handlers isn't really displayed to users when they click buttons and interact with a page.

We could very much be wrong here, so I'm happy to revisit. Since "v0" isn't necessary this "this PR" but it's before things move too far along in final/shipping implementations in browsers, and we have a lot of testing ahead of us, I'm for proceeding with optional title and revisiting if UX feedback is worse because of it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I did my best to convince you guys otherwise, but I clearly failed 😅, so I updated the PR to make title 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.

Honestly, this seems like exactly what our relationship with AAIF is good for, per webmachinelearning/charter#14.

How about we loop in @vthub for thoughts from an MCP perspective? I've also dropped a comment in https://discord.com/channels/1358869848138059966/1416012674663452752/1451622415040905317 to ask folks over there.

required DOMString description;
object inputSchema;
required ToolExecuteCallback execute;
Expand All @@ -294,6 +313,11 @@ callback ToolExecuteCallback = Promise<any> (object input, ModelContextClient cl
<p>A unique identifier for the tool. This is used by [=agents=] to reference the tool when making tool calls.
</dd>

<dt><code><var ignore>tool</var>["{{ModelContextTool/title}}"]</code></dt>
<dd>
<p>A label for the tool. This is used by the user agent to reference the tool in the user interface.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Regarding internationalization: should we add a note advising developers to localize the title based on the user's language settings?

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.

Does MCP encourage something similar?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There is no explicit rule in the spec that says "titles MUST be localized." BUT since those are not passed to the LLM but only for display purposes to the user, it'd make sense to provide them in the browser user language. Thoughts?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

For now added a line to the non-normative ModelContextTool Dictionary section that states 'It is recommended that this string be localized to the user’s language.'

</dd>

<dt><code><var ignore>tool</var>["{{ModelContextTool/description}}"]</code></dt>
<dd>
<p>A natural language description of the tool's functionality. This helps [=agents=] understand when and how to use the tool.
Expand Down