Skip to content

Conversation

@anyoung-tableau
Copy link
Collaborator

@anyoung-tableau anyoung-tableau commented Oct 17, 2025

These changes allow server administrators to limit the scope of its tools to a set of data sources, workbooks, or projects.

Enabling tool scoping can cause:

  1. Tools to return an error if they are called with arguments that are not within the allowed scope,
    and
  2. Tools to respond with results that have been filtered to only include content from the allowed
    scope.

Examples use-cases

  • Only allow clients to query a single data source with the Query Data Source tool. A client attempting to query any other data source will result in an error.
  • Filter the results of the List Workbooks tool to only include workbooks that exist in a single project. Workbooks from other projects will not be included in the results.

Comment on lines -13 to -17
process.env = {
...originalEnv,
DATASOURCE_CREDENTIALS: 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.

I refactored these tests to mock getConfig instead of relying on setting and resetting environment variables.

),
}));

describe('queryDatasourceTool', () => {
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 refactored these tests to mock getConfig instead of relying on setting and resetting environment variables.

workbookId,
siteId: restApi.siteId,
});
// Notice that we already have the workbook if it had been allowed by a project scope.
Copy link
Collaborator Author

@anyoung-tableau anyoung-tableau Oct 24, 2025

Choose a reason for hiding this comment

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

Leaving a note here since this does something a bit special. Checking whether the workbook is allowed could potentially have called restApi.workbooksMethods.getWorkbook(), the same method as below. No need to call it twice. See https://github.com/tableau/tableau-mcp/pull/131/files#r2458957992

getErrorText?: (error: E) => string;

// A function that constrains the success result of the tool
constrainSuccessResult: (result: T) => ConstrainedResult<T> | Promise<ConstrainedResult<T>>;
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 decided not to make this function optional, so we don't forget to implement it for any new tools

@anyoung-tableau anyoung-tableau marked this pull request as ready for review October 24, 2025 00:41
@Copilot Copilot AI review requested due to automatic review settings October 24, 2025 00:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds tool scoping capabilities to the Tableau MCP server, allowing administrators to constrain tool results and arguments by projects, data sources, or workbooks through environment variables.

Key changes:

  • Introduced bounded context filtering via INCLUDE_PROJECT_IDS, INCLUDE_DATASOURCE_IDS, and INCLUDE_WORKBOOK_IDS environment variables
  • Implemented ResourceAccessChecker singleton for validating and caching access permissions
  • Added constraint functions to filter results in list tools (workbooks, views, datasources, Pulse metrics/definitions/subscriptions, and search content)

Reviewed Changes

Copilot reviewed 65 out of 67 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/config.ts Added bounded context configuration parsing and validation
src/tools/resourceAccessChecker.ts New singleton class for checking resource access with caching logic
src/tools/tool.ts Extended tool execution to support result constraining
src/tools/workbooks/listWorkbooks.ts Added workbook filtering by bounded context
src/tools/views/listViews.ts Added view filtering by bounded context
src/tools/listDatasources/listDatasources.ts Added datasource filtering by bounded context
src/tools/pulse/*.ts Added Pulse metric/definition/subscription filtering
src/tools/contentExploration/searchContentUtils.ts Added search content filtering by bounded context
src/tools/workbooks/getWorkbook.ts Added workbook access validation before retrieval
src/tools/views/getViewImage.ts Added view access validation before image retrieval
src/tools/views/getViewData.ts Added view access validation before data retrieval
src/tools/queryDatasource/queryDatasource.ts Added datasource access validation before querying
src/tools/getDatasourceMetadata/getDatasourceMetadata.ts Added datasource access validation before metadata retrieval
src/tools/pulse/generateMetricValueInsightBundle/*.ts Added datasource validation for insight bundle generation
src/sdks/tableau/types/pulse.ts Added datasource_luid field to pulse metric schema
src/sdks/tableau/apis/*.ts Added new REST API endpoints for view and datasource queries
docs/** Documentation updates for tool scoping feature

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

}
}

return { allowed: true, content: workbook };
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here's that "special" thing I mentioned in comment: https://github.com/tableau/tableau-mcp/pull/131/files#r2458160645

This case doesn't apply for the other content types which is why you don't see it for data sources or views.

Enabling tool scoping can cause:

1. Tools to return an error if they are called with arguments that are not within the allowed scope,
and
Copy link
Contributor

Choose a reason for hiding this comment

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

is this "and" intentional or did you mean to add more to this sentence?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It was intentional but I can remove it. The 2nd bullet is the continuation of the sentence.

- Data source IDs can be determined using the
[Query Data Sources](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_data_sources.htm#query_data_sources)
REST API or the [List Data Sources](../../tools/data-qna/list-datasources.md) tool (assuming tool
scoping is disabled).
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps note that limiting a datasource does not limit workbooks or views (assuming that's how that works)

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.

2 participants