w
This commit is contained in:
@@ -4,6 +4,7 @@ __pycache__/
|
||||
.mcpregistry_*
|
||||
.playwright-mcp/
|
||||
.salt
|
||||
.venv
|
||||
*.egg-info/
|
||||
*.pyc
|
||||
build
|
||||
|
||||
+2
-2
@@ -119,12 +119,12 @@ def _parse_args(argv=None) -> argparse.Namespace:
|
||||
parser.add_argument(
|
||||
"--enabled-tools",
|
||||
default=None,
|
||||
help="Comma-separated whitelist of tool names to expose",
|
||||
help="Comma-separated whitelist of tool names or group aliases (read-only, write-only) to expose",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--disabled-tools",
|
||||
default=None,
|
||||
help="Comma-separated blacklist of tool names to hide",
|
||||
help="Comma-separated blacklist of tool names or group aliases (read-only, write-only) to hide",
|
||||
)
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
@@ -213,6 +213,59 @@ class SessionKeepalive:
|
||||
logger.debug("Keepalive ping failed (non-critical): %s", exc)
|
||||
|
||||
|
||||
# ── Tool groups ─────────────────────────────────────────────────────────
|
||||
|
||||
TOOL_GROUPS: dict[str, set[str]] = {
|
||||
"read-only": {
|
||||
"get_emails",
|
||||
"get_email",
|
||||
"search_emails",
|
||||
"get_calendar_events",
|
||||
"get_event_links",
|
||||
"find_person",
|
||||
"get_folders",
|
||||
"check_session",
|
||||
"find_free_time",
|
||||
"find_meeting_time",
|
||||
"get_meeting_stats",
|
||||
"get_meeting_contacts",
|
||||
"download_event_attachments",
|
||||
"get_email_links",
|
||||
"download_attachments",
|
||||
"login",
|
||||
},
|
||||
"write-only": {
|
||||
"send_email",
|
||||
"reply_email",
|
||||
"forward_email",
|
||||
"delete_email",
|
||||
"move_email",
|
||||
"mark_email_read",
|
||||
"create_meeting",
|
||||
"update_meeting",
|
||||
"cancel_meeting",
|
||||
"respond_to_meeting",
|
||||
"create_folder",
|
||||
"rename_folder",
|
||||
"empty_folder",
|
||||
"delete_folder",
|
||||
"move_folder",
|
||||
},
|
||||
}
|
||||
|
||||
# ── Alias resolution ────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def _resolve_aliases(names: list[str]) -> set[str]:
|
||||
resolved: set[str] = set()
|
||||
for name in names:
|
||||
if name in TOOL_GROUPS:
|
||||
resolved |= TOOL_GROUPS[name]
|
||||
else:
|
||||
resolved.add(name)
|
||||
return resolved
|
||||
|
||||
|
||||
# ── Tool filtering ───────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -236,8 +289,24 @@ def apply_tool_filters(
|
||||
if not canonical:
|
||||
return
|
||||
|
||||
# ── Group integrity check ───────────────────────────────────────────────
|
||||
all_grouped: set[str] = set().union(*TOOL_GROUPS.values())
|
||||
missing = canonical - all_grouped
|
||||
assert not missing, f"Tools not in any group: {sorted(missing)}"
|
||||
overlaps: set[str] = set()
|
||||
for i, (g1, s1) in enumerate(TOOL_GROUPS.items()):
|
||||
for g2, s2 in list(TOOL_GROUPS.items())[i + 1 :]:
|
||||
overlaps |= s1 & s2
|
||||
assert not overlaps, f"Tools in multiple groups: {sorted(overlaps)}"
|
||||
|
||||
allowed: set[str] = set(canonical)
|
||||
|
||||
# ── Resolve aliases ────────────────────────────────────────────────────
|
||||
if enabled:
|
||||
enabled = sorted(_resolve_aliases(enabled))
|
||||
if disabled:
|
||||
disabled = sorted(_resolve_aliases(disabled))
|
||||
|
||||
# ── Whitelist ──────────────────────────────────────────────────────────
|
||||
if enabled:
|
||||
enabled_set = {n.strip() for n in enabled if n.strip()}
|
||||
|
||||
Reference in New Issue
Block a user