MultiVibe Cloud

Developers

← Back to dashboard

Add MultiVibe Chat to your app

Your users bring their AI account. Add a familiar Chat interface, then connect it to your application's tools.

1. Register your web application

Open Your applications, create your application and copy its client ID. Register an HTTPS callback on your own domain for the application configuration. In Configure web SDK, enter the exact origin, such as https://app.example.com, add the supplied DNS TXT record and select Verify web domain.

Registered callbacks must use that exact origin. Register a separate application for each integrating origin. Wildcards and an unverified domain cannot embed Chat. The Chat loader uses MultiVibe's fixed callback internally; do not replace your application's callback with it.

2. Add the connection button

Replace YOUR_APPLICATION_UUID with your public client ID. No API key or client secret belongs in this code.

<link rel="stylesheet" href="https://app.multivibe.cloud/developers/connect/v1/button.css" crossorigin="anonymous">
<script src="https://app.multivibe.cloud/developers/connect/v1/chat.js" defer crossorigin="anonymous"></script>
<button class="mv-connect-button" type="button" data-multivibe-chat="YOUR_APPLICATION_UUID">
  <img class="mv-connect-icon" src="https://app.multivibe.cloud/developers/connect/v1/mark.svg" width="24" height="24" alt="" crossorigin="anonymous">
  Chat with MultiVibe
</button>

The button opens a modal. Sign-in and consent happen on MultiVibe; the user's models and this application's encrypted history stay inside the isolated Chat frame. Users choose Cloud, My accounts or Relay in the model selector. An offline Relay machine never silently switches to a paid model.

Your Content Security Policy must allow https://app.multivibe.cloud in script-src, style-src, img-src and frame-src. The current modal loader also uses inline style attributes; adapt your wrapper or style policy accordingly. Test popup permission and storage partitioning in your supported browsers.

3. Connect tools and skills

For application actions, load the same script and call mount from your own button handler. Use this pattern instead of the automatic data-multivibe-chat attribute.

// Call only after chat.js has loaded, from the user's button click.
const chat = window.MultiVibeChat.mount({
  clientId: 'YOUR_APPLICATION_UUID',
  manifest: {
    version: 1,
    tools: [{
      name: 'create_note',
      description: 'Create a note in this application',
      inputSchema: {
        type: 'object',
        properties: {title: {type: 'string'}},
        required: ['title'], additionalProperties: false
      },
      modifiesData: true, permission: 'notes.write'
    }],
    skills: [{
      id: 'notes.organize', version: '1.0.0', name: 'Organize notes',
      instructions: 'Create a note only when the user asks.',
      tools: ['create_note'], permissions: ['notes.write']
    }]
  },
  tools: {
    async create_note({title}, {operationId}) {
      // Your authenticated backend must recheck permissions and atomically
      // deduplicate operationId with the same request arguments.
      return applicationAPI.createNote({title}, {idempotencyKey: operationId});
    }
  },
  onClose() { /* optional application UI update */ },
  onError() { /* show a concise integration error */ }
});
// When leaving this application screen:
// chat.close();

applicationAPI represents your own authenticated service; it is not supplied by MultiVibe. Users grant tool permissions and select skills explicitly. Every modifying action asks for confirmation. Skills become application-provided user context, never system authority.

The opaque operationId is stable for one scoped tool call. Deduplicate it on your backend under the authenticated user and reject changed arguments. It is not an authorization credential. A timeout or interruption can leave the result unknown; do not rerun the action automatically. Stop prevents later actions but cannot undo an action already sent.

What your application can see

The isolated Chat keeps tokens, recovery material, history keys and conversation content out of the host page. A selected tool receives its arguments and opaque operation ID; your application therefore sees the data necessary to perform that action. The selected model receives the context necessary for inference.

Cloud stores encrypted conversation content, scoped to the user and application. First-time history recovery setup happens in the user's MultiVibe account. Never ask for a recovery code in your own application. Browser partitioning may require unlocking on each integrating site.

A custom or native interface can read the text it renders. It receives only this application's delegated history keys after user consent; it never receives the recovery code or account-wide history roots. Do not claim that a host-rendered interface has the same isolation as this Chat frame.

Verify before release

  • Connect on two verified origins and confirm each app sees only its own conversations.
  • Reload, reconnect and recover encrypted history without exposing keys to the host.
  • Exercise tool denial, permission revocation, interruption and backend idempotency.
  • Test Escape, keyboard navigation and focus restoration in the modal.
  • Use a real Relay machine and verify offline and quota behavior separately from UI fixtures.

The user funds inference through the selected source. Cloud credits, personal-provider terms and Relay access have distinct limits. The planned Relay offer is 250 free messages per month, then unlimited Relay with Cloud; do not present that offer as live until commercial activation has been verified.

Build your own interface with delegated API access →