Example file

03-inspect-and-call.html

Lists the tools the script registers and lets you call any of them yourself, in any browser.

To try this page, download it, replace the placeholders and put it on a test page of your website. Opening the file from your computer won't work, because the embeds check the website address they're on.

03-inspect-and-call.html · HTML Download
<!--
  How to see the tools the script offers, and call one yourself, without an
  AI assistant. Before the snippet loads, a small wrapper goes in front of
  document.modelContext. It records each tool and passes it on to the
  browser. In a browser without WebMCP it stands in for WebMCP, so
  this page works in any browser (AI assistants won't see the tools then).
  Replace wmk_YOUR_KEY with your integration's key.

  Each call goes to Subcontext for real: register_interest,
  share_requirements and book_callback save contacts, leads and bookings
  to your account. Use test details.
-->
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>WebMCP: see and call the tools</title>
  <style>
    section { border: 1px solid #ccc; padding: 0 1rem 1rem; margin: 1rem 0; }
    textarea { width: 100%; font-family: monospace; }
    pre { white-space: pre-wrap; }
  </style>
</head>
<body>
  <h1>See the tools and call them</h1>
  <p>
    This page lists every tool the script offers and lets you call any of them, as an AI assistant
    would. Edit the input before you call a tool.
  </p>
  <p><button id="destroy">SubcontextWebMCP.destroy()</button></p>
  <div id="tools">No tools yet.</div>

  <script>
    // 1. Before the script loads: put a wrapper in front of the browser's WebMCP
    //    (or a stand-in when there is none). The script uses document.modelContext
    //    first, so the wrapper sees every tool.
    var tools = {}
    var browser = document.modelContext || navigator.modelContext // undefined without WebMCP

    Object.defineProperty(document, 'modelContext', {
      configurable: true,
      value: {
        registerTool: function (tool, options) {
          tools[tool.name] = tool
          // destroy() aborts this signal, which is how the script removes a tool.
          options.signal.addEventListener('abort', function () { delete tools[tool.name]; render() })
          render()
          return browser ? browser.registerTool(tool, options) : Promise.resolve()
        },
        unregisterTool: function (name) {
          if (browser && browser.unregisterTool) return browser.unregisterTool(name)
        }
      }
    })

    // Example input for each tool. The slugs are placeholders: list_products gives you real ones.
    // book_callback's start must be a future time inside your business hours:
    // here, 2pm on the next weekday.
    var callbackDay = new Date()
    do { callbackDay.setDate(callbackDay.getDate() + 1) } while (callbackDay.getDay() === 0 || callbackDay.getDay() === 6)
    var callbackStart = callbackDay.toISOString().slice(0, 10) + 'T14:00:00'

    var SAMPLE_INPUT = {
      show_product: { slug: 'PRODUCT_SLUG' },
      compare_products: { slugs: ['FIRST_SLUG', 'SECOND_SLUG'] },
      explain_cover: { slug: 'PRODUCT_SLUG' },
      check_availability: { product_type: 'term' },
      answer_question: { question: 'Do you cover people who have had cancer in the past?' },
      book_callback: { name: 'Test Visitor', phone: '+447700900123', start: callbackStart, reason: 'Questions about life cover' },
      register_interest: { name: 'Test Visitor', email: 'test.visitor@example.com', message: 'Interested in term life cover' },
      share_requirements: { email: 'test.visitor@example.com', requirements: { budget: '30 a month' } }
    }

    // 2. A card for each tool: its name and description, an input box and a Call button.
    function render() {
      var list = document.getElementById('tools')
      list.textContent = Object.keys(tools).length ? '' : 'No tools registered.'
      Object.keys(tools).forEach(function (name) {
        var tool = tools[name]
        var card = document.createElement('section')
        card.innerHTML = '<h3></h3><p></p><textarea rows="4"></textarea><button></button><pre></pre>'
        var parts = card.children
        parts[0].textContent = tool.title + ' (' + name + ')' + (tool.annotations.readOnlyHint === false ? ': saves to your account' : '')
        parts[1].textContent = tool.description
        parts[2].value = JSON.stringify(SAMPLE_INPUT[name] || {}, null, 2)
        parts[3].textContent = 'Call ' + name
        parts[3].onclick = function () { call(tool, parts[2].value, parts[4]) }
        list.appendChild(card)
      })
    }

    // 3. Call a tool the way an AI assistant does: execute(input) gives the tool's
    //    result, or fails with the error message from Subcontext.
    function call(tool, inputText, output) {
      output.textContent = 'Calling...'
      Promise.resolve().then(function () { return tool.execute(JSON.parse(inputText)) }).then(
        function (data) { output.textContent = JSON.stringify(data, null, 2) },
        function (error) { output.textContent = 'Error: ' + error.message }
      )
    }

    document.getElementById('destroy').onclick = function () { SubcontextWebMCP.destroy() }
  </script>

  <!-- 4. The snippet as usual, after the wrapper. Replace wmk_YOUR_KEY with your integration's key (starts wmk_).
       In the dashboard: Organisation > Agent access > Manage WebMCP tools, then open the integration. -->
  <script id="webmcp-embed-script" src="https://js.subcontext.com/webmcp-latest.js"
          data-key="wmk_YOUR_KEY" async></script>
</body>
</html>

Stuck, or something missing?

Get in touch and a person on the team will help.

Contact us