Wpnx330/pharos-discovery

The universal agent discovery framework for MCP — search, evaluate, approve, and connect to MCP services from any AI agent. Provider-agnostic, user-approval-gated.

1

stars

32

commits

Python

primary language

Aug 20, 2026

updated

agent-framework
ai-agents
discovery
interoperability
mcp
model-context-protocol
open-standard

README

Pharos Discovery SDK

Pharos Discovery SDK

Agent Integration Demo

Universal agent discovery framework for MCP (Model Context Protocol) servers — search, approve, and connect to MCP servers from any registry.

Features

  • Registry Client — Search and browse MCP server packages from any Pharos-compatible registry
  • MCP Adapter — Normalize server cards from MCP official registry, npm, and custom registries
  • Approval Engine — HMAC-signed token approval system with configurable handlers
  • Connection Manager — Multi-transport connections (streamable-http, http+sse, stdio) with retry and reconnection
  • Security — Blocklist (hash-based) and key pinning (TOFU) for safe server connections
  • SSE Events — Subscribe to registry events (package.published, package.unpublished, etc.) with auto-reconnect
  • Consent Store — Persistent user consent records with TTL and revocation
  • Headless Mode — CI/CD-friendly approval policies (allow_all, deny_all, allow_trusted_only)
  • Plan Approval — Two-phase install: review risk-assessed plan, then approve execution
  • Caching — TTL-based cache with LRU eviction for registry responses

Installation

Python

pip install pharos-discovery

TypeScript

npm install @pharos/discovery

Quick Start

Python

from pharos_discovery import RegistryClient, ApprovalEngine

client = RegistryClient("https://api.getpharos.dev")
results = await client.search("filesystem")

# Approve and connect
engine = ApprovalEngine(secret="your-hmac-secret")
token = engine.sign_token(server_id="fs-server", scopes=["read"])

TypeScript

import { RegistryClient, ApprovalEngine } from "@pharos/discovery";

const client = new RegistryClient("https://api.getpharos.dev");
const results = await client.search("filesystem");

const engine = new ApprovalEngine({ secret: "your-hmac-secret" });
const token = engine.signToken({ serverId: "fs-server", scopes: ["read"] });

MCP Server

The pharos_discovery.mcp_server package exposes the SDK as an MCP server, so any MCP-compatible client (Claude Desktop, LibreChat, VS Code, Hermes Agent) can search, install, approve, and connect to MCP servers directly from chat.

Quick Start

pip install pharos-discovery
python3 -m pharos_discovery.mcp_server

Add to your MCP client config (e.g. Claude Desktop claude_desktop_config.json):

{
  "mcpServers": {
    "pharos": {
      "command": "python3",
      "args": ["-m", "pharos_discovery.mcp_server"]
    }
  }
}

Tools

Mode is selected at startup by PHAROS_MCP_APPS.

CLI mode (default — no iframe):

ToolDescription
pharos_searchSearch the registry for MCP servers (natural-language query)
pharos_infoServer card details
pharos_installInstall a server (remote endpoint or CLI for stdio)
pharos_removeRemove an installed server
pharos_listList installed servers
pharos_list_toolsList tools available on a connected server
pharos_call_toolCall a tool on a connected server

Apps mode (PHAROS_MCP_APPS=true — LibreChat / MCP Apps hosts):

ToolDescription
pharos_search_appsSearch + results iframe
pharos_info_appsServer details iframe
pharos_install_appsInstall with visual approval (replaces pharos_connect)
pharos_remove_appsRemove with confirmation iframe
pharos_list_appsInstalled-servers iframe
pharos_publish_appsPublish confirmation iframe

pharos_connect is gone. Approval is POST /approve (custom HTTP route, not an MCP tool — invisible to the model). The iframe Approve button posts via the host (postMessage); the AI cannot click it. After pharos_install_apps returns pending_approval, the host polls pharos_check_approval.

Tool JSON is compact. HTML lives on ui://pharos/... resources, often with a per-call token (ui://pharos/approval/{token}) so iframes do not show a stale card.

MCP Apps UI Resources

The server ships three sandboxed-iframe UI resources (MCP Apps, io.modelcontextprotocol/ui):

  • ui://pharos/results — search results gallery (clickable cards)
  • ui://pharos/approval — server approval card (Approve/Deny)
  • ui://pharos/oauth — OAuth consent screen

Transport

Transport defaults to stdio (for local clients). Set PHAROS_MCP_TRANSPORT for network transports:

# SSE (for LibreChat, web clients)
PHAROS_MCP_TRANSPORT=sse PHAROS_MCP_HOST=0.0.0.0 PHAROS_MCP_PORT=8766 \
  python3 -m pharos_discovery.mcp_server

# Streamable HTTP (newer MCP clients)
PHAROS_MCP_TRANSPORT=streamable-http PHAROS_MCP_PORT=8766 \
  python3 -m pharos_discovery.mcp_server

Configuration

Env VarDefaultDescription
PHAROS_REGISTRY_URLhttps://api.getpharos.devRegistry base URL
PHAROS_CLIpharosPath to the pharos CLI binary (used by pharos_install)
PHAROS_MCP_TRANSPORTstdioTransport: stdio, sse, or streamable-http
PHAROS_MCP_HOST0.0.0.0Bind host (SSE / streamable-http only)
PHAROS_MCP_PORT8766Bind port (SSE / streamable-http only)

Architecture

The SDK is a monorepo with parallel implementations:

  • packages/python/ — Python 3.10+ with pydantic v2, httpx, anyio
  • packages/typescript/ — Node 20+ with zod, dual ESM/CJS output

Both implementations share the same API surface and are feature-complete.

Testing

Python

cd packages/python
PYTHONPATH=src python3 -m pytest tests/ -q

TypeScript

cd packages/typescript
npx vitest run

Author

Built by Chris Wykel — reach me at chris@chriswykel.com.

License

MIT © Chris Wykel

Contributors

Wpnx330

32 commits

Wpnx330/pharos-discovery

The universal agent discovery framework for MCP — search, evaluate, approve, and connect to MCP services from any AI agent. Provider-agnostic, user-approval-gated.

1

stars

32

commits

Python

primary language

Aug 20, 2026

updated

agent-framework
ai-agents
discovery
interoperability
mcp
model-context-protocol
open-standard

README

Pharos Discovery SDK

Pharos Discovery SDK

Agent Integration Demo

Universal agent discovery framework for MCP (Model Context Protocol) servers — search, approve, and connect to MCP servers from any registry.

Features

  • Registry Client — Search and browse MCP server packages from any Pharos-compatible registry
  • MCP Adapter — Normalize server cards from MCP official registry, npm, and custom registries
  • Approval Engine — HMAC-signed token approval system with configurable handlers
  • Connection Manager — Multi-transport connections (streamable-http, http+sse, stdio) with retry and reconnection
  • Security — Blocklist (hash-based) and key pinning (TOFU) for safe server connections
  • SSE Events — Subscribe to registry events (package.published, package.unpublished, etc.) with auto-reconnect
  • Consent Store — Persistent user consent records with TTL and revocation
  • Headless Mode — CI/CD-friendly approval policies (allow_all, deny_all, allow_trusted_only)
  • Plan Approval — Two-phase install: review risk-assessed plan, then approve execution
  • Caching — TTL-based cache with LRU eviction for registry responses

Installation

Python

pip install pharos-discovery

TypeScript

npm install @pharos/discovery

Quick Start

Python

from pharos_discovery import RegistryClient, ApprovalEngine

client = RegistryClient("https://api.getpharos.dev")
results = await client.search("filesystem")

# Approve and connect
engine = ApprovalEngine(secret="your-hmac-secret")
token = engine.sign_token(server_id="fs-server", scopes=["read"])

TypeScript

import { RegistryClient, ApprovalEngine } from "@pharos/discovery";

const client = new RegistryClient("https://api.getpharos.dev");
const results = await client.search("filesystem");

const engine = new ApprovalEngine({ secret: "your-hmac-secret" });
const token = engine.signToken({ serverId: "fs-server", scopes: ["read"] });

MCP Server

The pharos_discovery.mcp_server package exposes the SDK as an MCP server, so any MCP-compatible client (Claude Desktop, LibreChat, VS Code, Hermes Agent) can search, install, approve, and connect to MCP servers directly from chat.

Quick Start

pip install pharos-discovery
python3 -m pharos_discovery.mcp_server

Add to your MCP client config (e.g. Claude Desktop claude_desktop_config.json):

{
  "mcpServers": {
    "pharos": {
      "command": "python3",
      "args": ["-m", "pharos_discovery.mcp_server"]
    }
  }
}

Tools

Mode is selected at startup by PHAROS_MCP_APPS.

CLI mode (default — no iframe):

ToolDescription
pharos_searchSearch the registry for MCP servers (natural-language query)
pharos_infoServer card details
pharos_installInstall a server (remote endpoint or CLI for stdio)
pharos_removeRemove an installed server
pharos_listList installed servers
pharos_list_toolsList tools available on a connected server
pharos_call_toolCall a tool on a connected server

Apps mode (PHAROS_MCP_APPS=true — LibreChat / MCP Apps hosts):

ToolDescription
pharos_search_appsSearch + results iframe
pharos_info_appsServer details iframe
pharos_install_appsInstall with visual approval (replaces pharos_connect)
pharos_remove_appsRemove with confirmation iframe
pharos_list_appsInstalled-servers iframe
pharos_publish_appsPublish confirmation iframe

pharos_connect is gone. Approval is POST /approve (custom HTTP route, not an MCP tool — invisible to the model). The iframe Approve button posts via the host (postMessage); the AI cannot click it. After pharos_install_apps returns pending_approval, the host polls pharos_check_approval.

Tool JSON is compact. HTML lives on ui://pharos/... resources, often with a per-call token (ui://pharos/approval/{token}) so iframes do not show a stale card.

MCP Apps UI Resources

The server ships three sandboxed-iframe UI resources (MCP Apps, io.modelcontextprotocol/ui):

  • ui://pharos/results — search results gallery (clickable cards)
  • ui://pharos/approval — server approval card (Approve/Deny)
  • ui://pharos/oauth — OAuth consent screen

Transport

Transport defaults to stdio (for local clients). Set PHAROS_MCP_TRANSPORT for network transports:

# SSE (for LibreChat, web clients)
PHAROS_MCP_TRANSPORT=sse PHAROS_MCP_HOST=0.0.0.0 PHAROS_MCP_PORT=8766 \
  python3 -m pharos_discovery.mcp_server

# Streamable HTTP (newer MCP clients)
PHAROS_MCP_TRANSPORT=streamable-http PHAROS_MCP_PORT=8766 \
  python3 -m pharos_discovery.mcp_server

Configuration

Env VarDefaultDescription
PHAROS_REGISTRY_URLhttps://api.getpharos.devRegistry base URL
PHAROS_CLIpharosPath to the pharos CLI binary (used by pharos_install)
PHAROS_MCP_TRANSPORTstdioTransport: stdio, sse, or streamable-http
PHAROS_MCP_HOST0.0.0.0Bind host (SSE / streamable-http only)
PHAROS_MCP_PORT8766Bind port (SSE / streamable-http only)

Architecture

The SDK is a monorepo with parallel implementations:

  • packages/python/ — Python 3.10+ with pydantic v2, httpx, anyio
  • packages/typescript/ — Node 20+ with zod, dual ESM/CJS output

Both implementations share the same API surface and are feature-complete.

Testing

Python

cd packages/python
PYTHONPATH=src python3 -m pytest tests/ -q

TypeScript

cd packages/typescript
npx vitest run

Author

Built by Chris Wykel — reach me at chris@chriswykel.com.

License

MIT © Chris Wykel

Contributors

Wpnx330

32 commits

Languages

Python

75.0%

TypeScript

25.0%