Jeremiah Lowin commited on
Commit
f6b57a9
·
unverified ·
1 Parent(s): ccc2857

Add annotations docs (#1268)

Browse files
Files changed (1) hide show
  1. docs/servers/resources.mdx +56 -3
docs/servers/resources.mdx CHANGED
@@ -104,6 +104,18 @@ def get_application_status() -> dict:
104
  <ParamField body="enabled" type="bool" default="True">
105
  A boolean to enable or disable the resource. See [Disabling Resources](#disabling-resources) for more information
106
  </ParamField>
 
 
 
 
 
 
 
 
 
 
 
 
107
  </Card>
108
 
109
  ### Return Values
@@ -300,11 +312,46 @@ Notifications are only sent when these operations occur within an active MCP req
300
 
301
  Clients can handle these notifications using a [message handler](/clients/messages) to automatically refresh their resource lists or update their interfaces.
302
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  ## Resource Templates
304
 
305
  Resource Templates allow clients to request resources whose content depends on parameters embedded in the URI. Define a template using the **same `@mcp.resource` decorator**, but include `{parameter_name}` placeholders in the URI string and add corresponding arguments to your function signature.
306
 
307
- Resource templates share most configuration options with regular resources (name, description, mime_type, tags), but add the ability to define URI parameters that map to function parameters.
308
 
309
  Resource templates generate a new resource for each unique set of parameters, which means that resources can be dynamically created on-demand. For example, if the resource template `"user://profile/{name}"` is registered, MCP clients could request `"user://profile/ford"` or `"user://profile/marvin"` to retrieve either of those two user profiles as resources, without having to register each resource individually.
310
 
@@ -332,8 +379,14 @@ def get_weather(city: str) -> dict:
332
  "unit": "celsius"
333
  }
334
 
335
- # Template with multiple parameters
336
- @mcp.resource("repos://{owner}/{repo}/info")
 
 
 
 
 
 
337
  def get_repo_info(owner: str, repo: str) -> dict:
338
  """Retrieves information about a GitHub repository."""
339
  # In a real implementation, this would call the GitHub API
 
104
  <ParamField body="enabled" type="bool" default="True">
105
  A boolean to enable or disable the resource. See [Disabling Resources](#disabling-resources) for more information
106
  </ParamField>
107
+
108
+ <ParamField body="annotations" type="Annotations | dict | None">
109
+ An optional `Annotations` object or dictionary to add additional metadata about the resource.
110
+ <Expandable title="Annotations attributes">
111
+ <ParamField body="readOnlyHint" type="bool | None">
112
+ If true, the resource is read-only and does not modify its environment.
113
+ </ParamField>
114
+ <ParamField body="idempotentHint" type="bool | None">
115
+ If true, reading the resource repeatedly will have no additional effect on its environment.
116
+ </ParamField>
117
+ </Expandable>
118
+ </ParamField>
119
  </Card>
120
 
121
  ### Return Values
 
312
 
313
  Clients can handle these notifications using a [message handler](/clients/messages) to automatically refresh their resource lists or update their interfaces.
314
 
315
+ ### Annotations
316
+
317
+ <VersionBadge version="2.11.0" />
318
+
319
+ FastMCP allows you to add specialized metadata to your resources through annotations. These annotations communicate how resources behave to client applications without consuming token context in LLM prompts.
320
+
321
+ Annotations serve several purposes in client applications:
322
+ - Indicating whether resources are read-only or may have side effects
323
+ - Describing the safety profile of resources (idempotent vs. non-idempotent)
324
+ - Helping clients optimize caching and access patterns
325
+
326
+ You can add annotations to a resource using the `annotations` parameter in the `@mcp.resource` decorator:
327
+
328
+ ```python
329
+ @mcp.resource(
330
+ "data://config",
331
+ annotations={
332
+ "readOnlyHint": True,
333
+ "idempotentHint": True
334
+ }
335
+ )
336
+ def get_config() -> dict:
337
+ """Get application configuration."""
338
+ return {"version": "1.0", "debug": False}
339
+ ```
340
+
341
+ FastMCP supports these standard annotations:
342
+
343
+ | Annotation | Type | Default | Purpose |
344
+ | :--------- | :--- | :------ | :------ |
345
+ | `readOnlyHint` | boolean | true | Indicates if the resource only provides data without side effects |
346
+ | `idempotentHint` | boolean | true | Indicates if repeated reads have the same effect as a single read |
347
+
348
+ Remember that annotations help make better user experiences but should be treated as advisory hints. They help client applications present appropriate UI elements and optimize access patterns, but won't enforce behavior on their own. Always focus on making your annotations accurately represent what your resource actually does.
349
+
350
  ## Resource Templates
351
 
352
  Resource Templates allow clients to request resources whose content depends on parameters embedded in the URI. Define a template using the **same `@mcp.resource` decorator**, but include `{parameter_name}` placeholders in the URI string and add corresponding arguments to your function signature.
353
 
354
+ Resource templates share most configuration options with regular resources (name, description, mime_type, tags, annotations), but add the ability to define URI parameters that map to function parameters.
355
 
356
  Resource templates generate a new resource for each unique set of parameters, which means that resources can be dynamically created on-demand. For example, if the resource template `"user://profile/{name}"` is registered, MCP clients could request `"user://profile/ford"` or `"user://profile/marvin"` to retrieve either of those two user profiles as resources, without having to register each resource individually.
357
 
 
379
  "unit": "celsius"
380
  }
381
 
382
+ # Template with multiple parameters and annotations
383
+ @mcp.resource(
384
+ "repos://{owner}/{repo}/info",
385
+ annotations={
386
+ "readOnlyHint": True,
387
+ "idempotentHint": True
388
+ }
389
+ )
390
  def get_repo_info(owner: str, repo: str) -> dict:
391
  """Retrieves information about a GitHub repository."""
392
  # In a real implementation, this would call the GitHub API