feat(api-tools): fix model and server uuid references, tighten mcp server exposure

- Map model_uuid to model.embedding.list / model.rerank.list / model.llm.list based on operation_id prefix
- Map server_uuid to mcp.server.list and clarify server_uuid vs server_name in OperationDoc descriptions
- Restrict mcp.server.create and mcp.server.update to exposure='assistant' and risk='dangerous'
- Add input parameter descriptions to PipelineRunInput and RoutePreviewInput

Ref: LANG-229
Co-authored-by: multica-agent <[email protected]>
This commit is contained in:
RockChinQ
2026-10-31 11:02:30 +00:00
co-authored by multica-agent
parent 6864b91770
commit baa1802c84
2 changed files with 29 additions and 16 deletions
@@ -486,14 +486,14 @@ OPERATION_DOCS: dict[str, OperationDoc] = {
label={'zh_Hans': '创建MCP服务', 'en_US': 'Create MCP Server'},
summary='Configure and register a new MCP server connection.',
description='Register a new MCP server in the workspace. Provide server_data with transport type, command/URL, and environment. Side effect: Instantiates MCP server client.',
risk='write',
exposure='all',
risk='dangerous',
exposure='assistant',
),
'mcp.server.delete': OperationDoc(
domain='mcp',
label={'zh_Hans': '删除MCP服务', 'en_US': 'Delete MCP Server'},
summary='Disconnect and delete an MCP server from the workspace.',
description='Remove an MCP server registration and terminate active subprocess or connection. Prerequisites: Call mcp.server.list to obtain server_name. Side effect: Deletes server registration.',
description='Remove an MCP server registration and terminate active subprocess or connection. Prerequisites: Call mcp.server.list to obtain server_uuid (note: list returns server objects with uuid; get, logs, runtime, and test use server_name). Side effect: Deletes server registration.',
risk='dangerous',
exposure='all',
),
@@ -541,9 +541,9 @@ OPERATION_DOCS: dict[str, OperationDoc] = {
domain='mcp',
label={'zh_Hans': '更新MCP服务', 'en_US': 'Update MCP Server'},
summary='Update configuration and parameters of an MCP server.',
description='Modify connection parameters, environment variables, or transport settings of an MCP server. Prerequisites: Call mcp.server.list to obtain server_name. Side effect: Restarts MCP client.',
risk='write',
exposure='all',
description='Modify connection parameters, environment variables, or transport settings of an MCP server. Prerequisites: Call mcp.server.list to obtain server_uuid (note: list returns server objects with uuid; get, logs, runtime, and test use server_name). Side effect: Restarts MCP client.',
risk='dangerous',
exposure='assistant',
),
'model.embedding.create': OperationDoc(
domain='model',
@@ -1405,7 +1405,7 @@ OPERATION_DOCS: dict[str, OperationDoc] = {
domain='tool',
label={'zh_Hans': '工具详情', 'en_US': 'Get Tool'},
summary='Get parameter schema and description for a specific tool.',
description='Retrieve input schema, argument descriptions, and execution requirements for a tool. Prerequisites: Call tool.list to obtain tool_name and pipeline_uuid.',
description='Retrieve input schema, argument descriptions, and execution requirements for a tool. Prerequisites: Call tool.list to obtain tool_name (and optional pipeline_uuid from pipeline.list).',
risk='read',
exposure='all',
),
@@ -1413,7 +1413,7 @@ OPERATION_DOCS: dict[str, OperationDoc] = {
domain='tool',
label={'zh_Hans': '工具列表', 'en_US': 'List Tools'},
summary='List all registered function tools available for execution.',
description='Retrieve all available executable function tools, including plugin actions, MCP tools, and skill functions. Optionally filter by pipeline_uuid.',
description='Retrieve all available executable function tools, including plugin actions, MCP tools, and skill functions. Optionally filter by pipeline_uuid (get it from pipeline.list).',
risk='read',
exposure='all',
),
@@ -765,6 +765,7 @@ _LIST_OPS_BY_ENTITY = {
'agent': 'agent.list',
'model': 'model.llm.list',
'provider': 'provider.list',
'server': 'mcp.server.list',
'kb': 'knowledge.base.list',
'knowledge_base': 'knowledge.base.list',
'adapter': 'adapter.list',
@@ -791,6 +792,16 @@ def _field_description(name: str, operation_id: str) -> str | None:
return 'ISO 8601 timestamp or Unix epoch representing the time boundary'
if name in {'query', 'keyword', 'user_query'}:
return 'Search query string used to filter results'
if name == 'model_uuid':
if operation_id.startswith('model.embedding.'):
list_op = 'model.embedding.list'
elif operation_id.startswith('model.rerank.'):
list_op = 'model.rerank.list'
else:
list_op = 'model.llm.list'
return f'UUID of the model; get it from {list_op}'
if name == 'server_uuid':
return 'UUID of the MCP server; get it from mcp.server.list'
if name.endswith('_uuid'):
entity = name[:-5]
list_op = _LIST_OPS_BY_ENTITY.get(entity, f'{entity}.list')
@@ -876,9 +887,11 @@ def operations() -> tuple[Operation, ...]:
class PipelineRunInput(Input):
pipeline_uuid: str = Field(min_length=1)
text: str = Field(min_length=1, max_length=100_000)
timeout: float = Field(default=60.0, gt=0, le=300)
pipeline_uuid: str = Field(min_length=1, description='UUID of the pipeline; get it from pipeline.list')
text: str = Field(
min_length=1, max_length=100_000, description='Input message or query text to trigger the pipeline execution'
)
timeout: float = Field(default=60.0, gt=0, le=300, description='Maximum execution time in seconds')
async def _pipeline_run(ap, context, payload):
@@ -933,11 +946,11 @@ async def _assistant(ap, context, payload, method):
class RoutePreviewInput(Input):
bot_uuid: str = Field(min_length=1)
event_type: str = Field(min_length=1)
event_data: dict | None = None
event_context: dict | None = None
event_bindings: list[dict] | None = None
bot_uuid: str = Field(min_length=1, description='UUID of the bot; get it from bot.list')
event_type: str = Field(min_length=1, description='Event type name to simulate routing for')
event_data: dict | None = Field(default=None, description='Event payload data to simulate')
event_context: dict | None = Field(default=None, description='Event context metadata')
event_bindings: list[dict] | None = Field(default=None, description='Optional custom route bindings')
async def _route_preview(ap, context, payload):