Skip to content
Dark MatterDark Matter

Custom Site Adapters

How to build a custom SiteAdapter for the DMTR extension.

Overview

The DMTR extension uses a SiteAdapter interface to support entity extraction from any website. You can build a custom adapter for internal tools, research platforms, or any page that displays private company information.

Implementing a SiteAdapter

Create a new file in packages/extension/src/adapters/ and implement the interface:

import type { SiteAdapter, ExtractedEntity, InjectionPoint } from "../types";

export const myAdapter: SiteAdapter = {
  name: "My Platform",

  patterns: [
    { hostname: "app.myplatform.com", pathname: "/companies/" },
  ],

  extractEntities(doc: Document): ExtractedEntity[] {
    const name = doc.querySelector("h1.company-name")?.textContent?.trim();
    if (!name) return [];
    return [{
      name,
      type: "startup",
      confidence: 0.9,
      source: "myplatform-header",
    }];
  },

  injectionPoints(doc: Document): InjectionPoint[] {
    return [];
  },
};

Then register it in src/content/index.ts:

import { myAdapter } from "../adapters/my-platform";

const adapters: SiteAdapter[] = [pitchbookAdapter, myAdapter];

URL patterns

Each adapter declares URL patterns as { hostname, pathname? } objects. The content script matches the current page against all adapters and runs the first match. The hostname is matched with includes() (substring), and pathname is matched with startsWith().

Entity extraction tips

  • Try multiple CSS selectors in priority order (most specific first, fallback last)
  • Set confidence proportional to selector specificity
  • Include metadata for any additional page context (valuation, sector, etc.)
  • The extension resolves entity names against the DMTR intelligence database — exact names work best

Host permissions

Custom adapters require adding the host to manifest.json under host_permissions and content_scripts.matches for the content script to be injected.

Edit this page on GitHub

Last reviewed: March 23, 2026

Was this page helpful?