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 ## Available Tools
**82 tools** across 12 categories: **76 tools** across 11 categories:
### Project (14) ### 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_update` | Update drawing (position, rotation, SVG) |
| `drawing_delete` | Delete a drawing | | `drawing_delete` | Delete a drawing |
### Symbol (6) <!--
Symbol tools (symbol_list / symbol_get / symbol_dimensions /
| Tool | Description | symbol_defaults / symbol_upload / symbol_delete) are disabled for now:
|------|-------------| they require a vision-capable model to be genuinely useful. Revisit later.
| `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) |
### Appliance (3) ### Appliance (3)

View File

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