mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-08 16:02:30 +00:00
fix: include endpoint descriptions in mcp tools (#8925)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
2ed26c2254
commit
07951e81ae
@@ -384,6 +384,19 @@ def schema_to_rust_value(schema: Optional[Dict[str, Any]]) -> str:
|
||||
return "None"
|
||||
return f"Some(serde_json::json!({json.dumps(schema, indent=8)}))"
|
||||
|
||||
def build_tool_description(operation: Dict[str, Any], method: str, path: str) -> str:
|
||||
"""Build the MCP tool description from OpenAPI summary and description."""
|
||||
summary = operation.get('summary', '').strip()
|
||||
description = operation.get('description', '').strip()
|
||||
|
||||
if summary and description:
|
||||
return f"{summary}: {description}".rstrip('.!? ')
|
||||
if summary:
|
||||
return summary
|
||||
if description:
|
||||
return description.rstrip('.!? ')
|
||||
return f'{method.upper()} {path}'
|
||||
|
||||
def find_mcp_tools(spec: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""Find all endpoints marked with x-mcp-tool: true."""
|
||||
tools = []
|
||||
@@ -395,7 +408,7 @@ def find_mcp_tools(spec: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
# Extract tool information
|
||||
tool = {
|
||||
'name': operation.get('operationId', f"{method}_{path.replace('/', '_').replace('{', '').replace('}', '')}"),
|
||||
'description': operation.get('summary', operation.get('description', f'{method.upper()} {path}')),
|
||||
'description': build_tool_description(operation, method, path),
|
||||
'instructions': operation.get('x-mcp-instructions', ''),
|
||||
'path': path,
|
||||
'method': method.upper(),
|
||||
@@ -607,4 +620,4 @@ def main():
|
||||
print("Done!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
||||
@@ -7406,6 +7406,9 @@ paths:
|
||||
/w/{workspace}/scripts/create:
|
||||
post:
|
||||
summary: create script
|
||||
description: |
|
||||
Creates a new script when the path does not already exist.
|
||||
Creates a new version of an existing script when called with the same path and the current `parent_hash`.
|
||||
operationId: createScript
|
||||
x-mcp-tool: true
|
||||
x-mcp-instructions: "To create a script, specify the path (e.g., 'f/my_folder/my_script'), the content (source code), and the language. For TypeScript, use 'bun' unless deno-specific APIs are needed."
|
||||
|
||||
@@ -78,6 +78,12 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
"type": "string",
|
||||
"description": "The expiration date of the variable",
|
||||
"format": "date-time"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -157,6 +163,12 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
"type": "string",
|
||||
"description": "The new description of the variable"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"path__body": {
|
||||
"type": "string",
|
||||
"description": "The path to the variable (body parameter)"
|
||||
@@ -244,6 +256,10 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
"per_page": {
|
||||
"type": "integer",
|
||||
"description": "number of items to return for a given page (default 30, max 100)"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@@ -287,6 +303,12 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
"resource_type": {
|
||||
"type": "string",
|
||||
"description": "The resource_type associated with the resource"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -355,6 +377,12 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
"type": "string",
|
||||
"description": "The new resource_type to be associated with the resource"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"path__body": {
|
||||
"type": "string",
|
||||
"description": "The path to the resource (body parameter)"
|
||||
@@ -437,6 +465,10 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
"broad_filter": {
|
||||
"type": "string",
|
||||
"description": "broad search across multiple fields (case-insensitive substring match)"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@@ -544,6 +576,10 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
"dedicated_worker": {
|
||||
"type": "boolean",
|
||||
"description": "(default regardless)\nIf true, show only scripts with dedicated_worker enabled.\nIf false, show only scripts with dedicated_worker disabled.\n"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@@ -555,7 +591,8 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
},
|
||||
EndpointTool {
|
||||
name: Cow::Borrowed("createScript"),
|
||||
description: Cow::Borrowed("create script"),
|
||||
description: Cow::Borrowed("create script: Creates a new script when the path does not already exist.
|
||||
Creates a new version of an existing script when called with the same path and the current `parent_hash`"),
|
||||
instructions: Cow::Borrowed("To create a script, specify the path (e.g., 'f/my_folder/my_script'), the content (source code), and the language. For TypeScript, use 'bun' unless deno-specific APIs are needed."),
|
||||
path: Cow::Borrowed("/w/{workspace}/scripts/create"),
|
||||
method: Cow::Borrowed("POST"),
|
||||
@@ -578,7 +615,7 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
},
|
||||
"language": {
|
||||
"type": "string",
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, duckdb, bunnative"
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, rlang, duckdb, bunnative"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
@@ -772,6 +809,10 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
"dedicated_worker": {
|
||||
"type": "boolean",
|
||||
"description": "(default regardless)\nIf true, show only flows with dedicated_worker enabled.\nIf false, show only flows with dedicated_worker disabled.\n"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@@ -1095,7 +1136,7 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
},
|
||||
"language": {
|
||||
"type": "string",
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, duckdb, bunnative"
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, rlang, duckdb, bunnative"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string"
|
||||
@@ -1127,7 +1168,7 @@ pub fn all_tools() -> Vec<EndpointTool> {
|
||||
},
|
||||
"language": {
|
||||
"type": "string",
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, duckdb, bunnative"
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, rlang, duckdb, bunnative"
|
||||
},
|
||||
"lock": {
|
||||
"type": "string",
|
||||
@@ -1691,6 +1732,12 @@ You should get the schema of the script or flow before creating the schedule to
|
||||
"preserve_permissioned_as": {
|
||||
"type": "boolean",
|
||||
"description": "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -1894,6 +1941,12 @@ You should get the schema of the script or flow before updating the schedule to
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "If true and user is admin/wm_deployers, preserve the provided permissioned_as instead of using the deploying user's identity"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -2001,6 +2054,10 @@ You should get the schema of the script or flow before updating the schedule to
|
||||
"broad_filter": {
|
||||
"type": "string",
|
||||
"description": "broad search across multiple fields (case-insensitive substring match)"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
||||
@@ -88,6 +88,12 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"type": "string",
|
||||
"description": "The expiration date of the variable",
|
||||
"format": "date-time"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -167,6 +173,12 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"type": "string",
|
||||
"description": "The new description of the variable"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"path__body": {
|
||||
"type": "string",
|
||||
"description": "The path to the variable (body parameter)"
|
||||
@@ -254,6 +266,10 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"per_page": {
|
||||
"type": "integer",
|
||||
"description": "number of items to return for a given page (default 30, max 100)"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@@ -297,6 +313,12 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"resource_type": {
|
||||
"type": "string",
|
||||
"description": "The resource_type associated with the resource"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -365,6 +387,12 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"type": "string",
|
||||
"description": "The new resource_type to be associated with the resource"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"path__body": {
|
||||
"type": "string",
|
||||
"description": "The path to the resource (body parameter)"
|
||||
@@ -447,6 +475,10 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"broad_filter": {
|
||||
"type": "string",
|
||||
"description": "broad search across multiple fields (case-insensitive substring match)"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@@ -554,6 +586,10 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"dedicated_worker": {
|
||||
"type": "boolean",
|
||||
"description": "(default regardless)\nIf true, show only scripts with dedicated_worker enabled.\nIf false, show only scripts with dedicated_worker disabled.\n"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@@ -565,7 +601,7 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
},
|
||||
{
|
||||
name: "createScript",
|
||||
description: "create script",
|
||||
description: "create script: Creates a new script when the path does not already exist.\nCreates a new version of an existing script when called with the same path and the current `parent_hash`",
|
||||
instructions: "To create a script, specify the path (e.g., 'f/my_folder/my_script'), the content (source code), and the language. For TypeScript, use 'bun' unless deno-specific APIs are needed.",
|
||||
path: "/w/{workspace}/scripts/create",
|
||||
method: "POST",
|
||||
@@ -588,7 +624,7 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
},
|
||||
"language": {
|
||||
"type": "string",
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, duckdb, bunnative"
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, rlang, duckdb, bunnative"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
@@ -782,6 +818,10 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"dedicated_worker": {
|
||||
"type": "boolean",
|
||||
"description": "(default regardless)\nIf true, show only flows with dedicated_worker enabled.\nIf false, show only flows with dedicated_worker disabled.\n"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@@ -1105,7 +1145,7 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
},
|
||||
"language": {
|
||||
"type": "string",
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, duckdb, bunnative"
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, rlang, duckdb, bunnative"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string"
|
||||
@@ -1137,7 +1177,7 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
},
|
||||
"language": {
|
||||
"type": "string",
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, duckdb, bunnative"
|
||||
"description": "Possible values: python3, deno, go, bash, powershell, postgresql, mysql, bigquery, snowflake, mssql, oracledb, graphql, nativets, bun, php, rust, ansible, csharp, nu, java, ruby, rlang, duckdb, bunnative"
|
||||
},
|
||||
"lock": {
|
||||
"type": "string",
|
||||
@@ -1698,6 +1738,12 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"preserve_permissioned_as": {
|
||||
"type": "boolean",
|
||||
"description": "When true and the caller is a member of the 'wm_deployers' group, preserves the original permissioned_as value instead of overwriting it."
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -1898,6 +1944,12 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"type": "boolean",
|
||||
"nullable": true,
|
||||
"description": "If true and user is admin/wm_deployers, preserve the provided permissioned_as instead of using the deploying user's identity"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -2005,6 +2057,10 @@ export const mcpEndpointTools: EndpointTool[] = [
|
||||
"broad_filter": {
|
||||
"type": "string",
|
||||
"description": "broad search across multiple fields (case-insensitive substring match)"
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Filter by label"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
||||
Reference in New Issue
Block a user