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

agent-discovery-sdk

v0.2.2

Published

SDK for the Agent Discovery Index — find machine services on the open web

Readme

agent-discovery-sdk

SDK for Montexi — find machine services on the open web.

The Agent Discovery Index is a neutral, stateless discovery layer that crawls the web for APIs, MCP servers, and agent services. This SDK lets your agent search the index, discover services, and integrate them into workflows — no accounts, no API keys.

Installation

npm install agent-discovery-sdk

Quick Start

import { AgentDiscovery } from 'agent-discovery-sdk'

const discovery = new AgentDiscovery()
const { results } = await discovery.search('translation')

for (const service of results) {
  console.log(service.endpoint, service.capabilities)
}

API Reference

new AgentDiscovery([options])

Create a client instance.

| Option | Type | Default | Description | |--------|------|---------|-------------| | indexUrl | string | https://montexi.com | Base URL of the index | | timeout | number | 10000 | Request timeout in milliseconds |

// Use the public index (default)
const discovery = new AgentDiscovery()

// Or point to a self-hosted index
const discovery = new AgentDiscovery({
  indexUrl: 'https://your-index.example.com',
  timeout: 15000,
})

discovery.search(capability, [options])

Search for services matching a capability.

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | capability | string | Yes | Search term (e.g. 'translation', 'search'). Use '*' for all services. | | options | object | No | Filter options (see below) |

Returns: Promise<{ results: Array, count: number, query: object }>

const results = await discovery.search('translation')
console.log(results.count) // number of matches
console.log(results.results) // array of service objects

discovery.submit(endpoint)

Submit a service URL for indexing. The crawler will probe it on the next pass.

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | endpoint | string | Yes | Full URL of the service (e.g. 'https://api.example.com') |

Returns: Promise<{ accepted: boolean, endpoint: string, message: string }>

const result = await discovery.submit('https://api.myservice.com')
console.log(result.message) // "endpoint accepted"

discovery.stats()

Get index statistics — total services, breakdowns by status, source, type, and economic signals.

Returns: Promise<object>

const stats = await discovery.stats()
console.log(stats.total_services)
console.log(stats.by_source_type)

discovery.health()

Check if the index is healthy.

Returns: Promise<{ status: string, service_count: number, last_crawl: string }>

const health = await discovery.health()
console.log(health.status) // "ok"

discovery.tools(name, [options])

Search for specific MCP tools by name across all indexed servers.

Parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | name | string | Yes | Tool name or partial name (e.g. 'search', 'create_page') | | options.description | string | No | Also search tool descriptions | | options.limit | number | No | Max results (default 20) |

Returns: Promise<{ results: Array, count: number }>

const tools = await discovery.tools('search')
for (const t of tools.results) {
  console.log(`${t.tool_name} — ${t.service_endpoint}`)
  console.log(`  ${t.tool_description}`)
}

discovery.discover(capability, [options])

Async generator that yields individual service results. Wraps search() for ergonomic iteration.

Parameters: Same as search().

Yields: Individual service objects.

for await (const service of discovery.discover('translation')) {
  console.log(service.endpoint, service.capabilities)
  // Agent decides what to do with each service
}

Search Filters

Pass these as the second argument to search() or discover():

| Filter | Type | Default | Description | |--------|------|---------|-------------| | status | string | 'alive' | Service status: 'alive', 'unreachable', 'unknown', 'any' | | limit | number | 20 | Max results (1–100) | | sourceType | string | — | Discovery type: 'a2a-agent-card', 'mcp-server-card', 'openapi', 'agent-json', 'llms-txt' | | source | string | — | Origin registry: 'mcp-registry', 'apis-guru', 'crawler', 'submitted' | | hasPayment | boolean | — | Only payment-gated services | | economic | boolean | — | Only economically-aware services | | agentNative | boolean | — | Only agent-native protocol services | | category | string | — | Capability category filter | | economicStrength | string | — | Minimum strength: 'strong', 'medium', 'weak', 'none' | | access | string | — | Access class: 'free', 'api-key', 'oauth', 'bearer-token', 'x402', 'payment' (any payment-gated), 'open' (free or unknown) |

// MCP servers only
const mcp = await discovery.search('*', { sourceType: 'mcp-server-card' })

// Payment-gated services
const paid = await discovery.search('*', { hasPayment: true })

// Top 5 alive A2A agents
const agents = await discovery.search('*', {
  sourceType: 'a2a-agent-card',
  status: 'alive',
  limit: 5,
})

// Free services only (no auth needed)
const free = await discovery.search('translation', { access: 'free' })

// x402 payment-gated services
const x402 = await discovery.search('*', { access: 'x402' })

// Services needing API keys
const keyed = await discovery.search('*', { access: 'api-key' })

Discovery Workflow

The typical agent workflow is: discover → probe → decide → execute.

import { AgentDiscovery } from 'agent-discovery-sdk'

const discovery = new AgentDiscovery()

// 1. Discover: find services for a capability
for await (const service of discovery.discover('translation', { limit: 5 })) {

  // 2. Probe: verify the service responds
  try {
    const res = await fetch(service.endpoint, {
      method: 'HEAD',
      signal: AbortSignal.timeout(5000),
    })
    if (!res.ok) continue
  } catch {
    continue // skip unreachable services
  }

  // 3. Decide: check capabilities and payment requirements
  const isFree = (service.payment_hints || []).includes('free')
  if (!isFree) continue // agent policy: only use free services

  // 4. Execute: interact with the service
  const response = await fetch(service.endpoint, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ text: 'Hello', target: 'es' }),
  })
  const data = await response.json()
  console.log('Translated:', data)
  break
}

Error Handling

The SDK throws typed errors for different failure modes:

import { AgentDiscovery, NetworkError, ValidationError, IndexError } from 'agent-discovery-sdk'

const discovery = new AgentDiscovery()

try {
  await discovery.search('translation')
} catch (err) {
  if (err instanceof NetworkError) {
    // Index unreachable, timeout, or DNS failure
    console.error('Network issue:', err.message)
    console.error('Cause:', err.cause) // original error
  } else if (err instanceof ValidationError) {
    // Bad input — missing capability, invalid URL
    console.error('Invalid input:', err.message)
  } else if (err instanceof IndexError) {
    // Index returned 4xx/5xx
    console.error('Index error:', err.message)
    console.error('Status:', err.statusCode)
    console.error('Body:', err.responseBody)
  }
}

| Error | When | Properties | |-------|------|------------| | NetworkError | Index unreachable, timeout, DNS failure | cause (original Error) | | ValidationError | Missing or invalid input | — | | IndexError | Index returned 4xx/5xx | statusCode, responseBody |

All errors extend AgentDiscoveryError which extends Error.

Configuration

| Option | Type | Default | Description | |--------|------|---------|-------------| | indexUrl | string | https://montexi.com | Index URL. Override for self-hosted instances. | | timeout | number | 10000 | Request timeout in ms. Increase for slow connections. |

For Service Providers

Make your service discoverable by the index:

  1. A2A Agent Card — serve /.well-known/agent-card.json (recommended for agents)
  2. MCP Server Card — serve /.well-known/mcp/server-card.json
  3. agent.json — serve /.well-known/agent.json
  4. OpenAPI spec — serve /openapi.json or /swagger.json
  5. llms.txt — serve /llms.txt for LLM consumption

No registration needed. Deploy the file and the crawler finds you automatically.

Or submit your domain manually:

await discovery.submit('https://api.myservice.com')

See montexi.com for full details.

Examples

See the examples/ directory:

Run them with:

node examples/basic-search.js

License

MIT — see LICENSE.