agent-discovery-sdk
v0.2.2
Published
SDK for the Agent Discovery Index — find machine services on the open web
Maintainers
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-sdkQuick 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 objectsdiscovery.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:
- A2A Agent Card — serve
/.well-known/agent-card.json(recommended for agents) - MCP Server Card — serve
/.well-known/mcp/server-card.json - agent.json — serve
/.well-known/agent.json - OpenAPI spec — serve
/openapi.jsonor/swagger.json - llms.txt — serve
/llms.txtfor 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:
basic-search.js— simple searchfiltered-search.js— search with filterssubmit-service.js— submit a new servicediscover-and-execute.js— full discovery workflow
Run them with:
node examples/basic-search.jsLicense
MIT — see LICENSE.
