Skip to main content
Glama

proxy_list_tls_fingerprints

List unique TLS client fingerprints (JA3/JA4) from captured network traffic with occurrence counts to identify and analyze client applications.

Instructions

List unique client JA3/JA4 fingerprints across captured traffic with occurrence counts.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoMax fingerprints to return (default: 20)
hostname_filterNoFilter by hostname substring

Implementation Reference

  • Handler for the "proxy_list_tls_fingerprints" tool, which aggregates and lists client JA3/JA4 fingerprints from captured traffic.
    server.tool(
      "proxy_list_tls_fingerprints",
      "List unique client JA3/JA4 fingerprints across captured traffic with occurrence counts.",
      {
        limit: z.number().optional().default(20).describe("Max fingerprints to return (default: 20)"),
        hostname_filter: z.string().optional().describe("Filter by hostname substring"),
      },
      async ({ limit, hostname_filter }) => {
        let traffic = proxyManager.getTraffic();
    
        if (hostname_filter) {
          const h = hostname_filter.toLowerCase();
          traffic = traffic.filter((t) => t.request.hostname.toLowerCase().includes(h));
        }
    
        // Aggregate JA3 fingerprints
        const ja3Counts = new Map<string, { count: number; hostnames: Set<string> }>();
        const ja4Counts = new Map<string, { count: number; hostnames: Set<string> }>();
    
        for (const t of traffic) {
          if (t.tls?.client?.ja3Fingerprint) {
            const fp = t.tls.client.ja3Fingerprint;
            const entry = ja3Counts.get(fp) || { count: 0, hostnames: new Set() };
            entry.count++;
            entry.hostnames.add(t.request.hostname);
            ja3Counts.set(fp, entry);
          }
          if (t.tls?.client?.ja4Fingerprint) {
            const fp = t.tls.client.ja4Fingerprint;
            const entry = ja4Counts.get(fp) || { count: 0, hostnames: new Set() };
            entry.count++;
            entry.hostnames.add(t.request.hostname);
            ja4Counts.set(fp, entry);
          }
        }
    
        // Sort by count descending
        const ja3List = [...ja3Counts.entries()]
          .sort((a, b) => b[1].count - a[1].count)
          .slice(0, limit)
          .map(([fp, { count, hostnames }]) => ({
            fingerprint: fp,
            count,
            hostnames: [...hostnames].slice(0, 5),
          }));
    
        const ja4List = [...ja4Counts.entries()]
          .sort((a, b) => b[1].count - a[1].count)
          .slice(0, limit)
          .map(([fp, { count, hostnames }]) => ({
            fingerprint: fp,
            count,
            hostnames: [...hostnames].slice(0, 5),
          }));
    
        return {
          content: [{
            type: "text" as const,
            text: truncateResult({
              status: "success",
              totalExchangesWithTls: traffic.filter((t) => t.tls?.client).length,
              ja3: ja3List,
              ja4: ja4List,
            }),
          }],
        };
      },
    );
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yfe404/proxy-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server