chore: disable symbol MCP tools for now

Symbol tools (symbol_list/get/dimensions/defaults/upload/delete) require
a vision-capable model to be genuinely useful — they shuttle SVG
content, which a text-only LLM cannot inspect or produce. The tool
registrations and imports are commented out (handlers stay in
symbols.py); revisit when multimodal support is worked out.
This commit is contained in:
YueGuobin 2026-08-25 13:22:59 +08:00
parent 702fc1f6d9
commit 9e4edc8a8a
No known key found for this signature in database
2 changed files with 75 additions and 74 deletions

View File

@ -94,7 +94,7 @@ All subsequent tool handler REST API calls use this JWT → zero extra bcrypt
## Available Tools
**82 tools** across 12 categories:
**76 tools** across 11 categories:
### Project (14)
@ -191,16 +191,11 @@ All subsequent tool handler REST API calls use this JWT → zero extra bcrypt
| `drawing_update` | Update drawing (position, rotation, SVG) |
| `drawing_delete` | Delete a drawing |
### Symbol (6)
| Tool | Description |
|------|-------------|
| `symbol_list` | List all symbols |
| `symbol_get` | Get symbol download URL |
| `symbol_dimensions` | Get symbol dimensions |
| `symbol_defaults` | Get default symbol mapping |
| `symbol_upload` | Upload a custom symbol (SVG content) |
| `symbol_delete` | Delete a custom symbol (built-in: 403) |
<!--
Symbol tools (symbol_list / symbol_get / symbol_dimensions /
symbol_defaults / symbol_upload / symbol_delete) are disabled for now:
they require a vision-capable model to be genuinely useful. Revisit later.
-->
### Appliance (3)

View File

@ -66,11 +66,14 @@ from .projects import (
from .server import (
get_version_handler, get_statistics_handler,
)
from .symbols import (
get_symbols_handler, get_symbol_handler,
get_symbol_dimensions_handler, get_default_symbols_handler,
upload_symbol_handler, delete_symbol_handler,
)
# Symbol tools are disabled for now: they require a vision-capable model to
# be genuinely useful (the tools shuttle SVG content, which a text-only LLM
# cannot inspect or produce). Revisit later.
# from .symbols import (
# get_symbols_handler, get_symbol_handler,
# get_symbol_dimensions_handler, get_default_symbols_handler,
# upload_symbol_handler, delete_symbol_handler,
# )
from .appliances import (
get_appliances_handler, get_appliance_handler,
install_appliance_handler,
@ -1280,64 +1283,67 @@ async def server_statistics() -> list[dict[str, Any]]:
# ── Symbol tools ──────────────────────────────────────────────────────
@mcp.tool()
async def symbol_list() -> list[dict[str, Any]]:
"""List all available symbols on the server."""
return await asyncio.to_thread(_run_handler_sync, get_symbols_handler, {})
@mcp.tool()
async def symbol_get(
symbol_id: Annotated[str, Field(description="Symbol ID (e.g. ':/symbols/router.svg')")],
) -> list[dict[str, Any]]:
"""Get a download URL for a symbol file (SVG). The URL includes a short-lived JWT (10 min). Use curl to download."""
return await asyncio.to_thread(_run_handler_sync, get_symbol_handler, {
"symbol_id": symbol_id,
})
@mcp.tool()
async def symbol_dimensions(
symbol_id: Annotated[str, Field(description="Symbol ID to get dimensions for")],
) -> list[dict[str, Any]]:
"""Get the dimensions (width, height) of a symbol."""
return await asyncio.to_thread(_run_handler_sync, get_symbol_dimensions_handler, {
"symbol_id": symbol_id,
})
@mcp.tool()
async def symbol_defaults() -> list[dict[str, Any]]:
"""Get the default symbol mapping for each node type."""
return await asyncio.to_thread(_run_handler_sync, get_default_symbols_handler, {})
@mcp.tool()
async def symbol_upload(
symbol_id: Annotated[str, Field(description="Symbol ID to upload (e.g. ':/symbols/my_symbol.svg')")],
content: Annotated[str, Field(description="SVG content of the symbol")],
) -> list[dict[str, Any]]:
"""Upload or update a custom symbol on the server. Provide the SVG content as a string."""
return await asyncio.to_thread(_run_handler_sync, upload_symbol_handler, {
"symbol_id": symbol_id, "content": content,
})
@mcp.tool()
async def symbol_delete(
symbol_id: Annotated[str, Field(description="Symbol ID to delete (e.g. ':/symbols/my_custom_symbol.svg'). Use symbol_list to get existing IDs.")],
) -> list[dict[str, Any]]:
"""Delete a custom symbol from the server.
NOTE: Only custom (user-uploaded) symbols can be deleted.
Built-in symbols (starting with ':/symbols/') will be rejected with 403.
Use symbol_list to see which symbols are available and their IDs.
"""
return await asyncio.to_thread(_run_handler_sync, delete_symbol_handler, {
"symbol_id": symbol_id,
})
#
# Disabled for now: symbol handling requires a vision-capable model (the
# tools shuttle SVG content, which a text-only LLM cannot inspect or
# produce). Revisit later.
#
# @mcp.tool()
# async def symbol_list() -> list[dict[str, Any]]:
# """List all available symbols on the server."""
# return await asyncio.to_thread(_run_handler_sync, get_symbols_handler, {})
#
#
# @mcp.tool()
# async def symbol_get(
# symbol_id: Annotated[str, Field(description="Symbol ID (e.g. ':/symbols/router.svg')")],
# ) -> list[dict[str, Any]]:
# """Get a download URL for a symbol file (SVG). The URL includes a short-lived JWT (10 min). Use curl to download."""
# return await asyncio.to_thread(_run_handler_sync, get_symbol_handler, {
# "symbol_id": symbol_id,
# })
#
#
# @mcp.tool()
# async def symbol_dimensions(
# symbol_id: Annotated[str, Field(description="Symbol ID to get dimensions for")],
# ) -> list[dict[str, Any]]:
# """Get the dimensions (width, height) of a symbol."""
# return await asyncio.to_thread(_run_handler_sync, get_symbol_dimensions_handler, {
# "symbol_id": symbol_id,
# })
#
#
# @mcp.tool()
# async def symbol_defaults() -> list[dict[str, Any]]:
# """Get the default symbol mapping for each node type."""
# return await asyncio.to_thread(_run_handler_sync, get_default_symbols_handler, {})
#
#
# @mcp.tool()
# async def symbol_upload(
# symbol_id: Annotated[str, Field(description="Symbol ID to upload (e.g. ':/symbols/my_symbol.svg')")],
# content: Annotated[str, Field(description="SVG content of the symbol")],
# ) -> list[dict[str, Any]]:
# """Upload or update a custom symbol on the server. Provide the SVG content as a string."""
# return await asyncio.to_thread(_run_handler_sync, upload_symbol_handler, {
# "symbol_id": symbol_id, "content": content,
# })
#
#
# @mcp.tool()
# async def symbol_delete(
# symbol_id: Annotated[str, Field(description="Symbol ID to delete (e.g. ':/symbols/my_custom_symbol.svg'). Use symbol_list to get existing IDs.")],
# ) -> list[dict[str, Any]]:
# """Delete a custom symbol from the server.
#
# NOTE: Only custom (user-uploaded) symbols can be deleted.
# Built-in symbols (starting with ':/symbols/') will be rejected with 403.
# Use symbol_list to see which symbols are available and their IDs.
# """
# return await asyncio.to_thread(_run_handler_sync, delete_symbol_handler, {
# "symbol_id": symbol_id,
# })
# ── Appliance tools ───────────────────────────────────────────────────