Coverage for mcpgateway / routers / toolops_router.py: 96%
50 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-02-11 07:10 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-02-11 07:10 +0000
1# -*- coding: utf-8 -*-
2"""Location: ./mcpgateway/routers/toolops_router.py
3Copyright 2025
4SPDX-License-Identifier: Apache-2.0
5Authors: Jay Bandlamudi
7Toolops Router Module
9This module provides FastAPI endpoints for managing Toolops functionalities
10.It supports tool test case generation , tool meta-data enrichment and tool
11test case execution with an agent.
13The module handles API endpoints created for several toolops features.
15"""
17# Standard
18from typing import Any, Dict, List
20# Third-Party
21from fastapi import APIRouter, Depends, HTTPException, Query, status
22import orjson
23from pydantic import BaseModel, Field
24from sqlalchemy.orm import Session
26# First-Party
27from mcpgateway.main import get_db
28from mcpgateway.middleware.rbac import get_current_user_with_permissions, require_permission
29from mcpgateway.services.logging_service import LoggingService
30from mcpgateway.services.tool_service import ToolService
31from mcpgateway.toolops.toolops_altk_service import enrich_tool, execute_tool_nl_test_cases, validation_generate_test_cases
33# Initialize router
34toolops_router = APIRouter(prefix="/toolops", tags=["Toolops"])
36# Initialize services
37tool_service = ToolService()
39# Logging
40logging_service = LoggingService()
41logger = logging_service.get_logger(__name__)
43# ---------- Utility ----------
46class ToolNLTestInput(BaseModel):
47 """
48 Toolops test input format to run NL test cases of a tool using agent
50 Args:
51 tool_id : Unique Tool ID
52 tool_nl_test_cases: List of natural language test cases for testing MCP tool with the agent
54 Returns:
55 This class defines tool NL test input format and returns nothing.
56 """
58 tool_id: str | None = Field(default=None, title="Tool ID", max_length=300)
59 tool_nl_test_cases: list | None = Field(default=None, title="List of natural language test cases for testing MCP tool with the agent")
62# ---------- ROUTES ----------
65# First-Party
66# Toolops APIs - Generating test cases , Tool enrichment #
67@toolops_router.post("/validation/generate_testcases")
68@require_permission("admin.system_config")
69async def generate_testcases_for_tool(
70 tool_id: str = Query(None, description="Tool ID"),
71 number_of_test_cases: int = Query(2, description="Maximum number of tool test cases"),
72 number_of_nl_variations: int = Query(1, description="Number of NL utterance variations per test case"),
73 mode: str = Query("generate", description="Three modes: 'generate' for test case generation, 'query' for obtaining test cases from DB , 'status' to check test generation status"),
74 db: Session = Depends(get_db),
75 _user=Depends(get_current_user_with_permissions),
76) -> List[Dict]:
77 """
78 Generate test cases for a tool
80 This endpoint handles the automated test case generation for a tool by accepting
81 a tool id . The `require_auth` dependency ensures that
82 the user is authenticated before proceeding.
84 Args:
85 tool_id: Tool ID in context forge.
86 number_of_test_cases: Number of test cases to generate for the given tools (optional)
87 number_of_nl_variations: Number of Natural language variations(parapharses) per test case (optional)
88 mode: Three supported modes - 'generate' for test case generation, 'query' for obtaining test cases from DB , 'status' to check test generation status
89 db: DB session to connect with database
91 Returns:
92 List: A list of test cases generated for the tool , each test case is dictionary object
94 Raises:
95 HTTPException: If the request body contains invalid JSON, a 400 Bad Request error is raised.
96 """
97 try:
98 # logger.debug(f"Authenticated user {user} is initializing the protocol.")
99 test_cases = await validation_generate_test_cases(tool_id, tool_service, db, number_of_test_cases, number_of_nl_variations, mode)
100 return test_cases
102 except orjson.JSONDecodeError:
103 raise HTTPException(
104 status_code=status.HTTP_400_BAD_REQUEST,
105 detail="Invalid JSON in request body",
106 )
109@toolops_router.post("/validation/execute_tool_nl_testcases")
110@require_permission("admin.system_config")
111async def execute_tool_nl_testcases(tool_nl_test_input: ToolNLTestInput, db: Session = Depends(get_db), _user=Depends(get_current_user_with_permissions)) -> List:
112 """
113 Execute test cases for a tool
115 This endpoint handles the automated test case generation for a tool by accepting
116 a tool id . The `require_auth` dependency ensures that
117 the user is authenticated before proceeding.
119 Args:
120 tool_nl_test_input: NL test case format input to run test cases with agent , it contains\
121 - tool_id: Tool ID in context forge\
122 - tool_nl_test_cases: List of natural language test cases (utteances) for testing MCP tool with the agent
123 db: DB session to connect with database
125 Returns:
126 List: A list of tool outputs after agent execution for the provided tool nl test cases
128 Raises:
129 HTTPException: If the request body contains invalid JSON, a 400 Bad Request error is raised.
130 """
131 try:
132 # logger.debug(f"Authenticated user {user} is initializing the protocol.")
133 tool_id = tool_nl_test_input.tool_id
134 tool_nl_test_cases = tool_nl_test_input.tool_nl_test_cases
135 tool_nl_test_cases_output = await execute_tool_nl_test_cases(tool_id, tool_nl_test_cases, tool_service, db)
136 return tool_nl_test_cases_output
138 except orjson.JSONDecodeError:
139 raise HTTPException(
140 status_code=status.HTTP_400_BAD_REQUEST,
141 detail="Invalid JSON in request body",
142 )
145@toolops_router.post("/enrichment/enrich_tool")
146@require_permission("admin.system_config")
147async def enrich_a_tool(tool_id: str = Query(None, description="Tool ID"), db: Session = Depends(get_db), _user=Depends(get_current_user_with_permissions)) -> dict[str, Any]:
148 """
149 Enriches an input tool
151 Args:
152 tool_id: Unique Tool ID MCP-CF.
153 db: The database session used to interact with the data store.
155 Returns:
156 result: A dict having the keys "tool_id", "tool_name", "original_desc" and "enriched_desc" with their corresponding values
158 Raises:
159 HTTPException: If the request body contains invalid JSON, a 400 Bad Request error is raised.
160 """
161 try:
162 logger.info("Running tool enrichment for Tool - " + tool_id)
163 enriched_tool_description, tool_schema = await enrich_tool(tool_id, tool_service, db)
164 result: dict[str, Any] = {}
165 result["tool_id"] = tool_id
166 result["tool_name"] = tool_schema.name
167 result["original_desc"] = tool_schema.description
168 result["enriched_desc"] = enriched_tool_description
169 # logger.info ("result: "+ json.dumps(result, indent=4, sort_keys=False))
170 return result
172 except Exception as e:
173 logger.info("Error in tool enrichment for Tool - " + str(e))
174 raise HTTPException(
175 status_code=status.HTTP_400_BAD_REQUEST,
176 detail="Invalid JSON in request body" + str(e),
177 ) from e