Skip to content

Commit 2245fd4

Browse files
author
Ratnakar Asara
committed
updates as per suggested comments
Signed-off-by: Ratnakar Asara <rasara@us.ibm.com>
1 parent c906547 commit 2245fd4

File tree

7 files changed

+196
-206
lines changed

7 files changed

+196
-206
lines changed

executable/prescribed/README.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Prescribed Tools
2+
3+
A **prescribed tool** is a tool that maps to a specific [GraphQL operation](https://spec.graphql.org/September2025/#sec-Language.Operations) in a [persisted document](https://spec.graphql.org/September2025/#sec-Persisted-Documents). The `@tool(prescribed:)` argument links the tool definition to an operation name in a persisted document. This approach provides a structured way to expose specific GraphQL operations as tools that can be called by AI models.
4+
5+
This sample demonstrates how to use the `@tool` directive to create prescribed tools for MCP (Model Context Protocol).
6+
7+
## Overview
8+
9+
The sample implements a mock weather service API with a single operation: weather forecast for a city.
10+
11+
The key feature demonstrated is how to create a prescribed tool that maps to a persisted GraphQL operation, allowing AI models to execute specific, well-defined queries.
12+
13+
## Schema Structure
14+
15+
The schema consists of:
16+
17+
1. A main schema file (`index.graphql`) that defines:
18+
- The GraphQL types for weather data
19+
- The `@tool` directive that creates a prescribed tool
20+
- The `@sdl` directive that includes the persisted operation
21+
22+
2. An operations file (`operations.graphql`) that contains:
23+
- A GraphQL operation that will be exposed as a tool
24+
- Descriptions for the operation and its variables (recommended best practice)
25+
26+
## How Prescribed Tools Work
27+
28+
A prescribed tool is defined using the `@tool` directive with the `prescribed` argument pointing to a specific operation in a persisted document:
29+
30+
```graphql
31+
schema
32+
# Load the persisted operations document that contains the WeatherForecast operation
33+
@sdl(
34+
files: []
35+
executables: [{ document: "operations.graphql", persist: true }]
36+
)
37+
# Define a prescribed tool that maps to the WeatherForecast operation in the persisted document
38+
@tool(name: "weather-lookup", prescribed: "WeatherForecast") {
39+
query: Query
40+
}
41+
```
42+
43+
The operation in the persisted document should include descriptions ([new to GraphQL September 2025](https://spec.graphql.org/September2025/#Description)) to help AI models understand how to use the tool:
44+
45+
```graphql
46+
"""
47+
Get detailed weather forecast for a specific city
48+
This operation provides a multi-day weather forecast including temperature, conditions, and other meteorological data
49+
"""
50+
query WeatherForecast(
51+
"""The name of the city to get weather forecast for"""
52+
$city: String!,
53+
"""Number of days to forecast (1-7), defaults to 3 days"""
54+
$days: Int = 3
55+
) {
56+
weatherForecast(city: $city, days: $days) {
57+
city {
58+
name
59+
country
60+
timezone
61+
}
62+
forecast {
63+
date
64+
conditions
65+
high {
66+
celsius
67+
fahrenheit
68+
}
69+
low {
70+
celsius
71+
fahrenheit
72+
}
73+
precipitation
74+
humidity
75+
windSpeed
76+
windDirection
77+
}
78+
}
79+
}
80+
```
81+
82+
## MCP Tool Description
83+
84+
When deployed, this schema will expose a tool through the MCP endpoint. The tool's description and parameter information are derived from the GraphQL operation's descriptions:
85+
86+
```json
87+
{
88+
"name": "weather-lookup",
89+
"description": "Get detailed weather forecast for a specific city. This operation provides a multi-day weather forecast including temperature, conditions, and other meteorological data",
90+
"inputSchema": {
91+
"type": "object",
92+
"properties": {
93+
"variables": {
94+
"properties": {
95+
"city": {
96+
"description": "The name of the city to get weather forecast for",
97+
"type": "string"
98+
},
99+
"days": {
100+
"description": "Number of days to forecast (1-7), defaults to 3 days",
101+
"type": "integer",
102+
"default": 3
103+
}
104+
},
105+
"required": ["city"],
106+
"type": "object"
107+
}
108+
},
109+
"required": ["variables"]
110+
}
111+
}
112+
```
113+
114+
## Using the Tool
115+
116+
An AI model can use this tool by:
117+
118+
1. Understanding the tool's purpose from the operation's description
119+
2. Providing the required variables (city name and optionally number of days)
120+
3. Receiving structured weather forecast data in response
121+
122+
## Benefits of Prescribed Tools
123+
124+
1. **Controlled Access**: Only specific, predefined operations are exposed as tools, providing fine-grained control over what AI models can execute.
125+
2. **Type Safety**: The GraphQL schema ensures that inputs are properly validated.
126+
3. **Clear Documentation**: Operation descriptions serve as both documentation for developers and instructions for AI models.
127+
4. **Versioning**: Operations can be versioned and updated independently of the tool definition.
128+
129+
## Testing as an MCP Tool
130+
131+
To test this as an MCP tool with AI models:
132+
133+
1. Deploy the schema to StepZen using the command `stepzen deploy`
134+
2. [Connect Claude Desktop](https://modelcontextprotocol.io/docs/develop/connect-local-servers) to your StepZen MCP endpoint
135+
3. The tool will appear as `weather-lookup` and can be called by the AI model
136+
137+
**Example**: Interaction between MCP and the Claude UI.
138+
139+
<img width="563" height="360" alt="Image" src="https://github.com/user-attachments/assets/7da0cd20-2469-45cd-8a17-0891a1a03dec" />
140+
141+
<img width="502" height="588" alt="Image" src="https://github.com/user-attachments/assets/cf499b7e-a3fe-433c-b837-bdde25441739" />

executable/tools-with-descriptions/index.graphql renamed to executable/prescribed/index.graphql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
schema
2+
# Load the persisted operations document that contains the WeatherForecast operation
23
@sdl(
34
files: []
45
executables: [{ document: "operations.graphql", persist: true }]
56
)
7+
# Define a prescribed tool that maps to the WeatherForecast operation in the persisted document
68
@tool(name: "weather-lookup", prescribed: "WeatherForecast") {
79
query: Query
810
}
911

1012
type Query {
1113
# Get weather forecast for a specific city
12-
weatherForecast(city: String!, days: Int = 3): WeatherForecast
14+
weatherForecast(city: String!, days: Int = 1): WeatherForecast
1315
@value(
1416
script: {
1517
src: """
@@ -49,8 +51,8 @@ type Query {
4951
}
5052
};
5153
52-
// Default to 3 days if not specified or out of range
53-
const daysToForecast = days < 1 || days > 7 ? 3 : days;
54+
// Default to 1 day if not specified or out of range
55+
const daysToForecast = days < 1 || days > 7 ? 1 : days;
5456
5557
const normalizedCity = city.toLowerCase();
5658
const cityData = cities[normalizedCity] || {

executable/tools-with-descriptions/operations.graphql renamed to executable/prescribed/operations.graphql

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ This operation provides a multi-day weather forecast including temperature, cond
55
query WeatherForecast(
66
"""The name of the city to get weather forecast for"""
77
$city: String!,
8-
"""Number of days to forecast (1-7), defaults to 3 days"""
9-
$days: Int = 3
8+
"""Number of days to forecast (1-7), defaults to current day"""
9+
$days: Int = 1
1010
) {
1111
weatherForecast(city: $city, days: $days) {
1212
city {
@@ -15,7 +15,6 @@ query WeatherForecast(
1515
timezone
1616
}
1717
forecast {
18-
date
1918
high {
2019
celsius
2120
fahrenheit
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const {
2+
deployAndRun,
3+
stepzen,
4+
getTestDescription,
5+
} = require("../../../tests/gqltest.js");
6+
7+
testDescription = getTestDescription("snippets", __dirname);
8+
9+
describe(testDescription, function () {
10+
const tests = [
11+
{
12+
label: "WeatherForecast",
13+
documentId:
14+
"sha256:eb01da571734ea3074e4aa494398f947ff76c3b339ad0c15d5c9127b5f53ac4d",
15+
operationName: "WeatherForecast",
16+
variables: {
17+
city: "Sydney",
18+
},
19+
expected: {
20+
weatherForecast: {
21+
city: {
22+
name: "Sydney",
23+
country: "Australia",
24+
timezone: "Australia/Sydney"
25+
},
26+
forecast: [
27+
{
28+
high: {
29+
celsius: 28,
30+
fahrenheit: 82
31+
},
32+
low: {
33+
celsius: 20,
34+
fahrenheit: 68
35+
},
36+
conditions: "Sunny",
37+
precipitation: 10,
38+
humidity: 60,
39+
windSpeed: 15,
40+
windDirection: "NE"
41+
},
42+
],
43+
},
44+
},
45+
},
46+
];
47+
return deployAndRun(__dirname, tests, stepzen.admin);
48+
});

executable/tools-with-descriptions/README.md

Lines changed: 0 additions & 110 deletions
This file was deleted.

0 commit comments

Comments
 (0)