Skip to content

Commit 6ddb60a

Browse files
authored
Merge branch 'master' into tkdodo/tanstack-start
2 parents 4138f39 + 65ce01b commit 6ddb60a

File tree

13 files changed

+562
-15
lines changed

13 files changed

+562
-15
lines changed

docs/platforms/android/session-replay/index.mdx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,22 @@ SentryAndroid.init(context) { options ->
5757

5858
options.sessionReplay.onErrorSampleRate = 1.0
5959
options.sessionReplay.sessionSampleRate = 0.1
60+
61+
// if your application has strict PII requirements we recommend using the Canvas screenshot strategy
62+
// Note: this strategy is experimental and does **not** support any masking options, it always masks text and images
63+
// Available in the Android SDK version 8.24.0 or above
64+
// options.sessionReplay.screenshotStrategy = ScreenshotStrategyType.CANVAS
6065
}
6166
```
6267

6368
```XML {filename:AndroidManifest.xml}
6469
<meta-data android:name="io.sentry.session-replay.on-error-sample-rate" android:value="1.0" />
6570
<meta-data android:name="io.sentry.session-replay.session-sample-rate" android:value="0.1" />
71+
72+
<!-- if your application has strict PII requirements we recommend using the Canvas screenshot strategy -->
73+
<!-- Note: this strategy is experimental and does **not** support any masking options, it always masks text and images -->
74+
<!-- Available in the Android SDK version 8.24.0 or above -->
75+
<!-- <meta-data android:name="io.sentry.session-replay.screenshot-strategy" android:value="canvas" /> -->
6676
```
6777

6878
## Verify
@@ -117,6 +127,32 @@ options.sessionReplay.maskAllImages = false
117127
<meta-data android:name="io.sentry.session-replay.mask-all-images" android:value="false" />
118128
```
119129

130+
### Screenshot Strategy
131+
132+
The SDK offers two strategies for recording replays: `PixelCopy` and `Canvas`.
133+
134+
`PixelCopy` uses Android's [PixelCopy](https://developer.android.com/reference/android/view/PixelCopy) API to capture screenshots of the current screen and takes a snapshot of the view hierarchy within the same frame. The view hierarchy is then used to find the position of controls such as text boxes, images, labels, and buttons and mask them with a block that's drawn over these controls. This strategy has slightly lower performance overhead but may result in masking misalignments due to the asynchronous nature of the PixelCopy API. We recommend using this strategy for apps that do not have strict PII requirements or do not require masking functionality.
135+
136+
`Canvas` uses Android's custom [Canvas](https://developer.android.com/reference/android/graphics/Canvas) API to redraw the screen contents onto a bitmap, masking all `drawText` and `drawBitmap` operations in the process to produce a masked screenshot. This strategy has a slightly higher performance overhead but provides more reliable masking. We recommend using this strategy for apps with strict PII requirements.
137+
138+
<Alert level="warning">
139+
140+
The `Canvas` screenshot strategy is currently experimental and does **not** support any masking options. When the screenshot strategy is set to `Canvas`, it will **always** mask all texts, input fields and images, disregarding any masking options set. If you need more flexibility with masking, switch back to `PixelCopy`.
141+
142+
</Alert>
143+
144+
You can change the strategy as follows:
145+
146+
```kotlin
147+
import io.sentry.ScreenshotStrategyType
148+
149+
options.sessionReplay.screenshotStrategy = ScreenshotStrategyType.CANVAS // or ScreenshotStrategyType.PIXEL_COPY (default)
150+
```
151+
152+
```XML {filename:AndroidManifest.xml}
153+
<meta-data android:name="io.sentry.session-replay.screenshot-strategy" android:value="canvas|pixelCopy" />
154+
```
155+
120156
## Error Linking
121157

122158
Errors that happen while a replay is running will be linked to the replay, making it possible to jump between related issues and replays. However, it's **possible** that in some cases the error count reported on the **Replays Details** page won't match the actual errors that have been captured. That's because errors can be lost, and while this is uncommon, there are a few reasons why it could happen:

docs/platforms/android/session-replay/privacy/index.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ description: "Learn how to mask parts of your app's data in Session Replay."
77

88
<Alert level="warning">
99

10+
The masking options below only apply when using the default `PixelCopy` strategy. If you set the strategy to [Canvas](/platforms/android/session-replay/#screenshot-strategy), those options will be ignored and all sensitive content (texts, inputs, images) will be **always** masked.
11+
12+
</Alert>
13+
14+
<Alert level="warning">
15+
1016
Before enabling Session Replay in production, verify your masking configuration to ensure no sensitive data is captured. Our default settings aggressively mask potentially sensitive data, but if you modify these settings or update UI frameworks or system SDKs, you must thoroughly test your application. If you find any masking issues or sensitive data that should be masked but isn't, please [create a GitHub issue](https://github.com/getsentry/sentry-java/issues/new/choose) and avoid deploying to production with Session Replay enabled until the issue is resolved.
1117

1218
</Alert>

docs/platforms/javascript/common/configuration/integrations/pino.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,12 @@ supported:
2323
- javascript.remix
2424
- javascript.react-router
2525
- javascript.astro
26-
- javascript.bun
2726
- javascript.tanstackstart-react
2827
---
2928

3029
<Alert>
3130

32-
This integration only works in the Node.js and Bun runtimes. Requires SDK version `10.18.0` or higher.
31+
This integration only works in the Node.js runtime. Requires SDK version `10.18.0` or higher.
3332

3433
</Alert>
3534

docs/platforms/javascript/common/tracing/instrumentation/ai-agents-module.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ The JavaScript SDK supports automatic instrumentation for some AI libraries. We
6464

6565
## Manual Instrumentation
6666

67-
If you're using a library that Sentry does not automatically instrument, you can manually instrument your code to capture spans. For your AI agents data to show up in the Sentry [AI Agents Insights](https://sentry.io/orgredirect/organizations/:orgslug/insights/agents/), two spans must be created and have well-defined names and data attributes. See below.
67+
If you're using a library that Sentry does not automatically instrument, you can manually instrument your code to capture spans. For your AI agents data to show up in the Sentry [AI Agents Insights](https://sentry.io/orgredirect/organizations/:orgslug/insights/ai/agents/), two spans must be created and have well-defined names and data attributes. See below.
6868

6969
## Spans
7070

docs/platforms/python/integrations/index.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ The Sentry SDK uses integrations to hook into the functionality of popular libra
4848
| <LinkWithPlatformIcon platform="langchain" label="LangChain" url="/platforms/python/integrations/langchain" /> ||
4949
| <LinkWithPlatformIcon platform="langgraph" label="LangGraph" url="/platforms/python/integrations/langgraph" /> ||
5050
| <LinkWithPlatformIcon platform="litellm" label="LiteLLM" url="/platforms/python/integrations/litellm" /> | |
51+
| <LinkWithPlatformIcon platform="pydantic-ai" label="Pydantic AI" url="/platforms/python/integrations/pydantic-ai" /> | |
52+
| <LinkWithPlatformIcon platform="mcp" label="MCP (Model Context Protocol)" url="/platforms/python/integrations/mcp" /> | |
53+
5154

5255
### Data Processing
5356

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
---
2+
title: MCP (Model Context Protocol)
3+
description: "Learn about using the Sentry Python SDK for MCP (Model Context Protocol) servers."
4+
---
5+
6+
<Alert title="Beta">
7+
8+
The support for **MCP (Model Context Protocol) Python SDK** is in its beta phase. Please test locally before using in production.
9+
10+
</Alert>
11+
12+
This integration connects Sentry with the [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk), enabling monitoring and error tracking for MCP servers built with Python.
13+
14+
The integration supports both the high-level FastMCP API and the low-level `mcp.server.lowlevel.Server` API, automatically instrumenting tools, prompts, and resources.
15+
16+
Once you've installed this SDK, you can use Sentry to monitor your MCP server's operations, track tool executions, and capture errors that occur during request handling.
17+
18+
Sentry MCP monitoring will automatically collect information about:
19+
20+
- Tool invocations and their arguments
21+
- Prompt template requests
22+
- Resource access operations
23+
- Request and session identifiers
24+
- Transport types (stdio/HTTP)
25+
- Execution errors
26+
27+
## Install
28+
29+
Install `sentry-sdk` from PyPI with the `mcp` extra:
30+
31+
```bash {tabTitle:pip}
32+
pip install "sentry-sdk[mcp]"
33+
```
34+
35+
```bash {tabTitle:uv}
36+
uv add "sentry-sdk[mcp]"
37+
```
38+
39+
## Configure
40+
41+
If you have the `mcp` package in your dependencies, the MCP integration will be enabled automatically when you initialize the Sentry SDK.
42+
43+
<PlatformContent includePath="getting-started-config" />
44+
45+
## Verify
46+
47+
Verify that the integration works by running an MCP server with tool handlers. The resulting data should show up in your Sentry dashboard.
48+
49+
### Using FastMCP (High-Level API)
50+
51+
FastMCP provides a simplified decorator-based API for building MCP servers:
52+
53+
```python
54+
import sentry_sdk
55+
from sentry_sdk.integrations.mcp import MCPIntegration
56+
57+
from mcp.server.fastmcp import FastMCP
58+
59+
# Initialize Sentry
60+
sentry_sdk.init(
61+
dsn="___PUBLIC_DSN___",
62+
traces_sample_rate=1.0,
63+
# Add data like tool inputs/outputs;
64+
# see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info
65+
send_default_pii=True,
66+
)
67+
68+
# Create the MCP server
69+
mcp = FastMCP("Example MCP Server")
70+
71+
# Define a tool
72+
@mcp.tool()
73+
async def calculate_sum(a: int, b: int) -> int:
74+
"""Add two numbers together."""
75+
return a + b
76+
77+
@mcp.tool()
78+
def greet_user(name: str) -> str:
79+
"""Generate a personalized greeting."""
80+
return f"Hello, {name}! Welcome to the MCP server."
81+
82+
# Define a resource
83+
@mcp.resource("config://settings")
84+
def get_settings() -> str:
85+
"""Get server configuration settings."""
86+
return "Server Configuration: Version 1.0.0"
87+
88+
# Define a prompt
89+
@mcp.prompt()
90+
def code_review_prompt(language: str = "python") -> str:
91+
"""Generate a code review prompt for a specific language."""
92+
return f"You are an expert {language} code reviewer..."
93+
94+
# Run the server
95+
mcp.run()
96+
```
97+
98+
### Using the Low-Level API
99+
100+
For more control over server behavior, use the low-level API:
101+
102+
```python
103+
import asyncio
104+
from typing import Any
105+
106+
import sentry_sdk
107+
from sentry_sdk.integrations.mcp import MCPIntegration
108+
109+
from mcp.server.lowlevel import Server
110+
from mcp.server import stdio
111+
from mcp.types import Tool, TextContent, GetPromptResult, PromptMessage
112+
113+
# Initialize Sentry
114+
sentry_sdk.init(
115+
dsn="___PUBLIC_DSN___",
116+
traces_sample_rate=1.0,
117+
send_default_pii=True,
118+
)
119+
120+
# Create the low-level MCP server
121+
server = Server("example-lowlevel-server")
122+
123+
# List available tools
124+
@server.list_tools()
125+
async def list_tools() -> list[Tool]:
126+
return [
127+
Tool(
128+
name="calculate_sum",
129+
description="Add two numbers together",
130+
inputSchema={
131+
"type": "object",
132+
"properties": {
133+
"a": {"type": "number", "description": "First number"},
134+
"b": {"type": "number", "description": "Second number"},
135+
},
136+
"required": ["a", "b"],
137+
},
138+
),
139+
]
140+
141+
# Handle tool execution
142+
@server.call_tool()
143+
async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
144+
if name == "calculate_sum":
145+
a = arguments.get("a", 0)
146+
b = arguments.get("b", 0)
147+
result = a + b
148+
return [TextContent(type="text", text=f"The sum is {result}")]
149+
150+
return [TextContent(type="text", text=f"Unknown tool: {name}")]
151+
152+
async def main():
153+
async with stdio.stdio_server() as (read_stream, write_stream):
154+
await server.run(
155+
read_stream,
156+
write_stream,
157+
server.create_initialization_options(),
158+
)
159+
160+
if __name__ == "__main__":
161+
asyncio.run(main())
162+
```
163+
164+
It may take a couple of moments for the data to appear in [sentry.io](https://sentry.io).
165+
166+
## Behavior
167+
168+
Data on the following will be collected:
169+
170+
- **Tool executions**: Tool name, arguments, results, and execution errors
171+
- **Prompt requests**: Prompt name, arguments, message counts, and content (for single-message prompts)
172+
- **Resource access**: Resource URI, protocol, and access patterns
173+
- **Request context**: Request IDs, session IDs, and transport types (stdio/HTTP)
174+
- **Execution spans**: Timing information for all handler invocations
175+
176+
Sentry considers tool inputs/outputs and prompt content as PII and doesn't include PII data by default. If you want to include the data, set `send_default_pii=True` in the `sentry_sdk.init()` call. To explicitly exclude this data despite `send_default_pii=True`, configure the integration with `include_prompts=False` as shown in the [Options section](#options) below.
177+
178+
### Captured Span Data
179+
180+
For each operation, the following span data attributes are captured:
181+
182+
**General (all operations):**
183+
- `mcp.method.name`: The MCP method name (e.g., `tools/call`, `prompts/get`, `resources/read`)
184+
- `mcp.transport`: Transport type (`pipe` for stdio, `tcp` for HTTP)
185+
- `mcp.request_id`: Request identifier (when available)
186+
- `mcp.session_id`: Session identifier (when available)
187+
188+
**Tools:**
189+
- `mcp.tool.name`: The name of the tool being executed
190+
- `mcp.request.argument.*`: Tool input arguments
191+
- `mcp.tool.result.content`: Tool output (when `send_default_pii=True`)
192+
- `mcp.tool.result.is_error`: Whether the tool execution resulted in an error
193+
194+
**Prompts:**
195+
- `mcp.prompt.name`: The name of the prompt being requested
196+
- `mcp.request.argument.*`: Prompt input arguments
197+
- `mcp.prompt.result.message.count`: Number of messages in the prompt result
198+
- `mcp.prompt.result.message.role`: Role of the message (for single-message prompts)
199+
- `mcp.prompt.result.message.content`: Message content (for single-message prompts, when `send_default_pii=True`)
200+
201+
**Resources:**
202+
- `mcp.resource.uri`: The URI of the resource being accessed
203+
- `mcp.resource.protocol`: The URI protocol/scheme (e.g., `config`, `data`, `file`)
204+
205+
## Options
206+
207+
By adding `MCPIntegration` to your `sentry_sdk.init()` call explicitly, you can set options for `MCPIntegration` to change its behavior:
208+
209+
```python
210+
import sentry_sdk
211+
from sentry_sdk.integrations.mcp import MCPIntegration
212+
213+
sentry_sdk.init(
214+
# ...
215+
# Add data like tool inputs and outputs;
216+
# see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info
217+
send_default_pii=True,
218+
integrations=[
219+
MCPIntegration(
220+
include_prompts=False, # Tool and prompt inputs/outputs will not be sent to Sentry
221+
),
222+
],
223+
)
224+
```
225+
226+
You can pass the following keyword arguments to `MCPIntegration()`:
227+
228+
- `include_prompts`:
229+
230+
Whether tool inputs/outputs and prompt content should be sent to Sentry. Sentry considers this data personal identifiable data (PII) by default. If you want to include the data, set `send_default_pii=True` in the `sentry_sdk.init()` call. To explicitly exclude prompts and outputs despite `send_default_pii=True`, configure the integration with `include_prompts=False`.
231+
232+
The default is `True`.
233+
234+
## Supported Versions
235+
236+
- MCP SDK: 1.15.0+
237+
- Python: 3.9+
238+

docs/platforms/python/integrations/openai-agents/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The support for **OpenAI Agents SDK** is in its beta phase. Please test locally
1212
This integration connects Sentry with the [OpenAI Python SDK](https://openai.github.io/openai-agents-python/).
1313
The integration has been confirmed to work with OpenAI Agents version 0.0.19.
1414

15-
Once you've installed this SDK, you can use [Sentry AI Agents Insights](https://sentry.io/orgredirect/organizations/:orgslug/insights/agents/), a Sentry dashboard that helps you understand what's going on with your AI agents.
15+
Once you've installed this SDK, you can use [Sentry AI Agents Insights](https://sentry.io/orgredirect/organizations/:orgslug/insights/ai/agents/), a Sentry dashboard that helps you understand what's going on with your AI agents.
1616

1717
Sentry AI Agents monitoring will automatically collect information about agents, tools, prompts, tokens, and models.
1818

0 commit comments

Comments
 (0)