Repository: modelcontextprotocol/python-sdk

Issue:
resourceTemplate do not - but do actually work in Python SDK v1.2.0
**Describe the bug**
resourceTemplates do not work, but actually it seems they do work....

**To Reproduce**
Steps to reproduce the behavior:
Follow the example at: https://github.com/modelcontextprotocol/python-sdk
Create the Demo server in latest release:

```python
# server.py
from mcp.server.fastmcp import FastMCP

# Create an MCP server
mcp = FastMCP("Demo")

# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

# Add a dynamic greeting resource
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """Get a personalized greeting"""
    return f"Hello, {name}!"

@mcp.resource("config://app")
def get_config() -> str:
    """Static configuration data"""
    return "App configuration here"

@mcp.resource("users://{user_id}/profile")
def get_user_profile(user_id: str) -> str:
    """Dynamic user data"""
    return f"Profile data for user {user_id}"
```

**Expected behavior**
Using inspector I should be able to 'List Resources' (that works) and 'List Templates(throws error).
Click List Templates in inspector throws:
Error
MCP error -32601: Method not found

I should see the two resourceTemplates in my Demo server.py
There are open issues in this repository related to same behavior with resourceTemplates and ./.venv/lib/python3.12/site-packages/mcp/server/fastmcp/server.py there is:

```python
    def _setup_handlers(self) -> None:
        """Set up core MCP protocol handlers."""
        self._mcp_server.list_tools()(self.list_tools)
        self._mcp_server.call_tool()(self.call_tool)
        self._mcp_server.list_resources()(self.list_resources)
        self._mcp_server.read_resource()(self.read_resource)
        self._mcp_server.list_prompts()(self.list_prompts)
        self._mcp_server.get_prompt()(self.get_prompt)
        # TODO: This has not been added to MCP yet, see https://github.com/jlowin/fastmcp/issues/10
        # self._mcp_server.list_resource_templates()(self.list_resource_templates)
```

I removed the comment

```python
    def _setup_handlers(self) -> None:
        """Set up core MCP protocol handlers."""
        self._mcp_server.list_tools()(self.list_tools)
        self._mcp_server.call_tool()(self.call_tool)
        self._mcp_server.list_resources()(self.list_resources)
        self._mcp_server.read_resource()(self.read_resource)
        self._mcp_server.list_prompts()(self.list_prompts)
        self._mcp_server.get_prompt()(self.get_prompt)
        # TODO: This has not been added to MCP yet, see https://github.com/jlowin/fastmcp/issues/10
        self._mcp_server.list_resource_templates()(self.list_resource_templates)
```
 
Apparently resourceTemplates are added to MCP (and I use them myself prior to FastMCP, just with python SDK)
Now I get the expected result.

REQUEST:
```json
{"method":"resources/templates/list","params":{}}
```
RESPONSE:
```json
{"resourceTemplates":[{"uriTemplate":"greeting://{name}","name":"get_greeting","description":"Get a personalized greeting"},{"uriTemplate":"users://{user_id}/profile","name":"get_user_profile","description":"Dynamic user data"}]}
```


**Desktop (please complete the following information):**
OS: Monterey 12.7.6
Browser Chrome

**Additional context**
just need to remove the '#' and enable the method it seems...


Discussion:

Patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 929e5f5..02cf387 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,32 +15,22 @@ uv sync --frozen --all-extras --dev
 
 ## Development Workflow
 
-1. Choose the correct branch for your changes:
-   - For bug fixes to a released version: use the latest release branch (e.g. v1.1.x for 1.1.3)
-   - For new features: use the main branch (which will become the next minor/major version)
-   - If unsure, ask in an issue first
-
-2. Create a new branch from your chosen base branch
-
-3. Make your changes
-
-4. Ensure tests pass:
+1. Create a new branch for your changes
+2. Make your changes
+3. Ensure tests pass:
 ```bash 
 uv run pytest
 ```
-
-5. Run type checking:
+4. Run type checking:
 ```bash
 uv run pyright
 ```
-
-6. Run linting:
+5. Run linting:
 ```bash
 uv run ruff check .
 uv run ruff format .
 ```
-
-7. Submit a pull request to the same branch you branched from
+6. Submit a pull request
 
 ## Code Style
 
diff --git a/examples/fastmcp/parameter_descriptions.py b/examples/fastmcp/parameter_descriptions.py
new file mode 100644
index 0000000..dc56e91
--- /dev/null
+++ b/examples/fastmcp/parameter_descriptions.py
@@ -0,0 +1,21 @@
+"""
+FastMCP Example showing parameter descriptions
+"""
+
+from pydantic import Field
+
+from mcp.server.fastmcp import FastMCP
+
+# Create server
+mcp = FastMCP("Parameter Descriptions Server")
+
+
+@mcp.tool()
+def greet_user(
+    name: str = Field(description="The name of the person to greet"),
+    title: str = Field(description="Optional title like Mr/Ms/Dr", default=""),
+    times: int = Field(description="Number of times to repeat the greeting", default=1),
+) -> str:
+    """Greet a user with optional title and repetition"""
+    greeting = f"Hello {title + ' ' if title else ''}{name}!"
+    return "\n".join([greeting] * times)
diff --git a/pyproject.toml b/pyproject.toml
index 31a5494..ddfa725 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [project]
 name = "mcp"
-version = "1.3.0.dev0"
+version = "1.2.0"
 description = "Model Context Protocol SDK"
 readme = "README.md"
 requires-python = ">=3.10"
@@ -83,4 +83,4 @@ target-version = "py310"
 members = ["examples/servers/*"]
 
 [tool.uv.sources]
-mcp = { workspace = true }
+mcp = { workspace = true }
\ No newline at end of file
diff --git a/src/mcp/cli/cli.py b/src/mcp/cli/cli.py
index f30529c..1512e11 100644
--- a/src/mcp/cli/cli.py
+++ b/src/mcp/cli/cli.py
@@ -6,10 +6,10 @@ import os
 import subprocess
 import sys
 from pathlib import Path
+from typing import Annotated
 
 try:
     import typer
-    from typing_extensions import Annotated
 except ImportError:
     print("Error: typer is required. Install with 'pip install mcp[cli]'")
     sys.exit(1)
diff --git a/src/mcp/server/fastmcp/server.py b/src/mcp/server/fastmcp/server.py
index 7d3d2ba..55d5a3c 100644
--- a/src/mcp/server/fastmcp/server.py
+++ b/src/mcp/server/fastmcp/server.py
@@ -133,8 +133,7 @@ class FastMCP:
         self._mcp_server.read_resource()(self.read_resource)
         self._mcp_server.list_prompts()(self.list_prompts)
         self._mcp_server.get_prompt()(self.get_prompt)
-        # TODO: This has not been added to MCP yet, see https://github.com/jlowin/fastmcp/issues/10
-        # self._mcp_server.list_resource_templates()(self.list_resource_templates)
+        self._mcp_server.list_resource_templates()(self.list_resource_templates)
 
     async def list_tools(self) -> list[MCPTool]:
         """List all available tools."""
diff --git a/uv.lock b/uv.lock
index 1eec17f..ad2ec81 100644
--- a/uv.lock
+++ b/uv.lock
@@ -191,7 +191,7 @@ wheels = [
 
 [[package]]
 name = "mcp"
-version = "1.2.0.dev0"
+version = "1.2.0"
 source = { editable = "." }
 dependencies = [
     { name = "anyio" },


Test patch:
diff --git a/tests/issues/test_129_resource_templates.py b/tests/issues/test_129_resource_templates.py
new file mode 100644
index 0000000..e6eff3d
--- /dev/null
+++ b/tests/issues/test_129_resource_templates.py
@@ -0,0 +1,44 @@
+import pytest
+
+from mcp import types
+from mcp.server.fastmcp import FastMCP
+
+
+@pytest.mark.anyio
+async def test_resource_templates():
+    # Create an MCP server
+    mcp = FastMCP("Demo")
+
+    # Add a dynamic greeting resource
+    @mcp.resource("greeting://{name}")
+    def get_greeting(name: str) -> str:
+        """Get a personalized greeting"""
+        return f"Hello, {name}!"
+
+    @mcp.resource("users://{user_id}/profile")
+    def get_user_profile(user_id: str) -> str:
+        """Dynamic user data"""
+        return f"Profile data for user {user_id}"
+
+    # Get the list of resource templates using the underlying server
+    # Note: list_resource_templates() returns a decorator that wraps the handler
+    # The handler returns a ServerResult with a ListResourceTemplatesResult inside
+    result = await mcp._mcp_server.request_handlers[types.ListResourceTemplatesRequest](
+        types.ListResourceTemplatesRequest(
+            method="resources/templates/list", params=None, cursor=None
+        )
+    )
+    assert isinstance(result.root, types.ListResourceTemplatesResult)
+    templates = result.root.resourceTemplates
+
+    # Verify we get both templates back
+    assert len(templates) == 2
+
+    # Verify template details
+    greeting_template = next(t for t in templates if t.name == "get_greeting")
+    assert greeting_template.uriTemplate == "greeting://{name}"
+    assert greeting_template.description == "Get a personalized greeting"
+
+    profile_template = next(t for t in templates if t.name == "get_user_profile")
+    assert profile_template.uriTemplate == "users://{user_id}/profile"
+    assert profile_template.description == "Dynamic user data"
diff --git a/tests/server/fastmcp/test_parameter_descriptions.py b/tests/server/fastmcp/test_parameter_descriptions.py
new file mode 100644
index 0000000..0a45e4f
--- /dev/null
+++ b/tests/server/fastmcp/test_parameter_descriptions.py
@@ -0,0 +1,30 @@
+"""Test that parameter descriptions are properly exposed through list_tools"""
+
+import pytest
+from pydantic import Field
+
+from mcp.server.fastmcp import FastMCP
+
+
+@pytest.mark.asyncio
+async def test_parameter_descriptions():
+    mcp = FastMCP("Test Server")
+
+    @mcp.tool()
+    def greet(
+        name: str = Field(description="The name to greet"),
+        title: str = Field(description="Optional title", default=""),
+    ) -> str:
+        """A greeting tool"""
+        return f"Hello {title} {name}"
+
+    tools = await mcp.list_tools()
+    assert len(tools) == 1
+    tool = tools[0]
+
+    # Check that parameter descriptions are present in the schema
+    properties = tool.inputSchema["properties"]
+    assert "name" in properties
+    assert properties["name"]["description"] == "The name to greet"
+    assert "title" in properties
+    assert properties["title"]["description"] == "Optional title"