Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Declarative tool-manifest for JS-callable tools: shape proposal, with production reference

Open
#341 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
28/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
html, javascript, json
Domain
api

Research direction

Start with the repo’s Alternatives Considered #2 and the input-schema-synthesis work in #210, then compare the proposed JSON block with the production reference’s current ai-actions and input_schema spellings. The issue asks whether and where to explore a shared declarative shape; done would mean an agreed direction on venue and conventions, which requires discussion and design rather than a bounded code change.

Written by the indexing model from the issue text.

Description

Context

The repo's Alternatives Considered #2 (Static Declarative Manifests) defers static declarations as "layered on in the future," on the correct observation that a manifest cannot contain executable code and so cannot replace imperative registration. The declarative API for <form> elements (see the input-schema-synthesis work in #210) addresses one subset of what a declarative counterpart could cover.

This issue proposes a declarative shape for the JS-callable subset — tools whose execution is a JavaScript function rather than a form submission — that would complement the imperative registerTool surface and the form-based declarative API already in flight. It is not a replacement for either.

Proposed shape

A <script type="application/json"> block in the page containing an array of MCP Tool objects, where each entry carries name, description, and inputSchema reused verbatim from MCP's wire type. A reader-side convention binds the tool name to the executing JavaScript function. One example in the shape under discussion:

<script type="application/json" id="ai-tools">
[
  { "name": "add_dictionaries",
    "description": "Add the named dictionaries to the current selection.",
    "inputSchema": {
      "type": "object",
      "properties": { "names": { "type": "array", "items": { "type": "string" } } },
      "required": ["names"]
    } }
]
</script>

Deliberately conservative:

  • MCP's Tool type reused verbatim. The same shape every MCP consumer already recognises, including WebMCP's own registerTool arguments — no new type to design, nothing to adopt beyond what the ecosystem already has.
  • Shape only. Dispatch binding (how a reader finds the JavaScript function to invoke) is left to each reader — WebMCP agents could call registerTool with the parsed entry; a widget could call its own dispatch table. This mirrors how the forms-based declarative API leaves execute behaviour to the user agent after schema synthesis.
  • No new lifecycle, state-conveyance, or permissions model. Only the schema part that registerTool already takes.

The reference implementation (see 'Reference implementation' below) currently uses the DOM id ai-actions and the snake_case field name input_schema as legacy spellings; the proposal above uses ai-tools and inputSchema to align with MCP's Tool type and WebMCP's registerTool surface, and the widget would migrate to the aligned spellings on standardisation.

Reference implementation

llm_meta_widget (npm @aibranch/llm-meta-widget, also a Ruby gem on RubyGems) reads this shape in production and dispatches declared tool-calls to a page-provided JavaScript function. Running live at https://pubdictionaries.org/text_annotation — view the page source to see the current shape in use, or interact with the chat widget directly. A related MCP Specification Enhancement Proposal, static-primitives, covers the backend-side analogue (pre-connection advertisement of a server's primitives via a Server Card extension).

Compatibility across the WebMCP adoption window

The pre-WebMCP window — Origin-Trial support in Chromium today, broader cross-browser adoption longer — is a period where host sites that want in-page LLM tool integration need a shape that works in every current browser. A declarative JSON-block manifest serves that need now: the widget reads it in any browser with ES-module support, without a WebMCP implementation present. If WebMCP later specifies a reader for the same block, the page's declaration continues working for both widget-style assistants and WebMCP-capable browser agents from a single source, without re-authoring.

The widget-style reader is the shipping path during the pre-WebMCP window; a shared shape avoids the authoring churn when WebMCP ships broadly.

Discussion

Would there be interest in exploring a shared declarative shape for JS-callable tools, as a complement to the forms-based declarative API in #210? Open on venue: this repo as the natural home, the Web Machine Learning CG, the Model Context Protocol SEP track, or combined. Happy to iterate on the shape, the DOM-placement convention, or any aspect of the proposal.

Dominant language
Bikeshed
Stars
4.7k
Forks
328
Avg merge
2d 15h
Merged PRs (30d)
16

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from webmachinelearning/webmcp

All issues in webmachinelearning/webmcp

Similar issues

More Backend & API Design issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.