Skip to content

Conversation

@anyoung-tableau
Copy link
Collaborator

@anyoung-tableau anyoung-tableau commented Feb 9, 2026

These changes lay the groundwork for @W-21200059: Add Get/Update MCP site settings REST APIs.

Once the "Get MCP Site Settings" REST API is available, we can call it to get the actual site settings. Currently, the ENABLE_MCP_SITE_SETTINGS feature is disabled but can be enabled for testing. When enabled, the method that retrieves the MCP site settings returns a placeholder empty object (implying no overrides).

@anyoung-tableau anyoung-tableau changed the title Allow config entries to be overridden at runtime from mocked MCP site settings response Add scaffolding so some config entries can be overridden at runtime Feb 9, 2026
@anyoung-tableau anyoung-tableau changed the title Add scaffolding so some config entries can be overridden at runtime Add scaffolding to override some config entries at runtime Feb 9, 2026
@anyoung-tableau anyoung-tableau changed the title Add scaffolding to override some config entries at runtime @W-21200034: Add scaffolding to override some config entries at runtime Feb 10, 2026
Comment on lines +48 to 61
private async getAllowedProjectIds({
restApiArgs,
}: {
restApiArgs: RestApiArgs;
}): Promise<Set<string> | null> {
return (
this._testOverrides.projectIds ??
(
await getConfigWithOverrides({
restApiArgs,
})
).boundedContext.projectIds
);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the scoping logic has changed. The changes in this file are so we retrieve the MCP site settings to see if a tool scoping override exists. Remember, the response from the REST API is cached for the site for n=10 minutes so once we call it once, all subsequence responses come from cache for the next 10 minutes.

Comment on lines +166 to +169
it('should set mcpSiteSettingsCheckIntervalInMinutes to default when not specified', () => {
const config = new Config();
expect(config.mcpSiteSettingsCheckIntervalInMinutes).toBe(10);
});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Diff is kinda bad in this file. I moved the tests for overridable config to their own file and added tests for MCP_SITE_SETTINGS_CHECK_INTERVAL_IN_MINUTES and ENABLE_MCP_SITE_SETTINGS.

Comment on lines -61 to -62
includeTools: Array<ToolName>;
excludeTools: Array<ToolName>;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had initially left all overridable config items in the Config class, leaving the responsibility of checking the site settings for an updated value on the developer. I felt this would be prone to bugs so I moved all the overridable items to OverridableConfig class instead.

import { exportedForTesting } from './overridableConfig.js';
import { stubDefaultEnvVars } from './testShared.js';

describe('OverridableConfig', () => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these tests are copy/paste from config.test.ts

Comment on lines +23 to +29
function filterEnvVarsToOverridable(
environmentVariables: Record<string, string | undefined>,
): Record<OverridableVariable, string | undefined> {
return Object.fromEntries(
Object.entries(environmentVariables).filter(([key]) => isOverridableVariable(key)),
) as Record<OverridableVariable, string | undefined>;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the magic that ensures only the environment variables that we have specified as overridable get overridden.

| 'tableau:views:download'
| 'tableau:insight_brief:create';
| 'tableau:insight_brief:create'
| 'tableau:mcp_site_settings:read';
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is currently a "fake" scope but will be the one we use when adding the new Get MCP Site Settings REST API

@anyoung-tableau anyoung-tableau marked this pull request as ready for review February 11, 2026 01:00
Copilot AI review requested due to automatic review settings February 11, 2026 01:00
Comment on lines +3 to +4
export const mcpSiteSettingsSchema = z.record(z.string(), z.string());
export type McpSiteSettings = z.infer<typeof mcpSiteSettingsSchema>;
Copy link
Collaborator Author

@anyoung-tableau anyoung-tableau Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is that the "Get MCP Site Settings" REST API will return a JSON object in this format, representing key-value pairs of environment variable names and their values

{
  "EXCLUDE_TOOLS": "query-datasource",
  "INCLUDE_DATASOURCE_IDS": "2d935df8-fe7e-4fd8-bb14-35eb4ba31d4"
}

Comment on lines +39 to +46
} & (
| {
requestId: RequestId;
disableLogging?: false;
}
| {
disableLogging: true;
}
Copy link
Collaborator Author

@anyoung-tableau anyoung-tableau Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's not clear, the requestId is only used in logging. This type makes it so you can't provide it when disableLogging is true. TypeScript rules and I'll die on this hill. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant