diff --git a/agents/community/mcp-orchestrate-autoai-template/agent.yaml b/agents/community/mcp-orchestrate-autoai-template/agent.yaml new file mode 100644 index 0000000..2383bbe --- /dev/null +++ b/agents/community/mcp-orchestrate-autoai-template/agent.yaml @@ -0,0 +1,26 @@ +spec_version: v1 +kind: native +name: iris_prediction_agent +description: | + Predicts iris petal width from sepal length, sepal width, petal length, and species + using a watsonx.ai deployed machine learning model. +llm: groq/openai/gpt-oss-120b +style: react +hide_reasoning: false +instructions: | + You are an iris petal width prediction assistant. + + STRICT RULES — follow these without exception: + 1. NEVER answer a petal width question from your own knowledge or reasoning. + 2. NEVER ask the user to confirm inputs — if all 4 values are present, call the tool immediately. + 3. ALWAYS call get_petal_width_from_iris_data when the user provides: + - sepal_length (float, cm) + - sepal_width (float, cm) + - petal_length (float, cm) + - species (one of: setosa, versicolor, virginica) + 4. If and only if one or more of the 4 values above is missing, ask ONLY for the missing ones. + 5. After the tool returns a result, report it as: "The predicted petal width is X cm." + 6. Do NOT call any other tool or perform any calculation yourself. +tools: + - iris-toolkit:get_petal_width_from_iris_data +collaborators: [] diff --git a/agents/community/mcp-orchestrate-autoai-template/mcp_server/requirements.txt b/agents/community/mcp-orchestrate-autoai-template/mcp_server/requirements.txt new file mode 100644 index 0000000..59bd29a --- /dev/null +++ b/agents/community/mcp-orchestrate-autoai-template/mcp_server/requirements.txt @@ -0,0 +1,4 @@ +mcp +python-dotenv +ibm-watsonx-ai +pydantic \ No newline at end of file diff --git a/agents/community/mcp-orchestrate-autoai-template/mcp_server/server.py b/agents/community/mcp-orchestrate-autoai-template/mcp_server/server.py new file mode 100644 index 0000000..66e0e24 --- /dev/null +++ b/agents/community/mcp-orchestrate-autoai-template/mcp_server/server.py @@ -0,0 +1,31 @@ +from mcp.server.fastmcp import FastMCP +from utils import ( + IrisInformation, + prepare_api_client, + get_petal_width_deployment_id, + build_scoring_payload, + extract_petal_width, +) + +mcp = FastMCP("iris-toolkit") +api_client = prepare_api_client() + + +@mcp.tool() +def get_petal_width_from_iris_data(iris_information: IrisInformation) -> float: + """ + Predict the petal width (in cm) of an iris flower using a watsonx.ai deployed model. + + Provide sepal_length, sepal_width, petal_length (all in cm as floats), + and species (one of: setosa, versicolor, virginica). + + Returns the predicted petal width as a float. + """ + deployment_id = get_petal_width_deployment_id() + payload = build_scoring_payload(iris_information) + response = api_client.deployments.score(deployment_id, meta_props=payload) + return extract_petal_width(response) + + +if __name__ == "__main__": + mcp.run(transport="stdio") diff --git a/agents/community/mcp-orchestrate-autoai-template/mcp_server/utils.py b/agents/community/mcp-orchestrate-autoai-template/mcp_server/utils.py new file mode 100644 index 0000000..4abccb2 --- /dev/null +++ b/agents/community/mcp-orchestrate-autoai-template/mcp_server/utils.py @@ -0,0 +1,68 @@ +import os +from dotenv import load_dotenv +from typing import Literal +from pydantic import BaseModel, Field + + +class IrisInformation(BaseModel): + sepal_length: float = Field(..., description="Sepal length in cm") + sepal_width: float = Field(..., description="Sepal width in cm") + petal_length: float = Field(..., description="Petal length in cm") + species: Literal["setosa", "versicolor", "virginica"] = Field( + ..., description="Iris species: setosa, versicolor, or virginica" + ) + + +def prepare_api_client(): + from ibm_watsonx_ai import APIClient, Credentials + + load_dotenv() + + api_client = APIClient( + credentials=Credentials( + url=os.getenv("WATSONX_URL"), + api_key=os.getenv("WATSONX_API_KEY"), + ), + space_id=os.getenv("WATSONX_SPACE_ID"), + ) + return api_client + + +def get_petal_width_deployment_id() -> str: + load_dotenv() + deployment_id = os.getenv("WATSONX_PETAL_WIDTH_DEPLOYMENT_ID") + if not deployment_id: + raise ValueError("WATSONX_PETAL_WIDTH_DEPLOYMENT_ID is not set") + return deployment_id + + +def build_scoring_payload(iris: IrisInformation) -> dict: + """Build the scoring payload in the format expected by watsonx.ai deployment.""" + return { + "input_data": [ + { + "fields": ["sepal_length", "sepal_width", "petal_length", "species"], + "values": [ + [ + iris.sepal_length, + iris.sepal_width, + iris.petal_length, + iris.species, + ] + ], + } + ] + } + + +def extract_petal_width(response: dict) -> float: + """Extract the predicted petal width float from the watsonx.ai scoring response.""" + try: + predictions = response["predictions"][0] + values = predictions["values"][0] + # The deployment returns a list of predicted values; petal width is the first + return float(values[0]) + except (KeyError, IndexError, TypeError, ValueError) as e: + raise RuntimeError( + f"Unexpected response structure from deployment: {response}" + ) from e diff --git a/agents/community/mcp-orchestrate-autoai-template/toolkit.yaml b/agents/community/mcp-orchestrate-autoai-template/toolkit.yaml new file mode 100644 index 0000000..27f0fb9 --- /dev/null +++ b/agents/community/mcp-orchestrate-autoai-template/toolkit.yaml @@ -0,0 +1,13 @@ +spec_version: v1 +kind: mcp +name: iris-toolkit +description: "Iris petal width prediction using watsonx.ai deployment" +command: python server.py +env: + - WATSONX_URL + - WATSONX_API_KEY + - WATSONX_SPACE_ID + - WATSONX_PETAL_WIDTH_DEPLOYMENT_ID +tools: + - "*" +package_root: ./mcp_server