npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ascending-inc/jarvis-embed

v0.1.3

Published

Official SDK for embedding the Jarvis AI Assistant in any web application

Readme

Jarvis Embed SDK

Embed the Jarvis AI Assistant in any web application.


Installation

npm install @ascending-inc/jarvis-embed

Browser (no bundler)

A pre-built UMD bundle is included in the package at dist/index.global.js. Load it with a <script> tag and access the class via window.JarvisSDK:

<script src="node_modules/@ascending-inc/jarvis-embed/dist/index.global.js"></script>
<script>
  const { JarvisEmbed } = window.JarvisSDK;

  const jarvis = new JarvisEmbed({
    provider:    'google',
    token:       googleIdToken,
    containerId: 'chat-container',
  });
</script>

Usage

import { JarvisEmbed } from '@ascending-inc/jarvis-embed';

const jarvis = new JarvisEmbed({
  provider:    'google',
  token:       googleIdToken,
  containerId: 'chat-container',
  model:       'my-spec',
  onReady:     (jarvisToken) => jarvis.setMcpServers(['my-mcp-server']),
});

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | provider | AuthProvider | required | Auth provider — see Authentication. | | token | string | required* | OAuth / JWT token. *Not used for hmac. | | containerId | string | — | ID of the DOM element to mount the iframe into. | | container | HTMLElement | — | Direct element reference (alternative to containerId). | | width | string | '100%' | CSS width of the iframe. | | height | string | '600px' | CSS height of the iframe. | | apiUrl | string | https://jarvis.ascendingdc.com | Override for self-hosted deployments. | | model | string | — | Spec identifier to use for the conversation (sent as ?spec= to the API). Retrieve available values from GET {apiUrl}/api/config. | | debug | boolean | false | Log SDK activity to the console. | | onReady | (jarvisToken: string) => void | — | Fires when the iframe is authenticated and ready. Receives the Jarvis session token — use it to call Jarvis APIs (e.g. GET {apiUrl}/api/mcp/servers) on behalf of the user. | | onError | (err: Error) => void | — | Fires on failure. | | onMessage | (data: unknown) => void | — | Fires when the iframe posts a message to the host page. |

If neither containerId nor container is provided the iframe appends to document.body.

Getting a spec

Available specs can be retrieved from the Jarvis config endpoint:

GET https://jarvis-demo.ascendingdc.com/api/config

Authentication

Calls POST {apiUrl}/api/auth/exchange with your auth payload and receives a Jarvis session token back.

google / s_jwt / a_jwt

| Provider | Token | |----------|-------| | google | Google id_token from OAuth2 | | s_jwt | JWT signed with a shared secret (HS256) | | a_jwt | JWT signed with a private key (RS256 / ES256) |

direct

Pass a Jarvis session token you already hold — the SDK skips the /api/auth/exchange call entirely and uses the token as-is for SDK_AUTH.

new JarvisEmbed({
  provider:    'direct',
  token:       existingJarvisToken,
  containerId: 'chat-container',
});

hmac

new JarvisEmbed({
  provider:  'hmac',
  userId:    'user_123',
  timestamp: Math.floor(Date.now() / 1000),
  signature: hmacHex, // HMAC-SHA256(userId + timestamp)
  containerId: 'chat-container',
});

Requests older than 5 minutes are rejected server-side.


Methods

| Method | Signature | Description | |--------|-----------|-------------| | destroy | () => void | Removes the iframe and cleans up the window message listener. Call this on unmount — essential for React. | | setMcpServers | (servers: string[]) => void | Activates one or more MCP servers by name. Safe to call before the iframe is ready — servers are queued and flushed automatically on SDK_READY. |


MCP (Model Context Protocol)

Pass one or more MCP server names to give Jarvis access to external tools and data sources during a session.

Discovering available servers

Call GET {apiUrl}/api/mcp/servers with the Jarvis token as a Bearer header to retrieve the names of all servers available to the authenticated user. The response is an object keyed by server name:

const jarvis = new JarvisEmbed({
  provider:    'google',
  token:       googleIdToken,
  containerId: 'chat-container',
  onReady: async (jarvisToken) => {
    const res = await fetch(`https://jarvis.ascendingdc.com/api/mcp/servers`, {
      headers: { Authorization: `Bearer ${jarvisToken}` },
    });
    const servers = await res.json(); // { "posthog": {...}, "github": {...}, ... }
    const names = Object.keys(servers);

    // Activate all of them, or let the user pick from `names`
    jarvis.setMcpServers(names);
  },
});

Activating servers

The safest place to call setMcpServers is inside onReady, which fires once the iframe has authenticated and is listening:

const jarvis = new JarvisEmbed({
  provider:    'google',
  token:       googleIdToken,
  containerId: 'chat-container',
  onReady: () => {
    jarvis.setMcpServers(['posthog', 'aws-knowledge']);
  },
});

You can also call it at any time after instantiation — if the iframe isn't ready yet the servers are queued internally and sent as soon as SDK_READY fires:

const jarvis = new JarvisEmbed({
  provider:    's_jwt',
  token:       myJwt,
  containerId: 'chat-container',
});

// Called immediately — queued until SDK_READY
jarvis.setMcpServers(['github', 'jira']);

To swap the active server set later (e.g. after a user action), call setMcpServers again with the new list:

document.getElementById('enable-analytics')?.addEventListener('click', () => {
  jarvis.setMcpServers(['posthog']);
});

React

useJarvis is not exported from the package — copy examples/react/src/useJarvis.ts into your project. It wraps JarvisEmbed in a useEffect and calls destroy() on unmount automatically:

import { useEffect, useRef } from 'react';
import { JarvisEmbed } from '@ascending-inc/jarvis-embed';
import type { JarvisConfig } from '@ascending-inc/jarvis-embed';

export function useJarvis(config: JarvisConfig | null) {
  const jarvisRef = useRef<JarvisEmbed | null>(null);

  useEffect(() => {
    if (!config) return;
    jarvisRef.current = new JarvisEmbed(config);
    return () => {
      jarvisRef.current?.destroy();
      jarvisRef.current = null;
    };
  }, [config]);

  return jarvisRef;
}

Pass null to defer initialization until the user is authenticated. The hook calls destroy() automatically on unmount, so there are no memory leaks or stale event listeners.

Using the container prop in React

When mounting into a React-managed DOM node, use a callback ref so initialization only happens once the element actually exists. Wrap config in useMemo with the container as a dependency — this ensures the SDK sees a real HTMLElement, not null:

import { useCallback, useMemo, useState } from 'react';
import { useJarvis } from './useJarvis';

function ChatWidget({ googleToken }: { googleToken: string }) {
  const [container, setContainer] = useState<HTMLDivElement | null>(null);

  const config = useMemo(() => {
    if (!container || !googleToken) return null;
    return {
      provider: 'google' as const,
      token:    googleToken,
      container,
      width:    '100%',
      height:   '100%',
      onReady:  (jarvisToken: string) => {
        // fetch available servers and activate them
      },
    };
  }, [container, googleToken]);

  const jarvisRef = useJarvis(config);

  return <div ref={setContainer} style={{ flex: 1 }} />;
}

Using containerId instead avoids this entirely — the SDK does the getElementById lookup itself after the iframe loads — but the container prop approach above is required when the element is managed by React state.


Examples

Both examples demonstrate Google OAuth, MCP tool selection, and embedding the chat widget. They share the same Express backend for token exchange.

1. Clone and set up

git clone https://github.com/ascending-llc/jarvis-embed.git
cd jarvis-embed
npm run setup

setup installs root dependencies, builds the SDK, and installs dependencies for both examples.

2. Configure environment variables

Each example has its own .env. Copy and fill in both:

cp examples/vanilla/.env.example examples/vanilla/.env
cp examples/react/.env.example   examples/react/.env

| Variable | Description | |---|---| | GOOGLE_CLIENT_ID | OAuth client ID from Google Cloud Console | | GOOGLE_CLIENT_SECRET | OAuth client secret (never sent to the browser) | | REDIRECT_URI | Must match what's registered in Google Cloud Console | | JARVIS_URL | https://jarvis-demo.ascendingdc.com or http://localhost:3080 for local Jarvis | | JARVIS_MODEL | Optional spec override | | PORT | Express port (default 5500) |

3. Run an example

Vanilla JS — floating chat widget, served at http://localhost:5500

npm run example:vanilla

ReactuseJarvis hook demo with proper cleanup, served at http://localhost:5501

npm run example:react