Skip to content

Commit 41556c8

Browse files
committed
take into account result list attributes as PII
1 parent d2a344f commit 41556c8

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

packages/core/src/integrations/mcp-server/attributes.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ export const MCP_TOOL_RESULT_CONTENT_COUNT_ATTRIBUTE = 'mcp.tool.result.content_
7676
/** Serialized content of the tool result */
7777
export const MCP_TOOL_RESULT_CONTENT_ATTRIBUTE = 'mcp.tool.result.content';
7878

79+
/** Prefix for tool result attributes that contain sensitive content */
80+
export const MCP_TOOL_RESULT_PREFIX = 'mcp.tool.result';
81+
7982
// =============================================================================
8083
// PROMPT RESULT ATTRIBUTES
8184
// =============================================================================
@@ -92,6 +95,9 @@ export const MCP_PROMPT_RESULT_MESSAGE_ROLE_ATTRIBUTE = 'mcp.prompt.result.messa
9295
/** Content of the message in the prompt result (for single message results) */
9396
export const MCP_PROMPT_RESULT_MESSAGE_CONTENT_ATTRIBUTE = 'mcp.prompt.result.message_content';
9497

98+
/** Prefix for prompt result attributes that contain sensitive content */
99+
export const MCP_PROMPT_RESULT_PREFIX = 'mcp.prompt.result';
100+
95101
// =============================================================================
96102
// REQUEST ARGUMENT ATTRIBUTES
97103
// =============================================================================

packages/core/src/integrations/mcp-server/piiFiltering.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ import {
1111
MCP_LOGGING_MESSAGE_ATTRIBUTE,
1212
MCP_PROMPT_RESULT_DESCRIPTION_ATTRIBUTE,
1313
MCP_PROMPT_RESULT_MESSAGE_CONTENT_ATTRIBUTE,
14+
MCP_PROMPT_RESULT_PREFIX,
1415
MCP_REQUEST_ARGUMENT,
1516
MCP_RESOURCE_URI_ATTRIBUTE,
1617
MCP_TOOL_RESULT_CONTENT_ATTRIBUTE,
18+
MCP_TOOL_RESULT_PREFIX,
1719
} from './attributes';
1820

1921
/**
@@ -31,11 +33,35 @@ const PII_ATTRIBUTES = new Set([
3133
]);
3234

3335
/**
34-
* Checks if an attribute key should be considered PII
36+
* Checks if an attribute key should be considered PII.
37+
*
38+
* Returns true for:
39+
* - Explicit PII attributes (client.address, client.port, mcp.logging.message, etc.)
40+
* - All request arguments (mcp.request.argument.*)
41+
* - Tool and prompt result content (mcp.tool.result.*, mcp.prompt.result.*) except metadata
42+
*
43+
* Preserves metadata attributes ending with _count, _error, or .is_error as they don't contain sensitive data.
44+
*
45+
* @param key - Attribute key to evaluate
46+
* @returns true if the attribute should be filtered out (is PII), false if it should be preserved
3547
* @internal
3648
*/
3749
function isPiiAttribute(key: string): boolean {
38-
return PII_ATTRIBUTES.has(key) || key.startsWith(`${MCP_REQUEST_ARGUMENT}.`);
50+
if (PII_ATTRIBUTES.has(key)) {
51+
return true;
52+
}
53+
54+
if (key.startsWith(`${MCP_REQUEST_ARGUMENT}.`)) {
55+
return true;
56+
}
57+
58+
if (key.startsWith(`${MCP_TOOL_RESULT_PREFIX}.`) || key.startsWith(`${MCP_PROMPT_RESULT_PREFIX}.`)) {
59+
if (!key.endsWith('_count') && !key.endsWith('_error') && !key.endsWith('.is_error')) {
60+
return true;
61+
}
62+
}
63+
64+
return false;
3965
}
4066

4167
/**

packages/core/test/lib/integrations/mcp-server/piiFiltering.test.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,16 @@ describe('MCP Server PII Filtering', () => {
215215
expect(result).not.toHaveProperty('mcp.tool.result.content');
216216
expect(result).not.toHaveProperty('mcp.prompt.result.description');
217217

218-
// Indexed/dynamic result attributes (not in PII_ATTRIBUTES) should remain
218+
// Count attributes should remain as they don't contain sensitive content
219219
expect(result).toHaveProperty('mcp.tool.result.content_count', 1);
220220
expect(result).toHaveProperty('mcp.prompt.result.message_count', 2);
221-
expect(result).toHaveProperty('mcp.prompt.result.0.role', 'user');
222-
expect(result).toHaveProperty('mcp.prompt.result.0.content', 'Sensitive prompt content');
223-
expect(result).toHaveProperty('mcp.prompt.result.1.role', 'assistant');
224-
expect(result).toHaveProperty('mcp.prompt.result.1.content', 'Another sensitive response');
221+
222+
// All tool and prompt result content should be filtered (including indexed attributes)
223+
expect(result).not.toHaveProperty('mcp.prompt.result.0.role');
224+
expect(result).not.toHaveProperty('mcp.prompt.result.0.content');
225+
expect(result).not.toHaveProperty('mcp.prompt.result.1.role');
226+
expect(result).not.toHaveProperty('mcp.prompt.result.1.content');
227+
225228
expect(result).toHaveProperty('mcp.resource.result.content_count', 1);
226229
expect(result).toHaveProperty('mcp.resource.result.uri', 'file:///private/file.txt');
227230
expect(result).toHaveProperty('mcp.resource.result.content', 'Sensitive resource content');

0 commit comments

Comments
 (0)