Skip to main content

Well-Known Provider

The Well-Known Provider discovers skills from websites that publish an RFC 8615 /.well-known/agent-skills.json manifest. This enables decentralized skill discovery from any website.

createWellKnownProvider

Create a well-known endpoint skill provider.
import { createWellKnownProvider } from 'auto-skill/core/providers';

const provider = createWellKnownProvider(['example.com']);

Type Signature

function createWellKnownProvider(
  domains: string[],
  options?: {
    timeout?: number;
    cacheTtl?: number;
  },
): SkillProvider

Parameters

domains
string[]
required
List of domains to query (e.g., ["example.com", "skills.mycompany.io"]).
options
object
Optional configuration.

Returns

A SkillProvider backed by well-known endpoints.
interface SkillProvider {
  name: string;           // "Well-Known Discovery"
  sourceId: string;       // "wellknown"
  search(query: string, limit?: number): Promise<SkillSearchResult[]>;
  getSkillDetails(skillId: string): Promise<SkillSearchResult | null>;
  isAvailable(): boolean;
}

Example Usage

Basic Usage

import { createWellKnownProvider } from 'auto-skill/core/providers';

const provider = createWellKnownProvider(['skills.example.com']);

// Search skills
const results = await provider.search('react', 5);
console.log(results);
// [
//   {
//     id: "react-component",
//     name: "React Component Setup",
//     description: "Create React components with TypeScript",
//     source: "wellknown",
//     confidence: 0.5,
//     author: "skills.example.com",
//     tags: ["react", "typescript"],
//     sourceUrl: "https://skills.example.com/react-component",
//     compatibleAgents: ["claude", "cursor"],
//     metadata: {
//       domain: "skills.example.com",
//       version: "1.2.0"
//     }
//   }
// ]

// Get specific skill
const skill = await provider.getSkillDetails('react-component');

Multiple Domains

import { createWellKnownProvider } from 'auto-skill/core/providers';

const provider = createWellKnownProvider([
  'skills.example.com',
  'skills.mycompany.io',
  'opensource.org',
]);

// Searches all domains and merges results
const results = await provider.search('typescript');

Custom Timeout and Cache

import { createWellKnownProvider } from 'auto-skill/core/providers';

const provider = createWellKnownProvider(
  ['skills.example.com'],
  {
    timeout: 5,      // 5 second timeout
    cacheTtl: 1800,  // 30 minute cache
  },
);

const results = await provider.search('testing');

RFC 8615 Well-Known Endpoints

The provider follows RFC 8615 for well-known URIs. It fetches skill manifests from:
https://{domain}/.well-known/agent-skills.json

Manifest Format

The manifest must be a JSON object with a skills array:
{
  "version": "1.0",
  "skills": [
    {
      "id": "skill-id",
      "name": "Skill Name",
      "description": "What this skill does",
      "author": "Author Name",
      "version": "1.0.0",
      "tags": ["typescript", "testing"],
      "url": "https://example.com/skills/skill-id",
      "compatible_agents": ["claude", "cursor", "codex"]
    }
  ]
}

Required Fields

  • skills (array): List of skill objects

Skill Object Fields

FieldTypeRequiredDescription
idstringNoUnique identifier (falls back to name)
namestringYesSkill name
descriptionstringNoWhat the skill does
authorstringNoSkill author (falls back to domain)
versionstringNoSkill version
tagsstring[]NoSkill tags
urlstringNoSkill source URL
compatible_agentsstring[]NoCompatible agent names

How It Works

Fetch and Cache Algorithm

  1. Check cache: Return cached manifest if within TTL
  2. Fetch manifest: Request https://{domain}/.well-known/agent-skills.json
  3. Validate structure: Ensure skills is an array
  4. Cache result: Store in memory with timestamp
  5. Return skills: Convert to SkillSearchResult[]

Search Algorithm

  1. Fetch from all domains: Query each domain’s manifest (with caching)
  2. Filter skills: Match query against name, description, tags
  3. Merge results: Combine results from all domains
  4. Truncate: Return up to limit results

Caching Strategy

  • In-memory cache: No persistence between process restarts
  • Per-domain: Each domain cached independently
  • TTL-based: Cache expires after cacheTtl seconds
  • Automatic refresh: Expired entries fetched on next request

Return Values

SkillSearchResult

interface SkillSearchResult {
  id: string;              // From manifest.id or manifest.name
  name: string;            // From manifest.name
  description: string;     // From manifest.description
  source: string;          // Always "wellknown"
  confidence: number;      // Always 0.5
  author: string;          // From manifest.author or domain
  tags: string[];          // From manifest.tags
  installCount: number;    // Always 0
  sourceUrl: string;       // From manifest.url or https://{domain}
  compatibleAgents: string[]; // From manifest.compatible_agents
  metadata: {
    domain: string;        // Source domain
    version: string | null; // From manifest.version
  };
}

Empty Results

The provider returns an empty array if:
  • No domains configured
  • All domains fail to respond
  • Manifests contain no matching skills
  • Query matches no skills
const results = await provider.search('nonexistent');
console.log(results); // []

Provider Methods

search(query, limit?)

Search for skills matching a query across all domains.
const results = await provider.search('react hooks', 10);
Parameters:
  • query (string): Search keywords (matches name, description, tags)
  • limit (number): Maximum results (default 10)
Returns: Promise<SkillSearchResult[]>

getSkillDetails(skillId)

Get detailed information about a specific skill.
const skill = await provider.getSkillDetails('react-component');
if (skill) {
  console.log(`Found: ${skill.name}`);
  console.log(`Author: ${skill.author}`);
  console.log(`URL: ${skill.sourceUrl}`);
}
Parameters:
  • skillId (string): The skill identifier (matches manifest.id or manifest.name)
Returns: Promise<SkillSearchResult | null>

isAvailable()

Check if the provider is available.
const available = provider.isAvailable();
console.log(available); // true if domains.length > 0
Returns: boolean (true if at least one domain configured)

Error Handling

The provider handles errors gracefully:
  • Network failures: Logs debug message, returns empty array
  • Timeouts: Logs debug message, returns empty array
  • Invalid JSON: Logs warning, returns empty array
  • Invalid manifest: Logs warning, returns empty array
  • Missing skills array: Logs warning, returns empty array
// All errors handled gracefully
await provider.search('query'); // Returns [] on errors
await provider.getSkillDetails('id'); // Returns null on errors

Security Considerations

HTTPS Only

The provider only fetches from HTTPS endpoints. This ensures:
  • Encryption in transit
  • Server authentication
  • Protection against MITM attacks

No Code Execution

The provider only reads metadata manifests. It does not:
  • Execute code from remote sources
  • Download SKILL.md files automatically
  • Install skills without user confirmation

Request Timeout

All HTTP requests have a configurable timeout to prevent:
  • Hanging requests
  • Resource exhaustion
  • Denial of service

Performance Considerations

Caching Benefits

  • Reduced latency: Cached manifests served instantly
  • Reduced bandwidth: No repeated fetches within TTL
  • Reduced load: Fewer requests to remote servers

Cache Tuning

// High-traffic applications: Longer cache
const provider = createWellKnownProvider(['example.com'], {
  cacheTtl: 3600, // 1 hour
});

// Real-time requirements: Shorter cache
const provider = createWellKnownProvider(['example.com'], {
  cacheTtl: 60, // 1 minute
});

// Development: No cache
const provider = createWellKnownProvider(['example.com'], {
  cacheTtl: 0, // Always fetch
});

Parallel Fetching

When searching multiple domains, fetches happen sequentially (not in parallel). For many domains, consider:
  1. Reducing the domain list
  2. Increasing the timeout
  3. Implementing parallel fetching (custom provider)

Publishing Your Own Manifest

To make your skills discoverable:
  1. Create manifest: /.well-known/agent-skills.json
  2. Serve over HTTPS: Required for security
  3. Set CORS headers: If accessed from browsers
  4. Follow manifest format: Include required fields
  5. Add to provider: Configure domain in consumers
// https://yoursite.com/.well-known/agent-skills.json
{
  "version": "1.0",
  "skills": [
    {
      "name": "Your Skill",
      "description": "What it does",
      "tags": ["typescript"],
      "url": "https://yoursite.com/skills/your-skill"
    }
  ]
}

Source Code Reference

Implementation: src/core/providers/wellknown-provider.ts:119-234 RFC 8615: Well-Known URIs

Build docs developers (and LLMs) love