Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@tableau/mcp-server",
"description": "Helping agents see and understand data.",
"version": "3.5.3",
"version": "3.5.4",
"repository": {
"type": "git",
"url": "git+https://github.com/tableau/tableau-mcp.git"
Expand Down
11 changes: 0 additions & 11 deletions src/tools/web/recordEvent/recordEvent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,6 @@ describe('getRecordEventTool', () => {
}
});

it('rejects event_type that is too long or not SCREAMING_SNAKE_CASE', async () => {
const schema = z.object(
await Provider.from(getRecordEventTool(new WebMcpServer()).paramsSchema),
);
expect(schema.safeParse({ event_type: 'A'.repeat(65) }).success).toBe(false); // too long
expect(schema.safeParse({ event_type: 'tool_error' }).success).toBe(false); // lowercase
expect(schema.safeParse({ event_type: 'TOOL ERROR' }).success).toBe(false); // spaces
expect(schema.safeParse({ event_type: '1TOOL_ERROR' }).success).toBe(false); // leading digit
expect(schema.safeParse({ event_type: '_TOOL_ERROR' }).success).toBe(false); // leading underscore
});

it('truncates message longer than 1024 characters in the forwarded event', async () => {
const extra = getMockRequestHandlerExtra();
const longMessage = 'x'.repeat(2000);
Expand Down
6 changes: 2 additions & 4 deletions src/tools/web/recordEvent/recordEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ import { WebTool } from '../tool.js';

// Starting field set — the final app-supplied schema is expected to grow later.
const paramsSchema = {
// Bounded free-form string rather than a hard enum: the event-type set is intentionally
// app-extensible (see above), so we reject malformed values but not unknown-yet-valid ones.
// Free-form string rather than a hard enum: the event-type set is intentionally
// app-extensible (see above), so we accept any value rather than reject unknown-yet-valid ones.
event_type: z
.string()
.max(64)
.regex(/^[A-Z][A-Z0-9_]*$/, 'event_type must be SCREAMING_SNAKE_CASE (e.g. TOOL_ERROR).')
.describe(
'The event type for product telemetry, e.g. TOOL_ERROR, PARSE_ERROR, AUTH_ERROR, EMBED_LOAD_ERROR, MCP_APP_CLICKED.',
),
Expand Down
Loading