Hasan Orchestrator
An MCP server that orchestrates multiple devices (mobile, desktop, laptop) via REST API, allowing a local voice assistant (Hermes) to execute actions across devices through dynamic capability routing.
README
Hasan Orchestrator
Orchestrateur MCP multi-devices en Python/FastAPI faisant le lien entre Hermes (assistant vocal local) et plusieurs appareils (mobile, desktop, laptop) via une API REST avec polling.
Hermes (localhost) → MCP localhost:8643
↓
Orchestrateur FastAPI (localhost:8080)
↓ HTTPS + Bearer token
┌───────────┼───────────┐
"phone" "desk" "laptop"
(polling) (polling) (polling)
Les devices initient toujours la connexion (register, heartbeat, long polling). L'orchestrateur ne contacte jamais directement un device.
1. Installation
cd ~/hasan-orchestrator
./install.sh
Le script :
- Crée un environnement virtuel Python (
venv/) - Installe les dépendances (
requirements.txt) - Crée
~/.hasan-orchestrator/pour la base SQLite (registry.db) - Génère
ORCHESTRATOR_ADMIN_KEYdans.envsi absent - Installe et active le service systemd utilisateur
hasan-orchestrator.service
Pour une installation manuelle :
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# éditer .env et définir ORCHESTRATOR_ADMIN_KEY (openssl rand -hex 32)
python main.py
L'API REST écoute par défaut sur http://127.0.0.1:8080.
2. Configuration Hermes
Ajouter dans ~/.hermes/config.yaml :
Option A — MCP en stdio (recommandé)
mcp:
servers:
- name: hasan-orchestrator
type: stdio
command: /chemin/vers/hasan-orchestrator/venv/bin/python
args: ["/chemin/vers/hasan-orchestrator/mcp_server.py"]
description: "Contrôle multi-devices (phone, desk, laptop)"
Le serveur MCP en stdio doit être lancé alors que l'orchestrateur FastAPI tourne déjà (il s'appuie sur l'API interne
/internal/*pour créer les commandes et lire les résultats).
Option B — MCP exposé via HTTP
mcp:
servers:
- name: hasan-orchestrator
url: "http://localhost:8643/mcp"
auth:
type: bearer
token: "${ORCHESTRATOR_ADMIN_KEY}"
3. Connecter un nouveau device
Chaque device (agent mobile/desktop/laptop) doit :
-
Calculer un
device_hashunique et immuable — un SHA256 généré une seule fois (par exemple à partir d'un identifiant matériel + sel aléatoire) et conservé localement. -
S'enregistrer :
curl -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{
"device_name": "phone",
"device_hash": "a3f2c8...",
"device_type": "mobile_agent",
"version": "1.0.0",
"capabilities": {
"send_sms": {"enabled": true, "auth_required": false},
"make_call": {"enabled": true, "auth_required": true},
"screenshot": {"enabled": true, "auth_required": false},
"get_battery": {"enabled": true, "auth_required": false}
}
}'
Réponse :
{
"status": "registered",
"session_token": "tok_...",
"heartbeat_interval": 30,
"polling_interval": 30,
"server_time": "..."
}
-
Conserver
session_tokenet l'utiliser dans le headerAuthorization: Bearer tok_...pour tous les appels suivants. -
Envoyer un heartbeat toutes les
heartbeat_intervalsecondes :
curl -X POST http://localhost:8080/heartbeat \
-H "Authorization: Bearer tok_..." \
-H "Content-Type: application/json" \
-d '{
"device_hash": "a3f2c8...",
"capabilities_version": "<hash renvoyé/calculé>",
"network": {"ip": "192.168.1.42", "transport": "https", "nat": true, "carrier": "WiFi"}
}'
Si capabilities_refresh_needed: true est retourné, refaire un /register
complet (les capabilities ont été modifiées côté orchestrateur).
- Boucler sur
GET /commands(long polling, jusqu'à 55s) pour recevoir les commandes à exécuter, puis poster le résultat sur/results.
Un device sans heartbeat depuis 2 × heartbeat_interval est marqué offline.
4. Tools MCP disponibles
L'orchestrateur n'a aucune connaissance hardcodée des capabilities. Les 3 tools ci-dessous sont les seuls exposés à Hermes :
| Tool | Description |
|---|---|
device_list() |
Liste les devices online et leurs capabilities activées |
device_info(device_name) |
Détails complets d'un device (registry, capabilities, statut) |
exec_action(action, params, device_name?) |
Exécute n'importe quelle action sur un device |
Principe : le device déclare ses propres capabilities à l'enregistrement.
L'orchestrateur les stocke et les route dynamiquement via exec_action.
Si device_name n'est pas précisé, l'orchestrateur choisit automatiquement
l'unique device online disposant de la capability demandée. S'il y en a
plusieurs, il demande de préciser.
Exemples d'appels exec_action
exec_action("send_sms", {"numero": "0612345678", "message": "hello"}, "phone")exec_action("record_audio", {"duration": 10}, "phone")exec_action("open_file", {"path": "/home/user/doc.pdf"}, "desk")exec_action("get_battery", {}, "phone")exec_action("set_volume", {"level": 50}, "desk")
5. Exemples de commandes vocales pour Hermes
- "Liste mes appareils"
- "Prends un screenshot du desk"
- "Envoie un SMS au 06 12 34 56 78 depuis le phone : je serai en retard"
- "Quel est le niveau de batterie du phone ?"
- "Lance Spotify sur le laptop"
- "Mets le volume à 50 sur le desk"
- "Ouvre le fichier rapport.pdf sur le laptop"
- "Active la capability run_terminal sur desk"
- "Désactive get_location sur phone"
6. Gestion des capabilities depuis l'orchestrateur (admin)
Modifier (merge) les capabilities d'un device :
curl -X PATCH http://localhost:8080/api/devices/phone/capabilities \
-H "Authorization: Bearer ${ORCHESTRATOR_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{"run_terminal": {"enabled": true, "auth_required": true}}'
Ajouter/modifier une seule capability :
curl -X POST http://localhost:8080/api/devices/desk/capabilities/run_terminal \
-H "Authorization: Bearer ${ORCHESTRATOR_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{"enabled": true, "auth_required": true}'
Supprimer une capability :
curl -X DELETE http://localhost:8080/api/devices/phone/capabilities/get_location \
-H "Authorization: Bearer ${ORCHESTRATOR_ADMIN_KEY}"
Au prochain heartbeat du device concerné, capabilities_refresh_needed: true
sera retourné et le device devra refaire un /register complet.
7. Endpoints admin (Hermes)
| Endpoint | Description |
|---|---|
GET /api/devices |
Liste tous les devices et leur statut |
GET /api/devices/{device_name} |
Détails d'un device |
GET /api/commands/{command_id} |
Statut d'une commande |
PATCH /api/devices/{device_name}/capabilities |
Merge de capabilities |
POST /api/devices/{device_name}/capabilities/{capability_name} |
Ajoute/modifie une capability |
DELETE /api/devices/{device_name}/capabilities/{capability_name} |
Supprime une capability |
Tous nécessitent Authorization: Bearer ${ORCHESTRATOR_ADMIN_KEY}.
8. Ajouter un nouveau type d'appareil
- Choisir un
device_typeparmimobile_agent,desktop_agent,laptop_agent(ou étendre l'enumDeviceTypedansmodels.pypour un nouveau type, ex.tablet_agent). - Implémenter côté agent :
/register,/heartbeat, boucleGET /commandsPOST /results(+/confirmsi des capabilitiesauth_required).
- Définir les
capabilitiespertinentes pour ce type d'appareil. Aucune modification de l'orchestrateur n'est nécessaire — les actions inconnues sont routées automatiquement viaexec_action. - Enregistrer le device : il apparaîtra automatiquement dans
device_list()et sera routable par nom ou par capability.
9. Logs
journalctl --user -u hasan-orchestrator -f
Niveau de log configurable via LOG_LEVEL dans .env (DEBUG, INFO,
ERROR).
10. Architecture des fichiers
hasan-orchestrator/
main.py # FastAPI : endpoints REST devices + admin
registry.py # Gestion SQLite des devices (registry persistant)
command_queue.py # File de commandes en mémoire avec TTL
mcp_server.py # Serveur MCP (stdio) exposé à Hermes
auth.py # Validation des Bearer tokens (admin + sessions device)
models.py # Schémas Pydantic
config.py # Configuration (.env)
install.sh # Installation + service systemd
requirements.txt
.env.example
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
mcp-server-qdrant
这个仓库展示了如何为向量搜索引擎 Qdrant 创建一个 MCP (Managed Control Plane) 服务器的示例。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器