Skip to content

Commit 09e4eb3

Browse files
ctcanbolCagri Canbol
andauthored
fix: OAuth scope filtering to respect enabled tools filter (#153)
* fix: only add scopes of enabled tools * refac: formatting --------- Co-authored-by: Cagri Canbol <[email protected]>
1 parent 75691bf commit 09e4eb3

File tree

3 files changed

+31
-5
lines changed

3 files changed

+31
-5
lines changed

src/auth.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,31 @@ const SCOPE_HIERARCHY: ScopeHierarchy = {
5050
'Contacts.ReadWrite': ['Contacts.Read'],
5151
};
5252

53-
function buildScopesFromEndpoints(includeWorkAccountScopes: boolean = false): string[] {
53+
function buildScopesFromEndpoints(
54+
includeWorkAccountScopes: boolean = false,
55+
enabledToolsPattern?: string
56+
): string[] {
5457
const scopesSet = new Set<string>();
5558

59+
// Create regex for tool filtering if pattern is provided
60+
let enabledToolsRegex: RegExp | undefined;
61+
if (enabledToolsPattern) {
62+
try {
63+
enabledToolsRegex = new RegExp(enabledToolsPattern, 'i');
64+
logger.info(`Building scopes with tool filter pattern: ${enabledToolsPattern}`);
65+
} catch (error) {
66+
logger.error(
67+
`Invalid tool filter regex pattern: ${enabledToolsPattern}. Building scopes without filter.`
68+
);
69+
}
70+
}
71+
5672
endpoints.default.forEach((endpoint) => {
73+
// Skip endpoints that don't match the tool filter
74+
if (enabledToolsRegex && !enabledToolsRegex.test(endpoint.toolName)) {
75+
return;
76+
}
77+
5778
// Skip endpoints that only have workScopes if not in work mode
5879
if (!includeWorkAccountScopes && !endpoint.scopes && endpoint.workScopes) {
5980
return;
@@ -77,7 +98,12 @@ function buildScopesFromEndpoints(includeWorkAccountScopes: boolean = false): st
7798
}
7899
});
79100

80-
return Array.from(scopesSet);
101+
const scopes = Array.from(scopesSet);
102+
if (enabledToolsPattern) {
103+
logger.info(`Built ${scopes.length} scopes for filtered tools: ${scopes.join(', ')}`);
104+
}
105+
106+
return scopes;
81107
}
82108

83109
interface LoginTestResult {

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ async function main(): Promise<void> {
1616
logger.info('Organization mode enabled - including work account scopes');
1717
}
1818

19-
const scopes = buildScopesFromEndpoints(includeWorkScopes);
19+
const scopes = buildScopesFromEndpoints(includeWorkScopes, args.enabledTools);
2020
const authManager = new AuthManager(undefined, scopes);
2121
await authManager.loadTokenCache();
2222

src/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class MicrosoftGraphServer {
120120
const protocol = req.secure ? 'https' : 'http';
121121
const url = new URL(`${protocol}://${req.get('host')}`);
122122

123-
const scopes = buildScopesFromEndpoints(this.options.orgMode);
123+
const scopes = buildScopesFromEndpoints(this.options.orgMode, this.options.enabledTools);
124124

125125
res.json({
126126
issuer: url.origin,
@@ -141,7 +141,7 @@ class MicrosoftGraphServer {
141141
const protocol = req.secure ? 'https' : 'http';
142142
const url = new URL(`${protocol}://${req.get('host')}`);
143143

144-
const scopes = buildScopesFromEndpoints(this.options.orgMode);
144+
const scopes = buildScopesFromEndpoints(this.options.orgMode, this.options.enabledTools);
145145

146146
res.json({
147147
resource: `${url.origin}/mcp`,

0 commit comments

Comments
 (0)