Skip to content

Commit 4d85212

Browse files
authored
Merge pull request #47 from Tanvi26Kori/new-capability
Finetuning Capability
2 parents f5c42a9 + 57cdaca commit 4d85212

File tree

7 files changed

+1383
-2
lines changed

7 files changed

+1383
-2
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ A Model Context Protocol server for Azure AI Foundry, providing a unified set of
6565
| | `connect_agent` | Send a query to a specified agent. |
6666
| | `query_default_agent` | Query the default agent defined in environment variables. |
6767

68+
### Capabilities: Finetuning
69+
70+
| Category | Tool | Description |
71+
|---|---|---|
72+
| **Finetuning** | `fetch_finetuning_status` | Retrieves detailed status and metadata for a specific fine-tuning job, including job state, model, creation and finish times, hyperparameters, and any errors. |
73+
| | `list_finetuning_jobs` | Lists all fine-tuning jobs in the resource, returning job IDs and their current statuses for easy tracking and management. |
74+
| | `get_finetuning_job_events` | Retrieves a chronological list of all events for a specific fine-tuning job, including timestamps and detailed messages for each training step, evaluation, and completion. |
75+
| | `get_finetuning_metrics` | Retrieves training and evaluation metrics for a specific fine-tuning job, including loss curves, accuracy, and other relevant performance indicators for monitoring and analysis. |
76+
| | `list_finetuning_files` | Lists all files available for fine-tuning in Azure OpenAI, including file IDs, names, purposes, and statuses. |
77+
| | `execute_dynamic_swagger_action` | Executes any tool dynamically generated from the Swagger specification, allowing flexible API calls for advanced scenarios. |
78+
| | `list_dynamic_swagger_tools` | Lists all dynamically registered tools from the Swagger specification, enabling discovery and automation of available API endpoints. |
79+
80+
6881
## Prompt Examples
6982

7083
### Models

src/mcp_foundry/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ def main() -> None:
4444

4545

4646
if __name__ == "__main__":
47-
main()
47+
main()
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
2+
# Extending and Customizing Finetuning Tools in MCP Foundry
3+
4+
This comprehensive guide will help you extend the capabilities of the `mcp_foundry_finetuning` module by adding new tools. It covers both static MCP tools (Python functions) and dynamic tools generated from a Swagger/OpenAPI specification. You’ll also find troubleshooting tips, advanced usage, and best practices for robust tool development.
5+
6+
---
7+
8+
## 1. Adding Static MCP Tools (Python Functions)
9+
10+
Static tools are Python functions decorated with `@mcp.tool()` in `tools.py`. These are registered with the MCP server and can be called directly from the MCP client or other services. Static tools are ideal for custom logic, orchestration.
11+
12+
### Step-by-Step: Creating a Static Tool
13+
14+
1. **Navigate to the tools file:**
15+
- Open `src/mcp_foundry/mcp_foundry_finetuning/tools.py` in your editor.
16+
17+
2. **Define your function:**
18+
- Decorate your function with `@mcp.tool()`.
19+
- The first argument can be a `Context` object (from `mcp.server.fastmcp`).
20+
- Add any additional parameters your tool needs.
21+
22+
3. **Implement your logic:**
23+
- Use environment variables for configuration (see existing tools for examples).
24+
- You can make HTTP requests, call other Python functions, or interact with files.
25+
- Handle errors gracefully and log useful information for debugging.
26+
27+
4. **Return results:**
28+
- Return a JSON-serializable object or string. This ensures compatibility with the MCP server and clients.
29+
- If your tool returns complex data, use `json.dumps()` to serialize it.
30+
31+
#### Example: Adding a Simple Tool
32+
```python
33+
from mcp_foundry.mcp_server import mcp
34+
from mcp.server.fastmcp import Context
35+
36+
@mcp.tool()
37+
def my_new_tool(ctx: Context, param1: str) -> str:
38+
"""
39+
Example tool that echoes the input parameter.
40+
"""
41+
# Your logic here
42+
return f"Received: {param1}"
43+
```
44+
45+
5. **Test your tool:**
46+
- Run the MCP server and use the client or test suite to call your new tool.
47+
- Check logs for errors or unexpected behavior.
48+
49+
## 2. Adding Dynamic Tools from Swagger/OpenAPI
50+
51+
Dynamic tools are generated automatically from the Swagger specification (`swagger.yaml`). The generator in `swagger.py` reads the spec and registers a tool for each operation. This is ideal for exposing REST API endpoints as MCP tools with minimal Python code.
52+
53+
### Step-by-Step: Creating a Dynamic Tool
54+
55+
1. **Edit the Swagger specification:**
56+
- Open `swagger.yaml` in the project root.
57+
- Add a new path and operation following the OpenAPI 3.0 format.
58+
- Each operation **must** have a unique `operationId` (this becomes the tool name).
59+
- Document parameters, request bodies, and responses clearly.
60+
61+
2. **(Optional) Add schemas:**
62+
- Define request/response schemas in the `components` section for better validation and documentation.
63+
64+
3. **Set the Swagger path:**
65+
- Ensure the `SWAGGER_PATH` environment variable is set to the path of your `swagger.yaml` file (found in `.env`).
66+
- Example: `SWAGGER_PATH=./swagger.yaml`
67+
68+
4. **Restart the MCP server:**
69+
- The dynamic tool will be auto-registered if the Swagger spec is valid.
70+
- Check logs for any errors during registration.
71+
72+
#### Example: Adding a Custom Endpoint
73+
```yaml
74+
paths:
75+
/openai/fine_tuning/jobs/my_custom:
76+
get:
77+
operationId: myCustomTool
78+
summary: My custom tool
79+
description: Does something custom
80+
responses:
81+
'200':
82+
description: Success
83+
```
84+
85+
#### Example: Adding Parameters and Schemas
86+
```yaml
87+
paths:
88+
/openai/fine_tuning/jobs/{job_id}/custom:
89+
get:
90+
operationId: getCustomJobInfo
91+
summary: Get custom job info
92+
parameters:
93+
- name: job_id
94+
in: path
95+
required: true
96+
schema:
97+
type: string
98+
responses:
99+
'200':
100+
description: Success
101+
content:
102+
application/json:
103+
schema:
104+
type: object
105+
properties:
106+
info:
107+
type: string
108+
```
109+
110+
### How Dynamic Tools Work
111+
- The generator in `swagger.py` parses the YAML and registers a tool for each operation.
112+
- You can list all dynamic tools using the `list_dynamic_swagger_tools` MCP tool.
113+
- Call a dynamic tool by its `operationId` using the `execute_dynamic_swagger_action` MCP tool, passing required parameters as needed.
114+
115+
#### Example: Calling a Dynamic Tool
116+
```python
117+
# Using the MCP client or another tool:
118+
result = execute_dynamic_swagger_action(ctx, tool_name="myCustomTool")
119+
```
120+
NOTE: Dynamic tools can also be invoked by natural language prompts.
121+
122+
---
123+
124+
## 3. Troubleshooting and Advanced Usage
125+
126+
- **Tool not appearing?**
127+
- Check that your function is decorated with `@mcp.tool()` (for static tools).
128+
- For dynamic tools, ensure your `swagger.yaml` is valid and `SWAGGER_PATH` is set correctly.
129+
- Restart the MCP server after changes.
130+
131+
- **Errors in logs?**
132+
- Look for missing environment variables, invalid YAML, or registration errors.
133+
- Use logging in your Python code to help debug issues.
134+
135+
- **Parameter issues?**
136+
- For dynamic tools, ensure all required parameters are defined in the Swagger spec and are passed when calling the tool.
137+
138+
- **Testing tools:**
139+
- Use the MCP client, test scripts, or unit tests to verify your tool’s behavior.
140+
- For dynamic tools, you can use the `list_dynamic_swagger_tools` tool to see all available endpoints and their parameters.
141+
142+
---
143+
144+
## 4. Best Practices
145+
146+
- **Use clear, unique `operationId`s** in Swagger for dynamic tools. This avoids naming collisions and makes tools easy to find.
147+
- **Document parameters and responses** thoroughly in both Python and YAML.
148+
- **Handle errors ** in both static and dynamic tools. Return helpful error messages and log details for debugging.
149+
- **Keep your tools modular**. If logic is complex, break it into helper functions or modules.
150+
- **Check logs** regularly for warnings or errors, especially after adding or modifying tools.
151+
152+
---
153+
154+
## 5. Useful References and Further Reading
155+
156+
- See `tools.py` for static tool examples and patterns.
157+
- See `swagger.yaml` for dynamic tool definitions and OpenAPI structure.
158+
- See `swagger.py` for the dynamic tool generator logic and advanced customization.
159+
- [OpenAPI Specification](https://swagger.io/specification/)
160+
- [Python logging documentation](https://docs.python.org/3/library/logging.html)
161+
162+
---

0 commit comments

Comments
 (0)