Example file

05-visitor-journey.html

Plays the part of an AI assistant, asking a question and a follow-up, registering interest, sharing requirements and getting a link to a specialist.

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.

05-visitor-journey.html · HTML Download
<!--
  What an AI assistant in the visitor's browser might do with your tools,
  played out by this page: a question and a follow-up in the same
  conversation, then register_interest, share_requirements and
  talk_to_a_specialist. Each tool takes what the one before it returned.
  Works in any browser (the wrapper from 03-inspect-and-call.html stands in
  when there is no WebMCP). Replace wmk_YOUR_KEY with your integration's key.

  This saves real data to your account: a conversation in your inbox, and a
  contact and a lead in your CRM. Use test details and tidy up afterwards.
-->
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>WebMCP: a visitor's journey</title>
  <style>
    pre { white-space: pre-wrap; }
  </style>
</head>
<body>
  <h1>A visitor's journey through the tools</h1>
  <p>
    This page plays the part of an AI assistant helping a visitor. It asks a question and a follow-up in the
    same conversation, registers the visitor's interest, shares what they're looking for, and gets a link to a
    specialist. Each step uses what the step before returned.
  </p>
  <p>
    <strong>This saves real data to your Subcontext account</strong>: a conversation in your inbox, and a
    contact and a lead in your CRM. Answering questions runs your AI agent and uses AI credit.
  </p>

  <form id="journey">
    <p><label>Visitor name<br><input name="name" value="Sam Visitor" size="40"></label></p>
    <p><label>Visitor email<br><input name="email" type="email" value="sam.visitor@example.com" size="40"></label></p>
    <p><label>Question<br><input name="question" value="Do you offer joint life cover?" size="60"></label></p>
    <p><label>Follow-up<br><input name="followUp" value="Is there an upper age limit?" size="60"></label></p>
    <p><button>Run the journey</button></p>
  </form>

  <ol id="steps"></ol>

  <script>
    // Record the tools the script offers (with a stand-in when the browser has
    // no WebMCP). 03-inspect-and-call.html explains this.
    var tools = {}
    var browser = document.modelContext || navigator.modelContext
    Object.defineProperty(document, 'modelContext', {
      configurable: true,
      value: {
        registerTool: function (tool, options) {
          tools[tool.name] = tool
          options.signal.addEventListener('abort', function () { delete tools[tool.name] })
          return browser ? browser.registerTool(tool, options) : Promise.resolve()
        },
        unregisterTool: function (name) {
          if (browser && browser.unregisterTool) return browser.unregisterTool(name)
        }
      }
    })

    // Calls one tool the way an AI assistant would, and shows the input and result.
    // Gives back the tool's data, or null when the tool isn't offered or the call fails.
    async function step(name, input) {
      var item = document.createElement('li')
      item.innerHTML = '<strong></strong><pre></pre>'
      item.firstChild.textContent = name
      var detail = item.lastChild
      document.getElementById('steps').appendChild(item)

      if (!tools[name]) {
        detail.textContent = 'Skipped: this tool isn\'t offered (tick it on the integration).'
        return null
      }
      detail.textContent = 'input: ' + JSON.stringify(input) + '\n...'
      try {
        var data = await tools[name].execute(input)
        detail.textContent = 'input: ' + JSON.stringify(input) + '\nresult: ' + JSON.stringify(data, null, 2)
        return data
      } catch (error) {
        detail.textContent = 'input: ' + JSON.stringify(input) + '\nerror: ' + error.message
        return null
      }
    }

    var form = document.getElementById('journey')
    form.addEventListener('submit', async function (event) {
      event.preventDefault()
      document.getElementById('steps').textContent = ''

      // A question, then a follow-up in the same conversation.
      var first = await step('answer_question', { question: form.question.value })
      await step('answer_question', { question: form.followUp.value, conversation_id: first ? first.conversation_id : undefined })

      // Who they are. An email or a phone number is required.
      var lead = await step('register_interest', {
        name: form.name.value,
        email: form.email.value,
        message: 'Asked about joint life cover'
      })

      // What they want, added to that contact. It never creates a contact,
      // so it fails until register_interest has run.
      await step('share_requirements', {
        contact_id: lead ? lead.contact_id : undefined,
        email: lead ? undefined : form.email.value,
        requirements: { cover_type: 'joint life', budget: '40 a month', timescale: 'within a month' }
      })

      // Where a person can take over.
      await step('talk_to_a_specialist', {})
    })
  </script>

  <!-- 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