mcp-agent-template

io.github.amineutron由 GitHub 账号 amineutron 发布v0.2.0更新于 Nov 7, 2026

Enterprise MCP guard: roles, allowlist policy, human confirmation, JSONL audit log, example tools.

概览

AI 生成的概览

带防护的企业级 MCP 模板:角色权限、白名单策略、人工确认与 JSONL 审计日志,并附带工单、通讯录与库存示例工具。

可以做什么
  • 管理支持工单:列出、查看、创建、关闭与删除工单,按策略“紧急”优先级仅限人工设置
  • 查询只读通讯录:按姓名、标识、邮箱、职务或部门搜索,查看人员档案与所属组,列出组成员
  • 查看只读 SQL 库存库:列出表与列,执行 SELECT 查询,写入由数据库本身拒绝
  • 每次调用都经过白名单与调用者角色校验,破坏性操作需人工确认
  • 以关联 ID 将每次调用写入 JSONL 审计日志,并遮蔽疑似密钥的参数
  • 可作为模板,用同一套策略与审计层搭建自己的受控 MCP 服务器
适用场景
适合 IT 团队希望让 AI 助手访问内部工具,但需要角色限制、白名单、破坏性操作人工批准和审计留痕的场景。也可作为编写自有受控 MCP 服务器的起点;自带示例使用本地虚构数据。
运行要求
以 Python 包通过 uvx 在本地运行(stdio 传输),仅限桌面。可选环境变量:MCP_AGENT_TEMPLATE_ROLE(lecteur、operateur 或 admin,默认 lecteur)、MCP_AGENT_TEMPLATE_CONFIRM(elicit 或 client)、MCP_AGENT_TEMPLATE_AUDIT_DIR 与 MCP_AGENT_TEMPLATE_DATA_DIR。未声明认证或 API 密钥;无云端、无遥测。
安装前请注意
调用者角色来自客户端配置,能修改该配置的人即可自行取得 admin 权限。delete_ticket 等破坏性工具会永久删除数据,需 admin 加人工确认;客户端无法提问时操作会被拒绝。审计日志写入磁盘(权限 0600),疑似密钥参数会被遮蔽,但仍应确认记录内容。自带数据为虚构;替换为真实系统后助手可触及的范围随之改变。

安装

在 SourceWeft 中

  1. 打开 控制台中的 mcp-agent-template,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

mcp-agent-template — un agent MCP d'entreprise, garde

[CI] [License: AGPL-3.0 + commercial] [Python 3.11+]

English summary. A template for MCP servers that an IT department can let an LLM agent use: every tool call goes through an allowlist policy (policy.yaml), a caller role (lecteur / operateur / admin, derived from the MCP tool annotations), per-parameter allowed values, a human confirmation for destructive actions (MCP elicitation, both the 2025-11-25 and 2026-07-28 protocols), and a JSONL audit log (mode 0600, one correlation id per call). The mcp-agent-template package ships two runnable examples: an enterprise one (tickets, a read-only LDAP-like directory, a read-only SQL inventory, all on fictitious local data) and a generic ops one (systemd and docker status, restart with confirmation). Local-first, self-hosted, on-prem; no cloud, no telemetry. Dual licensed: AGPL-3.0, or a commercial licence for companies of any size.


Donner des outils a un agent IA dans une entreprise pose toujours les memes questions : qui a le droit de faire quoi, qui a valide une action dangereuse, et ou est la trace. Ce depot est un modele (bouton « Use this template ») qui y repond une fois pour toutes, autour du SDK MCP officiel.

Ce que fait la garde

Chaque appel d'outil passe, dans l'ordre :

  1. Liste blanche (policy.yaml) : un outil absent est refuse.

  2. Role de l'appelant : le role minimal vient du type d'outil, et la politique peut seulement le durcir.

    Type d'outilAnnotation MCP publieeRole minimal
    lecturereadOnlyHintlecteur
    ecriture non destructrice—operateur
    destructifdestructiveHintadmin + confirmation humaine
  3. Valeurs permises : par exemple, seules certaines unites systemd peuvent etre redemarrees.

  4. Confirmation humaine pour les outils destructifs : le client affiche la question a l'humain (elicitation MCP). Les controles 1 a 3 passent AVANT : on ne demande jamais a l'humain d'approuver ce que le role n'autorise pas. Tout ce qui n'est pas un « oui » explicite vaut refus, y compris un client qui ne sait pas poser la question.

  5. Journal d'audit JSONL, fichier en 0600, un identifiant de correlation par appel qui relie la decision, la confirmation et le resultat. Les parametres qui ressemblent a des secrets (password, token, api_key...) sont masques.

Un refus renvoie une erreur lisible a l'agent, jamais un faux succes.

Essayer

bash
uvx mcp-agent-template --helpuvx mcp-agent-template serve --example enterprise   # tickets, annuaire, inventaire (donnees fictives)uvx mcp-agent-template serve --example ops          # systemd et dockeruvx mcp-agent-template check-policy policy.yaml     # valide une politique et resume ses regles

Dans un client MCP (Claude Code, Claude Desktop...) :

json
{  "mcpServers": {    "entreprise": {      "command": "uvx",      "args": ["mcp-agent-template", "serve", "--example", "enterprise"],      "env": { "MCP_AGENT_TEMPLATE_ROLE": "operateur" }    }  }}
VariableRoleDefaut
MCP_AGENT_TEMPLATE_ROLErole de l'appelant : lecteur, operateur, adminlecteur
MCP_AGENT_TEMPLATE_CONFIRMelicit : l'humain confirme via le client ; client : le client confirme deja lui-meme (il lit destructiveHint)elicit
MCP_AGENT_TEMPLATE_AUDIT_DIRdossier du journal d'audit~/.local/state/mcp-agent-template
MCP_AGENT_TEMPLATE_DATA_DIRbases SQLite des exemples~/.local/state/mcp-agent-template-demo

Le role vient pour l'instant de la configuration du client : chaque poste ou chaque profil recoit le sien. La source du role est une petite interface (RoleSource) : une authentification par jeton pourra s'y brancher sans toucher aux outils.

Les exemples

Entreprise (--example enterprise), sur des donnees FICTIVES d'une societe « Exemple SA » creees en local, sans aucun service externe :

  • support : list_tickets, get_ticket, create_ticket (la priorite « critique » est reservee aux humains par la politique), close_ticket, delete_ticket (admin + confirmation) ;
  • annuaire en lecture seule, facon LDAP : search_directory, get_user, group_members ;
  • inventaire en SQL lecture seule : list_tables, query_inventory. Deux verrous : la base est ouverte en mode=ro, et un autorisateur SQLite refuse toute ecriture, PRAGMA ou ATTACH, meme cachee dans un WITH.

Ops (--example ops) : service_status et list_containers en lecture, restart_service limite aux unites listees par la politique, apres confirmation.

Ecrire son propre serveur

python
from mcp.server.mcpserver import MCPServerfrom mcp_agent_template import Guard, Policy, ToolKind
server = MCPServer("mon-agent")guard = Guard(server, Policy.load("policy.yaml"))
@guard.tool(ToolKind.READ, title="Lister les commandes")def list_orders(status: str = "ouverte") -> list[dict]:    """Commandes du jour."""    ...
@guard.tool(ToolKind.DESTRUCTIVE, title="Annuler une commande")def cancel_order(order_id: int) -> dict:    """Annule une commande (admin + confirmation humaine)."""    ...
server.run()
yaml
# policy.yamlversion: 1default: denytools:  list_orders: {}  cancel_order:    allowed_values:      order_id: ["1042", "1043"]

Pour brancher un vrai outil de tickets, un vrai annuaire LDAP ou une vraie base, remplacer les classes de src/mcp_agent_template/examples/stores.py : les outils MCP et la garde ne changent pas.

Developpement

bash
uv syncuv run pytest        # garde, politique, audit, exemples, protocoles 2025-11-25 et 2026-07-28, stdiouv run ruff check src tests

Un devcontainer est fourni (.devcontainer/).

Licence

Double licence :

  • AGPL-3.0 (LICENSE) : gratuite pour les particuliers, les associations et l'enseignement ou la recherche ;
  • licence commerciale pour les entreprises, quelle que soit leur taille : voir COMMERCIAL-LICENSE.md.

Les contributions sont acceptees sous l'accord CLA.md.

Fait partie de l'ecosysteme Lyra

Meme approche que fedora-agents (journal d'audit avec identifiant de correlation, annotations MCP) et Lyra, l'assistant vocal French-first qui fait confirmer l'humain avant chaque action sensible.

来源:README.md,提交 6a8960a

工具

10

list_tickets

Lister les tickets

Tickets du support, les plus recents d'abord. status : ouvert, en_cours, resolu ou ferme.

输入参数limitstatus

get_ticket

Lire un ticket

Detail d'un ticket.

输入参数ticket_id必填

create_ticket

Creer un ticket

Ouvre un ticket. priority : basse, normale, haute ou critique.

输入参数title必填priorityrequesterdescription

close_ticket

Clore un ticket

Passe un ticket a l'etat ferme avec sa resolution.

输入参数ticket_id必填resolution必填

delete_ticket

Supprimer un ticket

Supprime definitivement un ticket (confirmation humaine, role admin).

输入参数ticket_id必填

search_directory

Chercher dans l'annuaire

Personnes dont le nom, l'identifiant, le mail, la fonction ou le service contient query.

输入参数query必填include_inactive

get_user

Fiche annuaire

Fiche d'une personne et ses groupes.

输入参数uid必填

group_members

Membres d'un groupe

Identifiants des membres actifs d'un groupe de l'annuaire.

输入参数group必填

list_tables

Tables de l'inventaire

Tables et colonnes de la base d'inventaire (parc, licences, sauvegardes).

无需输入参数。

query_inventory

Requete SQL (lecture seule)

Une requete SELECT sur l'inventaire ; toute ecriture est refusee par la base elle-meme.

输入参数sql必填limit

版本历史

1
  1. v0.2.0最新Nov 4, 2026

评分

已满足适用检查项的 90%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分
  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分