sassymcp
PyPI
v1.14.4
Published by an unidentified publisher — no publish provenance and no public repository, so the publisher could not be verified and the source cannot be independently located.
Unified MCP server for cross-platform (Windows/macOS/Linux) desktop automation, Android device control, security auditing, web inspection, cross-session communication, GitHub operations, and AI workflow persona
The grade answers one question — how safe is this server for you to adopt — so it is computed in two auditable stages. Nothing below is an opinion or an LLM's guess; every line is a real term the deterministic engine applied, and the same input always yields the same number.
1. Threat score — 100 − 6.3 = 94. What the published surface and source actually contain:
| Points | What was found | Category |
|---|---|---|
| −6.3 | Description names a credential store the tool cannot reach MTC-INJ-SCHEMA-1 | injection |
2. Client adoption risk — 94 − 12 = 82. Three small, subtract-only factors that reflect your risk in adopting it — a clean scan proves less on a powerful, unverified or barely-inspectable package, so the grade says so plainly:
| Points | Adoption-risk factor |
|---|---|
| −10 | capability blast radius (critical) — client exposure if the model is manipulated |
| −2 | publisher verification (unlinked) — no provenance/repo link, but the shipped source was fully read |
Capability observations and info notes are shown under Findings but never scored.
Open any row's finding below for the file, line and evidence behind a deduction.
This server (without client built-ins) exposes a complete data-exfiltration chain: sassy_combo_pr_review → sassy_gh_get_file_contents → sassy_adb_shell. Untrusted input is ingested, private data is read, and it can be sent to an external sink via the agent composing the tools (→). Static analysis proves the primitive exists, not that a specific run will occur.
Fix: Remove one leg of the trifecta: isolate untrusted-input tools from secret-reading tools and from egress tools, or require human approval between them.
Location: flow sassy_combo_pr_review → sassy_gh_get_file_contents → sassy_adb_shell
In the server's implementation (`sassymcp/modules/_security.py:652`): Reading private keys / cloud credentials, or serializing the whole environment, is a sensitive-data source that becomes exfiltration when combined with any egress. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: ".kube", home / ".netrc", home / ".pypirc", home / ".npmrc", ] # SassyMCP's own token st
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/modules/_security.py
In the server's implementation (`sassymcp/modules/linux.py:73`): Reading private keys / cloud credentials, or serializing the whole environment, is a sensitive-data source that becomes exfiltration when combined with any egress. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: for k in ("id_ed25519", "id_rsa", "id_ecdsa", "id_dsa")) try: import subprocess out = s
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/modules/linux.py
Tool "sassy_adb_shell" appears to run shell commands or evaluate code (keyword "shell" in tool name). Arbitrary execution driven by model input is one of the most dangerous MCP capabilities; combined with any untrusted input it becomes RCE.
Fix: Sandbox execution, allowlist commands/arguments, and never pass model output to a shell unescaped.
Location: tool sassy_adb_shell
Tool "sassy_linux_exec" appears to run shell commands or evaluate code (keyword "exec" in tool name). Arbitrary execution driven by model input is one of the most dangerous MCP capabilities; combined with any untrusted input it becomes RCE.
Fix: Sandbox execution, allowlist commands/arguments, and never pass model output to a shell unescaped.
Location: tool sassy_linux_exec
In the server's implementation (`sassymcp/modules/persona.py:140`): Evaluating strings as code is the most direct RCE primitive; if any tool input reaches it, the server executes attacker-chosen code. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: est for testing - Never eval() on external input **JavaScript/TypeScript:** - TypeScript strict mode, no `any` types -
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/modules/persona.py
In the server's implementation (`sassymcp/_jobctl.py:49`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: child between fork and exec (POSIX only). Start a new session (group leader) and, on Linux, ask the kernel to
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/_jobctl.py
In the server's implementation (`sassymcp/_phone_status.py:31`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: try: out = subprocess.run([adb, "devices", "-l"], capture_output=True, text=True, timeout=10) except Ex
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/_phone_status.py
In the server's implementation (`sassymcp/_platform.py:30`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: process_exec(*argv)` / `subprocess.run(argv)`, which avoids shell-injection and matches the existing module style. - m
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/_platform.py
In the server's implementation (`sassymcp/auth.py:102`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: try: result = subprocess.run( ["icacls.exe", str(path)], capture_output=True, text=Tru
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/auth.py
In the server's implementation (`sassymcp/desktop/bridge.py:112`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: = "nt": subprocess.Popen(["explorer", str(path)]) elif sys.platform == "darwin":
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/desktop/bridge.py
In the server's implementation (`sassymcp/modules/app_launcher.py:479`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: proc = subprocess.Popen([str(p)] + extra, creationflags=subprocess.DETACHED_PROCESS) ti
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/modules/app_launcher.py
In the server's implementation (`sassymcp/modules/linux.py:76`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: ubprocess out = subprocess.run( ["tasklist.exe", "/FI", "IMAGENAME eq pageant.exe", "/FO", "CSV", "/
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/modules/linux.py
In the server's implementation (`sassymcp/modules/web_inspector.py:230`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: ry: subprocess.run([cp, "--version"], capture_output=True, timeout=5) chrome = c
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/modules/web_inspector.py
In the server's implementation (`sassymcp/overlay/mesh.py:45`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: _hermes_proc = subprocess.Popen([sys.executable, str(hp)], cwd=str(repo_root()), env=env) except Exception
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/overlay/mesh.py
In the server's implementation (`sassymcp/server.py:902`): Spawning a shell/process is command-execution capability; with unsanitized tool input it is command injection / RCE. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: 0x00000008 subprocess.Popen( [sys.executable, "-m", "sassymcp.install", "--auto-other"],
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/server.py
Tool "sassy_wifi_profile" describes a credential store (SSH keys, cloud credentials, a keychain or an equivalent) that nothing in its input schema can address. A tool's interface is the honest statement of what it touches; prose that reaches past it is addressed to the model, not to a reader.
Evidence: Keychain
Fix: Remove the reference, or expose the target as an explicit, validated parameter so the client can see and consent to what the tool reads.
Location: tool sassy_wifi_profile · description
Tool "sassy_write_file" can write, overwrite or delete files (keyword "write_file" in tool name). Verify it is scoped to a safe directory.
Fix: Constrain file operations to an explicit, non-sensitive root; reject path traversal.
Location: tool sassy_write_file
Tool "sassy_gh_create_file" can write, overwrite or delete files (keyword "create_file" in tool name). Verify it is scoped to a safe directory.
Fix: Constrain file operations to an explicit, non-sensitive root; reject path traversal.
Location: tool sassy_gh_create_file
Tool "sassy_gh_delete_file" can write, overwrite or delete files (keyword "delete_file" in tool name). Verify it is scoped to a safe directory.
Fix: Constrain file operations to an explicit, non-sensitive root; reject path traversal.
Location: tool sassy_gh_delete_file
In the server's implementation (`sassymcp/modules/setup_wizard.py:836`): Loading a module chosen at runtime (from a variable) can pull in and run attacker-influenced code paths. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: try: __import__(pkg) packages[pkg] = {"installed": True} except ImportErr
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/modules/setup_wizard.py
In the server's implementation (`sassymcp/server.py:286`): Loading a module chosen at runtime (from a variable) can pull in and run attacker-influenced code paths. This is read from the code itself — not from the tool description — so a poisoned server cannot hide it behind honest-looking metadata.
Evidence: by name.""" return __import__(f"sassymcp.modules.{name}", fromlist=[name]) # ── Rate Limiter Setup ──────────────
Fix: Review this call path: confirm it never receives unsanitized tool input, constrain it, or remove it. Treat a server whose code reaches these sinks as high-capability regardless of what its tools claim.
Location: server sassymcp/server.py
Tool "sassy_adb_shell" can mutate/egress but declares no destructiveHint. Clients that don't default to spec-safe behavior may not prompt before running it.
Fix: Declare accurate annotations, and gate destructive tools on user confirmation regardless.
Location: tool sassy_adb_shell
Tool "sassy_write_file" can mutate/egress but declares no destructiveHint. Clients that don't default to spec-safe behavior may not prompt before running it.
Fix: Declare accurate annotations, and gate destructive tools on user confirmation regardless.
Location: tool sassy_write_file
Tool "sassy_gh_create_file" can mutate/egress but declares no destructiveHint. Clients that don't default to spec-safe behavior may not prompt before running it.
Fix: Declare accurate annotations, and gate destructive tools on user confirmation regardless.
Location: tool sassy_gh_create_file
Tool "sassy_gh_delete_file" can mutate/egress but declares no destructiveHint. Clients that don't default to spec-safe behavior may not prompt before running it.
Fix: Declare accurate annotations, and gate destructive tools on user confirmation regardless.
Location: tool sassy_gh_delete_file
Tool "sassy_linux_exec" can mutate/egress but declares no destructiveHint. Clients that don't default to spec-safe behavior may not prompt before running it.
Fix: Declare accurate annotations, and gate destructive tools on user confirmation regardless.
Location: tool sassy_linux_exec
Each tool and what it can reach — statically extracted from the published source.
sassy_adb_shellruns code / shellsassy_combo_pr_reviewingests untrusted inputsassy_crosslink_startnetwork egresssassy_gh_create_filewrites filessassy_gh_create_issuenetwork egresssassy_gh_delete_filewrites filessassy_gh_get_file_contentsreads sensitive datasassy_gh_get_secret_scanningreads sensitive datasassy_ghq_getreads sensitive datasassy_linux_execruns code / shellsassy_read_filereads sensitive datasassy_write_filewrites filessassy_adb_app_infono sensitive capabilitysassy_adb_devicesno sensitive capabilitysassy_adb_installno sensitive capabilitysassy_adb_logcatno sensitive capabilitysassy_adb_packagesno sensitive capabilitysassy_adb_pullno sensitive capabilitysassy_adb_pushno sensitive capabilitysassy_adb_screencapno sensitive capabilitysassy_adb_wifi_connectno sensitive capabilitysassy_android_logcatno sensitive capabilitysassy_android_processesno sensitive capabilitysassy_arp_tableno sensitive capabilitysassy_audit_clearno sensitive capabilitysassy_audit_false_positivesno sensitive capabilitysassy_audit_logno sensitive capabilitysassy_audit_searchno sensitive capabilitysassy_bt_androidno sensitive capabilitysassy_bt_devicesno sensitive capabilitysassy_bt_scanno sensitive capabilitysassy_clipboard_from_androidno sensitive capabilitysassy_clipboard_getno sensitive capabilitysassy_clipboard_setno sensitive capabilitysassy_clipboard_to_androidno sensitive capabilitysassy_close_windowno sensitive capabilitysassy_combo_codebase_grepno sensitive capabilitysassy_combo_phone_observeno sensitive capabilitysassy_context_estimateno sensitive capabilitysassy_coordination_boardno sensitive capabilitysassy_copyno sensitive capabilitysassy_crosslink_broadcastno sensitive capabilitysassy_crosslink_recvno sensitive capabilitysassy_crosslink_registerno sensitive capabilitysassy_crosslink_sendno sensitive capabilitysassy_crosslink_statusno sensitive capabilitysassy_crosslink_stopno sensitive capabilitysassy_dns_lookupno sensitive capabilitysassy_edit_blockno sensitive capabilitysassy_edit_multino sensitive capabilitysassy_eventlogno sensitive capabilitysassy_eventlog_searchno sensitive capabilitysassy_file_infono sensitive capabilitysassy_focus_windowno sensitive capabilitysassy_gh_add_issue_commentno sensitive capabilitysassy_gh_create_branchno sensitive capabilitysassy_gh_create_gistno sensitive capabilitysassy_gh_create_labelno sensitive capabilitysassy_gh_create_prno sensitive capabilitysassy_gh_create_pr_reviewno sensitive capabilitysassy_gh_create_repono sensitive capabilitysassy_gh_fork_repono sensitive capabilitysassy_gh_get_advisoryno sensitive capabilitysassy_gh_get_branch_protectionno sensitive capabilitysassy_gh_get_code_scanningno sensitive capabilitysassy_gh_get_commitno sensitive capabilitysassy_gh_get_dependabotno sensitive capabilitysassy_gh_get_discussionno sensitive capabilitysassy_gh_get_gistno sensitive capabilitysassy_gh_get_issueno sensitive capabilitysassy_gh_get_job_logsno sensitive capabilitysassy_gh_get_labelno sensitive capabilitysassy_gh_get_latest_releaseno sensitive capabilitysassy_gh_get_meno sensitive capabilitysassy_gh_get_notificationno sensitive capabilitysassy_gh_get_prno sensitive capabilitysassy_gh_get_projectno sensitive capabilitysassy_gh_get_release_by_tagno sensitive capabilitysassy_gh_get_runno sensitive capabilitysassy_gh_get_tagno sensitive capabilitysassy_gh_get_team_membersno sensitive capabilitysassy_gh_get_teamsno sensitive capabilitysassy_gh_get_treeno sensitive capabilitysassy_gh_list_branchesno sensitive capabilitysassy_gh_list_code_scanningno sensitive capabilitysassy_gh_list_commitsno sensitive capabilitysassy_gh_list_dependabotno sensitive capabilitysassy_gh_list_discussion_categoriesno sensitive capabilitysassy_gh_list_discussionsno sensitive capabilitysassy_gh_list_gistsno sensitive capabilitysassy_gh_list_global_advisoriesno sensitive capabilitysassy_gh_list_issuesno sensitive capabilitysassy_gh_list_labelsno sensitive capabilitysassy_gh_list_notificationsno sensitive capabilitysassy_gh_list_projectsno sensitive capabilitysassy_gh_list_prsno sensitive capabilitysassy_gh_list_releasesno sensitive capabilitysassy_gh_list_repo_advisoriesno sensitive capabilitysassy_gh_list_runsno sensitive capabilitysassy_gh_list_secret_scanningno sensitive capabilitysassy_gh_list_starredno sensitive capabilitysassy_gh_list_tagsno sensitive capabilitysassy_gh_mark_all_readno sensitive capabilitysassy_gh_mark_notification_readno sensitive capabilitysassy_gh_merge_prno sensitive capabilitysassy_gh_notification_subno sensitive capabilitysassy_gh_pr_filesno sensitive capabilitysassy_gh_pr_review_commentsno sensitive capabilitysassy_gh_pr_reviewsno sensitive capabilitysassy_gh_pr_statusno sensitive capabilitysassy_gh_protect_branchno sensitive capabilitysassy_gh_push_filesno sensitive capabilitysassy_gh_remove_branch_protectionno sensitive capabilitysassy_gh_repo_notification_subno sensitive capabilitysassy_gh_search_codeno sensitive capabilitysassy_gh_search_issuesno sensitive capabilitysassy_gh_search_orgsno sensitive capabilitysassy_gh_search_reposno sensitive capabilitysassy_gh_search_usersno sensitive capabilitysassy_gh_star_repono sensitive capabilitysassy_gh_trigger_workflowno sensitive capabilitysassy_gh_unstar_repono sensitive capabilitysassy_gh_update_fileno sensitive capabilitysassy_gh_update_gistno sensitive capabilitysassy_gh_update_issueno sensitive capabilitysassy_gh_update_labelno sensitive capabilitysassy_gh_update_prno sensitive capabilitysassy_gh_update_pr_branchno sensitive capabilitysassy_gh_update_repono sensitive capabilitysassy_ghq_issueno sensitive capabilitysassy_ghq_issuesno sensitive capabilitysassy_ghq_prno sensitive capabilitysassy_ghq_protectno sensitive capabilitysassy_ghq_pushno sensitive capabilitysassy_hooks_activateno sensitive capabilitysassy_hooks_deactivateno sensitive capabilitysassy_hooks_listno sensitive capabilitysassy_hooks_suggestno sensitive capabilitysassy_kill_processno sensitive capabilitysassy_launch_appno sensitive capabilitysassy_launch_exeno sensitive capabilitysassy_list_dirno sensitive capabilitysassy_memory_contextno sensitive capabilitysassy_memory_forgetno sensitive capabilitysassy_memory_handoffno sensitive capabilitysassy_memory_logno sensitive capabilitysassy_memory_milestonesno sensitive capabilitysassy_memory_recallno sensitive capabilitysassy_memory_rememberno sensitive capabilitysassy_memory_searchno sensitive capabilitysassy_memory_statsno sensitive capabilitysassy_minify_testno sensitive capabilitysassy_mkdirno sensitive capabilitysassy_moveno sensitive capabilitysassy_netstatno sensitive capabilitysassy_observability_healthno sensitive capabilitysassy_observability_metricsno sensitive capabilitysassy_observability_tool_statsno sensitive capabilitysassy_offline_commandsno sensitive capabilitysassy_offline_handoffno sensitive capabilitysassy_offline_statusno sensitive capabilitysassy_peer_announceno sensitive capabilitysassy_peer_delegateno sensitive capabilitysassy_peer_listno sensitive capabilitysassy_persona_capabilitiesno sensitive capabilitysassy_persona_contextno sensitive capabilitysassy_persona_decisionsno sensitive capabilitysassy_persona_fullno sensitive capabilitysassy_persona_observabilityno sensitive capabilitysassy_persona_practicesno sensitive capabilitysassy_persona_styleno sensitive capabilitysassy_phone_glanceno sensitive capabilitysassy_phone_keyno sensitive capabilitysassy_phone_openno sensitive capabilitysassy_phone_pauseno sensitive capabilitysassy_phone_resumeno sensitive capabilitysassy_phone_stateno sensitive capabilitysassy_phone_swipeno sensitive capabilitysassy_phone_tapno sensitive capabilitysassy_phone_typeno sensitive capabilitysassy_phone_uino sensitive capabilitysassy_phone_watchno sensitive capabilitysassy_port_scanno sensitive capabilitysassy_processesno sensitive capabilitysassy_read_multipleno sensitive capabilitysassy_resize_windowno sensitive capabilitysassy_safe_deleteno sensitive capabilitysassy_scrcpy_recordno sensitive capabilitysassy_scrcpy_startno sensitive capabilitysassy_scrcpy_stopno sensitive capabilitysassy_search_filesno sensitive capabilitysassy_self_checkno sensitive capabilitysassy_snap_windowno sensitive capabilitysassy_tool_catalogno sensitive capabilitysassy_tool_group_toggleno sensitive capabilitysassy_tool_groupsno sensitive capabilitysassy_tool_usageno sensitive capabilitysassy_tracerouteno sensitive capabilitysassy_wifi_networksno sensitive capabilitysassy_wifi_profileno sensitive capabilityCross-tool combinations that form a data-exfiltration primitive (untrusted input → sensitive source → external sink).
Scan history per published version. The engine is deterministic — the same version always yields the same score, so a changed score means the package itself changed.
| Version | Score | Findings | Engine | Scanned |
|---|---|---|---|---|
v1.14.4 latest |
B 82/100 | 27 | 1.13.0 | 2026-08-25 |
v1.14.3 |
B 82/100 | 27 | 1.12.1 | 2026-08-13 |
v1.14.2 |
B 82/100 | 27 | 1.12.1 | 2026-07-31 |
v1.14.1 |
B 82/100 | 27 | 1.12.1 | 2026-07-29 |
v1.13.0 |
B 82/100 | 29 | 1.12.1 | 2026-07-27 |
Show this server's live Trust Score in your README, docs or website. The badge is served straight from the registry and updates automatically after every rescan — no API key needed. It links back to this page, so anyone who sees the grade can also read the findings behind it instead of taking a number on faith.
The score above is reproducible: the same package version always yields the same result. Run it locally or over the free API — no account, no LLM, fully deterministic.
npx mcptrustchecker scan sassymcp --online --registry pypi
Hotel booking MCP server — 300K+ properties, real confirmation numbers, loyalty programs. Builders monetize every booking via Stripe Connect. The first MCP server that completes real hotel reservations inside AI conversations.
Manage AdGuard Home through AI assistants
Read-only Azure DevOps for MCP clients using only your existing browser session — no PAT, no Azure CLI. Browse work items, pull requests, comments, attachments and Artifacts feeds across every project, repo and feed you can access.
MCP server for Adobe Experience Manager Assets integration development
Servidor MCP para el tiempo oficial de España (API pública OpenData de AEMET). Predicción, observación y avisos como herramientas MCP tipadas.
A standalone MCP stdio bridge for Affinity by Canva's local MCP SSE server.