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

@agentlair/flue

v0.1.0

Published

AgentLair integration for Flue — agent identity (AATs), behavioral trust scoring, and trust-gated MCP connections.

Readme

@agentlair/flue

AgentLair integration for Flue — agent identity, JWKS-verified authentication, and trust-gated MCP connections.

Flue ships with no identity or auth layer by design. AgentLair fills that gap: each agent session gets a cryptographically signed identity token (AAT), verifiable by any service that accepts JWKS-backed Ed25519 JWTs — no shared secrets, no trust negotiation.

Install

npm install @agentlair/flue
# peer dependency
npm install @flue/sdk

Quick Start

Wrap your agent handler with withAgentLair. Your handler receives aal — a live token plus decoded claims — ready to attach to any outbound call.

// .flue/agents/my-agent.ts
import { withAgentLair, mcpOptions } from '@agentlair/flue';
import type { FlueContext } from '@agentlair/flue';

export const triggers = { webhook: true };

export default withAgentLair(
  async ({ init, payload, env, aal }) => {
    const agent = await init({ model: 'anthropic/claude-sonnet-4-6' });

    // Attach AAT to any outbound MCP server call
    const partnerTools = await connectMcpServer(
      'partner',
      mcpOptions('https://api.partner.com/mcp', aal),
    );

    const session = await agent.session();
    return await session.prompt(payload.message as string, {
      tools: [partnerTools],
    });
  },
  {
    audience: 'https://my-service.com',
    scopes: ['mcp:tools:execute', 'email:send'],
  },
);

Set AGENTLAIR_API_KEY in your Flue environment. The wrapper reads it automatically.

Three Patterns

1. Outbound identity — your agent calls external services

Use withAgentLair to get a token at session start, then attach it to MCP servers, webhooks, or any HTTP call.

import { withAgentLair, mcpOptions } from '@agentlair/flue';

export default withAgentLair(
  async ({ init, payload, env, aal }) => {
    // aal.token    — raw JWT
    // aal.bearer   — "Bearer eyJ..." string for Authorization header
    // aal.name     — agent display name
    // aal.accountId — stable account ID (persists across sessions)
    // aal.scopes   — granted scopes
    // aal.auditUrl — link to full audit trail for this token

    // MCP connection with AAT auth
    const tools = await connectMcpServer('data-api', mcpOptions(
      'https://data.example.com/mcp',
      aal,
    ));

    // Direct HTTP call with AAT auth
    const response = await fetch('https://api.example.com/data', {
      headers: { Authorization: aal.bearer },
    });

    const agent = await init({ model: 'anthropic/claude-sonnet-4-6' });
    const session = await agent.session();
    return await session.prompt(payload.message as string, { tools: [tools] });
  },
  {
    audience: 'https://data.example.com',
    scopes: ['mcp:tools:execute'],
  },
);

2. Inbound auth — your Flue webhook verifies callers

Services built on Flue can require callers to prove their identity before executing.

// .flue/agents/my-service.ts
import { verifyIncomingAAT } from '@agentlair/flue';

export const triggers = { webhook: true };

export default async function ({ init, payload, env }: FlueContext) {
  // Verify the calling agent's identity — throws if invalid
  const caller = await verifyIncomingAAT(
    (payload.headers as Record<string, string>)?.authorization,
    {
      audience: 'https://my-service.com',
      requiredScopes: ['mcp:tools:execute'],
    },
  );

  // caller.accountId — stable identity across sessions
  // caller.name      — human-readable name
  // caller.tokenRef  — unique token ID (safe to log)
  // caller.auditUrl  — link to caller's audit trail
  console.log(`Request from ${caller.name} (${caller.accountId})`);

  const agent = await init({ model: 'anthropic/claude-sonnet-4-6' });
  const session = await agent.session();
  return await session.prompt(payload.message as string);
}

Verification uses https://agentlair.dev/.well-known/jwks.json — no API key required on the receiving side.

3. A2A trust — session.task() with identity

When Flue's session.task() delegates to child agents, pass the AAT so the child can prove identity downstream.

import { withAgentLair } from '@agentlair/flue';

export default withAgentLair(
  async ({ init, payload, env, aal }) => {
    const agent = await init({ model: 'anthropic/claude-sonnet-4-6' });
    const session = await agent.session();

    // Spawn a child task — pass the AAT in the prompt context
    const result = await session.task(
      `Research this topic: ${payload.query}
       Your identity token: ${aal.token}
       Attach it as 'Authorization: Bearer <token>' when calling external APIs.`,
    );

    return result;
  },
  {
    audience: 'https://my-service.com',
    scopes: ['mcp:tools:execute', 'memory:write'],
  },
);

Token Lifecycle

AATs expire (default: 1 hour). For long-running agents, refresh before reuse:

import { withAgentLair, issueAAT, isAATValid } from '@agentlair/flue';

// Manual refresh pattern
export default withAgentLair(
  async ({ init, payload, env, aal }) => {
    const issueOptions = {
      apiKey: env.AGENTLAIR_API_KEY!,
      audience: 'https://my-service.com',
    };

    // Refresh if within 60 seconds of expiry
    if (!isAATValid(aal, 60)) {
      aal = await issueAAT(issueOptions);
    }

    // ... use aal
  },
  { audience: 'https://my-service.com' },
);

Environment Setup

In .flue/agents/<your-agent>.ts, AgentLair credentials come in via env:

// .flue/commands.ts (if using defineCommand pattern)
export const agentlair = defineCommand('agentlair-cli', {
  env: {
    AGENTLAIR_API_KEY: process.env.AGENTLAIR_API_KEY,
  },
});

Or set AGENTLAIR_API_KEY in your deployment environment (Cloudflare secrets, GitHub Actions secrets, etc.).

What's an AAT?

An Agent Authentication Token is an EdDSA-signed JWT issued by AgentLair:

{
  "iss": "https://agentlair.dev",
  "sub": "acc_7kLmNpQr2sT4",          // stable agent identity
  "aud": "https://my-service.com",
  "exp": 1716000000,
  "jti": "aat_X9bYzWvU8pQr3mNk",      // unique token ID (safe to log)
  "al_name": "my-flue-agent",
  "al_email": "[email protected]",
  "al_scopes": ["mcp:tools:execute", "email:send"],
  "al_audit_url": "https://agentlair.dev/v1/audit/aat_X9bYzWvU8pQr3mNk"
}

Any service can verify it offline using https://agentlair.dev/.well-known/jwks.json.

Never log the raw token. Log jti instead — it uniquely identifies this issuance in the audit trail.

Get an API Key

Register at agentlair.dev:

curl -X POST https://agentlair.dev/v1/register \
  -H 'Content-Type: application/json' \
  -d '{ "name": "my-flue-agent", "recovery_email": "[email protected]" }'

Returns { api_key, account_id, email_address } — your agent's permanent identity.

Related Packages

License

MIT