Skip to content

Commit 3cb2db1

Browse files
committed
Sync open source content 🐝 (from 7842d008183650a085539bed19833979d5bb4083)
1 parent 6322edd commit 3cb2db1

3 files changed

Lines changed: 83 additions & 0 deletions

File tree

_meta.global.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,9 @@ const meta = {
727727
"functions-framework": {
728728
title: "Using the Functions Framework",
729729
},
730+
"tool-annotations": {
731+
title: "Tool annotations",
732+
},
730733
"mcp-sdk": {
731734
title: "Using the MCP SDK",
732735
},

docs/mcp/build/gram-functions/functions-framework.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Each tool requires the following properties:
3636
- **`name`:** A unique identifier for the tool
3737
- **`description`(optional):** A human-readable explanation of what the tool does
3838
- **`inputSchema`:** A Zod schema defining the expected input parameters
39+
- **`annotations`(optional):** Behavior hints for AI models and clients (see [Tool annotations](/docs/mcp/build/gram-functions/tool-annotations))
3940
- **`execute`:** An async function that implements the tool logic
4041

4142
## Context object
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
title: "Tool annotations"
3+
description: "Add behavior hints to Gram Functions so AI models and clients can make better decisions about tool invocation."
4+
---
5+
6+
## What are tool annotations?
7+
8+
In the [Model Context Protocol](https://modelcontextprotocol.io/docs/concepts/tools#tool-annotations), tools are model-controlled primitives that let AI models invoke server-side functionality. While tool names, descriptions, and input schemas tell a model *what* a tool does, annotations tell clients *how* the tool behaves — whether it reads or writes data, whether it's destructive, and whether it reaches out to external systems.
9+
10+
This matters because MCP clients use annotations to build safer, more intuitive interfaces. A client might auto-approve a tool marked as read-only, require confirmation for destructive operations, or batch idempotent calls without worry. Without annotations, clients have to assume the worst — that every tool is potentially destructive and open-world.
11+
12+
The Gram Functions Framework supports MCP tool annotations directly in tool definitions. Add annotations to any tool using the `annotations` property:
13+
14+
```typescript
15+
import { Gram } from "@gram-ai/functions";
16+
import * as z from "zod/mini";
17+
18+
const gram = new Gram().tool({
19+
name: "delete_user",
20+
description: "Permanently delete a user account",
21+
inputSchema: { userId: z.string() },
22+
annotations: {
23+
title: "Delete User",
24+
destructiveHint: true,
25+
readOnlyHint: false,
26+
idempotentHint: true,
27+
openWorldHint: false,
28+
},
29+
async execute(ctx, input) {
30+
await deleteUser(input.userId);
31+
return ctx.json({ deleted: true });
32+
},
33+
});
34+
35+
export default gram;
36+
```
37+
38+
## Available fields
39+
40+
| Field | Type | Default | Description |
41+
| --- | --- | --- | --- |
42+
| `title` | `string` || Human-readable display name for the tool |
43+
| `readOnlyHint` | `boolean` | `false` | Tool does not modify its environment |
44+
| `destructiveHint` | `boolean` | `true` | Tool may perform destructive updates |
45+
| `idempotentHint` | `boolean` | `false` | Repeated calls with the same arguments have no additional effect |
46+
| `openWorldHint` | `boolean` | `true` | Tool interacts with external entities |
47+
48+
All annotation properties are **hints**. They are not guaranteed to be accurate, and clients should not rely on them for security decisions.
49+
50+
## Default behavior
51+
52+
When no annotations are specified, Gram applies conservative defaults: tools are assumed to be potentially destructive and open-world. Specify annotations explicitly to give clients more accurate information about tool behavior.
53+
54+
```typescript
55+
// A read-only tool that only queries data
56+
const gram = new Gram().tool({
57+
name: "get_weather",
58+
description: "Get current weather for a city",
59+
inputSchema: { city: z.string() },
60+
annotations: {
61+
readOnlyHint: true,
62+
destructiveHint: false,
63+
openWorldHint: true,
64+
},
65+
async execute(ctx, input) {
66+
const weather = await fetchWeather(input.city);
67+
return ctx.json(weather);
68+
},
69+
});
70+
```
71+
72+
## Annotations with MCP SDK passthrough
73+
74+
Annotations defined on Gram Functions are automatically forwarded when tools are exposed through MCP servers. No additional configuration is needed — the annotations set in the tool definition are passed through to MCP clients as part of the tool listing.
75+
76+
## Next steps
77+
78+
- Learn more about the [Functions Framework](/docs/mcp/build/gram-functions/functions-framework)
79+
- [Build and deploy](/docs/mcp/build/gram-functions/build-deploy) Gram Functions

0 commit comments

Comments
 (0)