"""VS Code-style icons for MCP tools.
SVG paths from microsoft/vscode-codicons (MIT License).
https://github.com/microsoft/vscode-codicons
Colors match VS Code's debug toolbar theme for familiar visual language.
"""
from __future__ import annotations
from urllib.parse import quote
from mcp.types import Icon
from ..core.constants import ToolName
# VS Code debug toolbar colors
DEBUG_GREEN = "#89D185" # Start, continue, restart, run
DEBUG_BLUE = "#75BEFF" # Step into/over/out, navigation
DEBUG_RED = "#F48771" # Stop, breakpoints
DEBUG_PURPLE = "#C586C0" # Inspect, variables
DEBUG_GRAY = "#CCCCCC" # Config, context, neutral
def _make_icon(path: str, color: str, viewbox: str = "0 0 16 16") -> Icon:
"""Create Icon from SVG path with color.
Parameters
----------
path : str
SVG path data (d attribute)
color : str
Fill color (hex)
viewbox : str
SVG viewBox attribute
Returns
-------
Icon
MCP Icon with data URI
"""
svg = (
f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="{viewbox}" '
f'fill="{color}"><path d="{path}"/></svg>'
)
return Icon(src=f"data:image/svg+xml,{quote(svg)}", mimeType="image/svg+xml")
def _make_multi_path_icon(
paths: list[str],
color: str,
viewbox: str = "0 0 16 16",
) -> Icon:
"""Create Icon from multiple SVG paths with color.
Parameters
----------
paths : list[str]
List of SVG path data (d attributes)
color : str
Fill color (hex)
viewbox : str
SVG viewBox attribute
Returns
-------
Icon
MCP Icon with data URI
"""
path_elements = "".join(f'<path d="{p}"/>' for p in paths)
svg = (
f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="{viewbox}" '
f'fill="{color}">{path_elements}</svg>'
)
return Icon(src=f"data:image/svg+xml,{quote(svg)}", mimeType="image/svg+xml")
# SVG paths from microsoft/vscode-codicons (MIT License)
# https://github.com/microsoft/vscode-codicons/tree/main/src/icons
_PATHS = {
# debug-start (play button) - 16x16
"debug_start": (
"M4.506 3.503L12.501 8L4.501 12.5L4.506 3.503ZM4.502 1.998C3.718 1.998 "
"3 2.626 3 3.5V12.5C3 13.374 3.718 14.002 4.502 14.002C4.747 14.002 "
"4.998 13.941 5.235 13.807L13.235 9.307C14.254 8.734 14.254 7.266 "
"13.235 6.692L5.235 2.193C4.997 2.059 4.746 1.998 4.502 1.998Z"
),
# debug-stop (square) - 16x16
"debug_stop": (
"M12.5 3.5V12.5H3.5V3.5H12.5ZM12.5 2H3.5C2.672 2 2 2.672 2 3.5V12.5"
"C2 13.328 2.672 14 3.5 14H12.5C13.328 14 14 13.328 14 12.5V3.5"
"C14 2.672 13.328 2 12.5 2Z"
),
# debug-restart (circular arrow) - 16x16
"debug_restart": (
"M14 8C14 8.81 13.842 9.596 13.528 10.336C13.224 11.053 12.791 11.694 "
"12.241 12.243C11.694 12.791 11.053 13.224 10.337 13.528C9.596 13.841 "
"8.81 14 8 14C7.19 14 6.404 13.842 5.664 13.528C4.947 13.224 4.306 "
"12.791 3.757 12.242C3.208 11.693 2.776 11.053 2.472 10.337C2.31 9.956 "
"2.488 9.516 2.869 9.354C3.251 9.19 3.69 9.37 3.852 9.751C4.081 10.288 "
"4.405 10.77 4.818 11.181C5.23 11.595 5.712 11.919 6.249 12.148C7.356 "
"12.615 8.643 12.615 9.752 12.148C10.288 11.919 10.77 11.595 11.181 "
"11.183C11.595 10.77 11.919 10.288 12.148 9.751C12.381 9.197 12.501 "
"8.608 12.501 8C12.501 7.392 12.382 6.803 12.148 6.248C11.919 5.712 "
"11.595 5.23 11.182 4.819C10.77 4.405 10.288 4.081 9.751 3.852C8.644 "
"3.385 7.357 3.385 6.248 3.852C5.712 4.081 5.23 4.405 4.819 4.817"
"C4.608 5.027 4.42 5.256 4.257 5.5H6.249C6.663 5.5 6.999 5.836 6.999 "
"6.25C6.999 6.664 6.663 7 6.249 7H2.749C2.335 7 1.999 6.664 1.999 6.25"
"V2.75C1.999 2.336 2.335 2 2.749 2C3.163 2 3.499 2.336 3.499 2.75V4.032"
"C3.582 3.938 3.668 3.845 3.758 3.757C4.305 3.209 4.946 2.776 5.662 "
"2.472C7.144 1.845 8.854 1.845 10.335 2.472C11.052 2.776 11.693 3.209 "
"12.242 3.758C12.791 4.307 13.223 4.947 13.527 5.663C13.84 6.404 "
"13.999 7.19 13.999 8H14Z"
),
# debug-step-over (arrow over dot) - 16x16
"debug_step_over": (
"M9.999 13C9.999 14.103 9.102 15 7.999 15C6.896 15 5.999 14.103 5.999 "
"13C5.999 11.897 6.896 11 7.999 11C9.102 11 9.999 11.897 9.999 13Z"
"M13.249 2C12.835 2 12.499 2.336 12.499 2.75V4.027C11.382 2.759 9.759 "
"2 7.999 2C5.032 2 2.479 4.211 2.06 7.144C2.001 7.554 2.287 7.934 "
"2.697 7.993C2.733 7.999 2.769 8.001 2.804 8.001C3.171 8.001 3.492 "
"7.731 3.546 7.357C3.86 5.159 5.775 3.501 8 3.501C9.529 3.501 10.919 "
"4.264 11.743 5.501H9.75C9.336 5.501 9 5.837 9 6.251C9 6.665 9.336 "
"7.001 9.75 7.001H13.25C13.664 7.001 14 6.665 14 6.251V2.751C14 2.337 "
"13.664 2.001 13.25 2.001L13.249 2Z"
),
# debug-step-into (arrow down with dot) - 16x16
"debug_step_into": (
"M10 13C10 14.103 9.103 15 8 15C6.897 15 6 14.103 6 13C6 11.897 6.897 "
"11 8 11C9.103 11 10 11.897 10 13ZM12.03 5.22C11.737 4.927 11.262 4.927 "
"10.969 5.22L8.749 7.44V1.75C8.749 1.336 8.413 1 7.999 1C7.585 1 7.249 "
"1.336 7.249 1.75V7.439L5.029 5.219C4.736 4.926 4.261 4.926 3.968 5.219"
"C3.675 5.512 3.675 5.987 3.968 6.28L7.468 9.78C7.614 9.926 7.806 10 "
"7.998 10C8.19 10 8.382 9.927 8.528 9.78L12.028 6.28C12.321 5.987 "
"12.321 5.512 12.028 5.219L12.03 5.22Z"
),
# debug-step-out (arrow up with dot) - 16x16
"debug_step_out": (
"M9.998 13C9.998 14.103 9.101 15 7.998 15C6.895 15 5.998 14.103 5.998 "
"13C5.998 11.897 6.895 11 7.998 11C9.101 11 9.998 11.897 9.998 13Z"
"M12.03 4.72L8.53 1.22C8.237 0.927 7.762 0.927 7.469 1.22L3.969 4.72"
"C3.676 5.013 3.676 5.488 3.969 5.781C4.262 6.074 4.737 6.074 5.03 "
"5.781L7.25 3.561V9.25C7.25 9.664 7.586 10 8 10C8.414 10 8.75 9.664 "
"8.75 9.25V3.561L10.97 5.781C11.116 5.927 11.308 6.001 11.5 6.001"
"C11.692 6.001 11.884 5.928 12.03 5.781C12.323 5.488 12.323 5.013 "
"12.03 4.72Z"
),
# search (magnifying glass) - 16x16
"search": (
"M10.02 10.727C9.066 11.522 7.839 12 6.5 12C3.462 12 1 9.538 1 6.5"
"C1 3.462 3.462 1 6.5 1C9.538 1 12 3.462 12 6.5C12 7.839 11.522 9.066 "
"10.727 10.02L13.854 13.146C14.049 13.342 14.049 13.658 13.854 13.854"
"C13.658 14.049 13.342 14.049 13.146 13.854L10.02 10.727ZM11 6.5"
"C11 4.015 8.985 2 6.5 2C4.015 2 2 4.015 2 6.5C2 8.985 4.015 11 6.5 11"
"C8.985 11 11 8.985 11 6.5Z"
),
# circle-filled (breakpoint) - 16x16
"circle_filled": (
"M8 4C8.367 4 8.721 4.048 9.063 4.145C9.404 4.238 9.721 4.372 10.016 "
"4.547C10.313 4.721 10.582 4.931 10.824 5.176C11.069 5.418 11.279 5.688 "
"11.453 5.984C11.628 6.279 11.762 6.596 11.856 6.938C11.952 7.279 12 "
"7.633 12 8C12 8.367 11.952 8.721 11.856 9.063C11.762 9.404 11.628 9.723 "
"11.453 10.02C11.279 10.314 11.069 10.583 10.824 10.828C10.582 11.07 "
"10.313 11.279 10.016 11.453C9.721 11.628 9.404 11.763 9.063 11.859"
"C8.721 11.953 8.367 12 8 12C7.633 12 7.279 11.953 6.938 11.859C6.596 "
"11.763 6.277 11.628 5.98 11.453C5.686 11.279 5.417 11.07 5.172 10.828"
"C4.93 10.583 4.721 10.314 4.547 10.02C4.372 9.723 4.237 9.404 4.141 "
"9.063C4.047 8.721 4 8.367 4 8C4 7.633 4.047 7.279 4.141 6.938C4.237 "
"6.596 4.372 6.279 4.547 5.984C4.721 5.688 4.93 5.418 5.172 5.176"
"C5.417 4.931 5.686 4.721 5.98 4.547C6.277 4.372 6.596 4.238 6.938 "
"4.145C7.279 4.048 7.633 4 8 4Z"
),
# info (i in circle) - 16x16
"info": (
"M8.499 7.5C8.499 7.224 8.275 7 7.999 7C7.723 7 7.499 7.224 7.499 7.5"
"V10.5C7.499 10.776 7.723 11 7.999 11C8.275 11 8.499 10.776 8.499 10.5"
"V7.5ZM8.748 5.5C8.748 5.914 8.413 6.249 7.999 6.249C7.585 6.249 7.25 "
"5.914 7.25 5.5C7.25 5.086 7.585 4.751 7.999 4.751C8.413 4.751 8.748 "
"5.086 8.748 5.5ZM8 1C4.134 1 1 4.134 1 8C1 11.866 4.134 15 8 15"
"C11.866 15 15 11.866 15 8C15 4.134 11.866 1 8 1ZM2 8C2 4.686 4.686 2 "
"8 2C11.314 2 14 4.686 14 8C14 11.314 11.314 14 8 14C4.686 14 2 11.314 "
"2 8Z"
),
# debug (bug icon) - 24x24
"debug": (
"M21.75 12H19.5V9C19.5 8.445 19.347 7.925 19.083 7.478L20.78 5.781"
"C21.072 5.489 21.072 5.013 20.78 4.721C20.487 4.428 20.012 4.428 "
"19.719 4.721L18.023 6.417C17.576 6.153 17.055 6 16.5 6C16.5 3.519 "
"14.481 1.5 12 1.5C9.519 1.5 7.5 3.519 7.5 6C6.945 6 6.425 6.153 5.978 "
"6.417L4.281 4.721C3.989 4.428 3.513 4.428 3.221 4.721C2.928 5.013 "
"2.928 5.489 3.221 5.781L4.917 7.478C4.653 7.925 4.5 8.445 4.5 9V12"
"H2.25C1.836 12 1.5 12.336 1.5 12.75C1.5 13.164 1.836 13.5 2.25 13.5"
"H4.5C4.5 15.299 5.136 16.95 6.195 18.245L3.594 20.846C3.302 21.138 "
"3.302 21.614 3.594 21.906C3.741 22.053 3.933 22.125 4.125 22.125"
"C4.317 22.125 4.509 22.052 4.656 21.906L7.257 19.305C8.55 20.364 "
"10.203 21 12.002 21C13.8 21 15.452 20.364 16.746 19.305L19.347 21.906"
"C19.494 22.053 19.686 22.125 19.878 22.125C20.07 22.125 20.262 22.052 "
"20.409 21.906C20.702 21.614 20.702 21.138 20.409 20.846L17.808 18.245"
"C18.867 16.952 19.503 15.299 19.503 13.5H21.753C22.167 13.5 22.503 "
"13.164 22.503 12.75C22.503 12.336 22.167 12 21.753 12H21.75ZM12 3"
"C13.655 3 15 4.346 15 6H9C9 4.346 10.346 3 12 3ZM18 13.5C18 16.809 "
"15.309 19.5 12 19.5C8.691 19.5 6 16.809 6 13.5V9C6 8.172 6.672 7.5 "
"7.5 7.5H16.5C17.328 7.5 18 8.172 18 9V13.5ZM14.781 11.031L13.062 12.75"
"L14.781 14.469C15.074 14.762 15.074 15.237 14.781 15.53C14.634 15.677 "
"14.442 15.749 14.25 15.749C14.058 15.749 13.866 15.675 13.719 15.53"
"L12 13.811L10.281 15.53C10.134 15.677 9.942 15.749 9.75 15.749"
"C9.558 15.749 9.366 15.675 9.219 15.53C8.927 15.237 8.927 14.762 9.219 "
"14.469L10.938 12.75L9.219 11.031C8.927 10.739 8.927 10.263 9.219 9.971"
"C9.512 9.678 9.987 9.678 10.28 9.971L11.999 11.69L13.718 9.971"
"C14.01 9.678 14.486 9.678 14.778 9.971C15.071 10.263 15.071 10.739 "
"14.778 11.031H14.781Z"
),
# package (3D box) - 16x16
"package": (
"M14.039 3.286L9.077 1.378C8.384 1.111 7.616 1.111 6.923 1.378L1.962 "
"3.286C1.383 3.509 1 4.065 1 4.686V11.312C1 11.933 1.382 12.489 1.962 "
"12.712L6.923 14.62C7.616 14.887 8.384 14.887 9.077 14.62L14.039 12.712"
"C14.618 12.489 15 11.933 15 11.312V4.686C15 4.065 14.618 3.509 14.039 "
"3.286ZM7.5 13.757C7.426 13.738 7.354 13.715 7.282 13.687L2.32 11.779"
"C2.127 11.705 2 11.519 2 11.312V4.971L7.5 7.328V13.757ZM2.564 4.126"
"L7.282 2.311C7.744 2.133 8.256 2.133 8.718 2.311L13.436 4.126L8 6.456"
"L2.564 4.126ZM14 11.313C14 11.52 13.873 11.705 13.68 11.78L8.718 13.688"
"C8.646 13.716 8.574 13.739 8.5 13.758V7.33L14 4.973V11.313Z"
),
}
# symbol-variable has multiple paths - 16x16
_SYMBOL_VARIABLE_PATHS = [
(
"M11.279 5.79L8.799 5.066C8.59 5.006 8.372 5.015 8.168 5.09L4.648 6.41"
"C4.26 6.556 4 6.932 4 7.347V9.14C4 9.571 4.274 9.952 4.684 10.088"
"L7.165 10.915C7.268 10.95 7.376 10.967 7.483 10.967C7.611 10.967 "
"7.739 10.943 7.859 10.894L11.376 9.465C11.755 9.312 12 8.948 12 8.539"
"V6.75C12 6.308 11.703 5.913 11.279 5.79ZM11 8.539L7.483 9.968L5 9.14"
"V7.347L8.521 6.027L11 6.751V8.54V8.539ZM7.48 7.467L8.807 6.914"
"C9.06 6.809 9.355 6.928 9.461 7.183C9.566 7.438 9.446 7.731 9.191 "
"7.837L7.999 8.334V8.626C7.999 8.902 7.775 9.126 7.499 9.126"
"C7.223 9.126 6.999 8.902 6.999 8.626V8.361L6.591 8.225C6.329 8.138 "
"6.188 7.855 6.275 7.593C6.364 7.331 6.647 7.192 6.908 7.277L7.48 7.467Z"
),
(
"M12.5 14H11.5C11.224 14 11 13.776 11 13.5C11 13.224 11.224 13 11.5 13"
"H12.5C12.776 13 13 12.775 13 12.5V3.5C13 3.225 12.776 3 12.5 3H11.5"
"C11.224 3 11 2.776 11 2.5C11 2.224 11.224 2 11.5 2H12.5C13.327 2 14 "
"2.673 14 3.5V12.5C14 13.327 13.327 14 12.5 14ZM5 13.5C5 13.224 4.776 "
"13 4.5 13H3.5C3.224 13 3 12.775 3 12.5V3.5C3 3.225 3.224 3 3.5 3H4.5"
"C4.776 3 5 2.776 5 2.5C5 2.224 4.776 2 4.5 2H3.5C2.673 2 2 2.673 2 "
"3.5V12.5C2 13.327 2.673 14 3.5 14H4.5C4.776 14 5 13.776 5 13.5Z"
),
]
# settings-gear - 24x24
_SETTINGS_GEAR_PATH = (
"M12 9C10.343 9 9 10.343 9 12C9 13.658 10.343 15 12 15C13.658 15 15 13.658 "
"15 12C15 10.343 13.658 9 12 9ZM12 13.5C11.172 13.5 10.5 12.828 10.5 12"
"C10.5 11.172 11.172 10.5 12 10.5C12.828 10.5 13.5 11.172 13.5 12"
"C13.5 12.828 12.828 13.5 12 13.5ZM21.848 14.573L19.919 12.942"
"C19.868 12.899 19.82 12.851 19.776 12.8C19.332 12.279 19.397 11.501 "
"19.919 11.058L21.848 9.428C22.04 9.266 22.113 9.005 22.037 8.766"
"C21.579 7.355 20.823 6.06 19.829 4.962C19.709 4.83 19.541 4.758 19.368 "
"4.758C19.298 4.758 19.227 4.77 19.16 4.794L16.779 5.642C16.716 5.664 "
"16.65 5.682 16.584 5.694C16.509 5.708 16.434 5.715 16.361 5.715"
"C15.773 5.715 15.251 5.298 15.141 4.701L14.687 2.223C14.642 1.977 14.451 "
"1.782 14.205 1.73C13.485 1.577 12.749 1.5 12.002 1.5C11.255 1.5 10.517 "
"1.578 9.797 1.73C9.551 1.782 9.36 1.977 9.315 2.223L8.862 4.701"
"C8.85 4.767 8.832 4.832 8.81 4.895C8.628 5.4 8.151 5.715 7.641 5.715"
"C7.503 5.715 7.362 5.691 7.224 5.643L4.844 4.796C4.776 4.772 4.704 4.76 "
"4.635 4.76C4.463 4.76 4.295 4.832 4.175 4.964C3.179 6.062 2.424 7.356 "
"1.965 8.768C1.887 9.006 1.962 9.267 2.154 9.429L4.083 11.06C4.134 11.103 "
"4.182 11.151 4.226 11.202C4.67 11.723 4.605 12.501 4.083 12.944L2.154 "
"14.574C1.962 14.736 1.889 14.997 1.965 15.236C2.423 16.647 3.179 17.942 "
"4.175 19.04C4.295 19.172 4.463 19.244 4.635 19.244C4.706 19.244 4.776 "
"19.232 4.844 19.208L7.224 18.36C7.287 18.338 7.353 18.32 7.419 18.308"
"C7.494 18.294 7.569 18.288 7.643 18.288C8.231 18.288 8.753 18.705 8.862 "
"19.302L9.315 21.78C9.36 22.026 9.551 22.221 9.797 22.274C10.517 22.427 "
"11.255 22.503 12.002 22.503C12.749 22.503 13.487 22.425 14.205 22.274"
"C14.451 22.221 14.642 22.026 14.687 21.78L15.141 19.302C15.153 19.236 "
"15.171 19.172 15.194 19.109C15.375 18.603 15.852 18.288 16.362 18.288"
"C16.5 18.288 16.641 18.312 16.779 18.36L19.158 19.208C19.227 19.232 "
"19.298 19.244 19.367 19.244C19.539 19.244 19.707 19.172 19.827 19.04"
"C20.823 17.942 21.578 16.647 22.035 15.236C22.113 14.997 22.038 14.736 "
"21.846 14.574L21.848 14.573ZM19.092 17.589L17.282 16.944C16.985 16.839 "
"16.676 16.785 16.362 16.785C15.209 16.785 14.171 17.514 13.782 18.599"
"C13.731 18.738 13.694 18.882 13.667 19.029L13.322 20.906C12.887 20.969 "
"12.444 21 12.002 21C11.559 21 11.117 20.969 10.68 20.904L10.337 19.028"
"C10.098 17.727 8.966 16.784 7.643 16.784C7.481 16.784 7.316 16.799 7.149 "
"16.829C7.004 16.856 6.861 16.893 6.72 16.943L4.91 17.588C4.358 16.896 "
"3.917 16.139 3.591 15.321L5.052 14.087C5.612 13.614 5.952 12.951 6.012 "
"12.222C6.072 11.493 5.843 10.785 5.367 10.227C5.271 10.115 5.165 10.008 "
"5.052 9.912L3.591 8.678C3.917 7.86 4.358 7.101 4.91 6.411L6.72 7.056"
"C7.017 7.161 7.326 7.215 7.641 7.215C8.795 7.215 9.833 6.486 10.221 5.402"
"C10.272 5.261 10.31 5.117 10.337 4.971L10.68 3.095C11.117 3.032 11.559 "
"2.999 12.002 2.999C12.444 2.999 12.887 3.03 13.322 3.093L13.665 4.97"
"C13.904 6.27 15.036 7.214 16.359 7.214C16.521 7.214 16.686 7.199 16.851 "
"7.169C16.997 7.142 17.141 7.104 17.282 7.055L19.092 6.41C19.644 7.1 "
"20.085 7.859 20.411 8.676L18.951 9.911C18.392 10.383 18.05 11.046 17.991 "
"11.775C17.931 12.504 18.161 13.214 18.636 13.77C18.734 13.884 18.839 "
"13.989 18.953 14.085L20.414 15.32C20.088 16.137 19.647 16.896 19.095 "
"17.586L19.092 17.589Z"
)
# Tool icons with VS Code debug toolbar colors
TOOL_ICONS: dict[str, Icon] = {
ToolName.INIT: _make_icon(_PATHS["debug"], DEBUG_BLUE, "0 0 24 24"),
ToolName.SESSION_START: _make_icon(_PATHS["debug_start"], DEBUG_GREEN),
ToolName.EXECUTE: _make_icon(_PATHS["debug_start"], DEBUG_GREEN),
ToolName.STEP: _make_icon(_PATHS["debug_step_over"], DEBUG_BLUE),
ToolName.INSPECT: _make_icon(_PATHS["search"], DEBUG_PURPLE),
ToolName.BREAKPOINT: _make_icon(_PATHS["circle_filled"], DEBUG_RED),
ToolName.VARIABLE: _make_multi_path_icon(_SYMBOL_VARIABLE_PATHS, DEBUG_PURPLE),
ToolName.SESSION: _make_icon(_PATHS["debug_restart"], DEBUG_GREEN),
ToolName.CONFIG: _make_icon(_SETTINGS_GEAR_PATH, DEBUG_GRAY, "0 0 24 24"),
ToolName.CONTEXT: _make_icon(_PATHS["info"], DEBUG_BLUE),
ToolName.RUN_UNTIL: _make_icon(_PATHS["debug_step_into"], DEBUG_BLUE),
ToolName.ADAPTER: _make_icon(_PATHS["package"], DEBUG_GRAY),
}
def get_tool_icon(tool_name: str) -> list[Icon] | None:
"""Get icon for a tool by name.
Parameters
----------
tool_name : str
The tool name (e.g., "init", "step", "inspect")
Returns
-------
list[Icon] | None
List containing the tool's icon, or None if not found
"""
icon = TOOL_ICONS.get(tool_name)
return [icon] if icon else None