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


Universal agent discovery framework for MCP (Model Context Protocol) servers — search, approve, and connect to MCP servers from any registry.
pip install pharos-discovery
npm install @pharos/discovery
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"])
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"] });
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.
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"]
}
}
}
Mode is selected at startup by PHAROS_MCP_APPS.
CLI mode (default — no iframe):
| Tool | Description |
|---|---|
pharos_search | Search the registry for MCP servers (natural-language query) |
pharos_info | Server card details |
pharos_install | Install a server (remote endpoint or CLI for stdio) |
pharos_remove | Remove an installed server |
pharos_list | List installed servers |
pharos_list_tools | List tools available on a connected server |
pharos_call_tool | Call a tool on a connected server |
Apps mode (PHAROS_MCP_APPS=true — LibreChat / MCP Apps hosts):
| Tool | Description |
|---|---|
pharos_search_apps | Search + results iframe |
pharos_info_apps | Server details iframe |
pharos_install_apps | Install with visual approval (replaces pharos_connect) |
pharos_remove_apps | Remove with confirmation iframe |
pharos_list_apps | Installed-servers iframe |
pharos_publish_apps | Publish 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.
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 screenTransport 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
| Env Var | Default | Description |
|---|---|---|
PHAROS_REGISTRY_URL | https://api.getpharos.dev | Registry base URL |
PHAROS_CLI | pharos | Path to the pharos CLI binary (used by pharos_install) |
PHAROS_MCP_TRANSPORT | stdio | Transport: stdio, sse, or streamable-http |
PHAROS_MCP_HOST | 0.0.0.0 | Bind host (SSE / streamable-http only) |
PHAROS_MCP_PORT | 8766 | Bind port (SSE / streamable-http only) |
The SDK is a monorepo with parallel implementations:
packages/python/ — Python 3.10+ with pydantic v2, httpx, anyiopackages/typescript/ — Node 20+ with zod, dual ESM/CJS outputBoth implementations share the same API surface and are feature-complete.
cd packages/python
PYTHONPATH=src python3 -m pytest tests/ -q
cd packages/typescript
npx vitest run
Built by Chris Wykel — reach me at chris@chriswykel.com.
MIT © Chris Wykel
32 commits
Python
75.0%
TypeScript
25.0%
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


Universal agent discovery framework for MCP (Model Context Protocol) servers — search, approve, and connect to MCP servers from any registry.
pip install pharos-discovery
npm install @pharos/discovery
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"])
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"] });
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.
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"]
}
}
}
Mode is selected at startup by PHAROS_MCP_APPS.
CLI mode (default — no iframe):
| Tool | Description |
|---|---|
pharos_search | Search the registry for MCP servers (natural-language query) |
pharos_info | Server card details |
pharos_install | Install a server (remote endpoint or CLI for stdio) |
pharos_remove | Remove an installed server |
pharos_list | List installed servers |
pharos_list_tools | List tools available on a connected server |
pharos_call_tool | Call a tool on a connected server |
Apps mode (PHAROS_MCP_APPS=true — LibreChat / MCP Apps hosts):
| Tool | Description |
|---|---|
pharos_search_apps | Search + results iframe |
pharos_info_apps | Server details iframe |
pharos_install_apps | Install with visual approval (replaces pharos_connect) |
pharos_remove_apps | Remove with confirmation iframe |
pharos_list_apps | Installed-servers iframe |
pharos_publish_apps | Publish 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.
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 screenTransport 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
| Env Var | Default | Description |
|---|---|---|
PHAROS_REGISTRY_URL | https://api.getpharos.dev | Registry base URL |
PHAROS_CLI | pharos | Path to the pharos CLI binary (used by pharos_install) |
PHAROS_MCP_TRANSPORT | stdio | Transport: stdio, sse, or streamable-http |
PHAROS_MCP_HOST | 0.0.0.0 | Bind host (SSE / streamable-http only) |
PHAROS_MCP_PORT | 8766 | Bind port (SSE / streamable-http only) |
The SDK is a monorepo with parallel implementations:
packages/python/ — Python 3.10+ with pydantic v2, httpx, anyiopackages/typescript/ — Node 20+ with zod, dual ESM/CJS outputBoth implementations share the same API surface and are feature-complete.
cd packages/python
PYTHONPATH=src python3 -m pytest tests/ -q
cd packages/typescript
npx vitest run
Built by Chris Wykel — reach me at chris@chriswykel.com.
MIT © Chris Wykel
32 commits
Python
75.0%
TypeScript
25.0%