mcp-sharepoint-us 2.0.2__py3-none-any.whl → 2.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mcp-sharepoint-us might be problematic. Click here for more details.

@@ -1,8 +1,8 @@
1
- """
2
- Entry point for mcp-sharepoint module
3
- """
4
- import asyncio
5
- from . import main
6
-
7
- if __name__ == "__main__":
8
- asyncio.run(main())
1
+ """
2
+ Entry point for mcp-sharepoint module
3
+ """
4
+ import asyncio
5
+ from . import main
6
+
7
+ if __name__ == "__main__":
8
+ asyncio.run(main())
mcp_sharepoint/auth.py CHANGED
@@ -1,234 +1,277 @@
1
- """
2
- Authentication module for SharePoint MCP Server
3
- Supports modern Azure AD authentication methods
4
- """
5
- import os
6
- import logging
7
- from typing import Optional
8
- from office365.sharepoint.client_context import ClientContext
9
- from office365.runtime.auth.client_credential import ClientCredential
10
- import msal
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
-
15
- class SharePointAuthenticator:
16
- """
17
- Handles authentication to SharePoint using modern Azure AD methods.
18
- Supports multiple authentication flows for compatibility with new tenants.
19
- """
20
-
21
- def __init__(
22
- self,
23
- site_url: str,
24
- client_id: str,
25
- client_secret: str,
26
- tenant_id: str,
27
- cert_path: Optional[str] = None,
28
- cert_thumbprint: Optional[str] = None,
29
- ):
30
- """
31
- Initialize SharePoint authenticator.
32
-
33
- Args:
34
- site_url: SharePoint site URL
35
- client_id: Azure AD application client ID
36
- client_secret: Azure AD application client secret
37
- tenant_id: Azure AD tenant ID
38
- cert_path: Optional path to certificate file for cert-based auth
39
- cert_thumbprint: Optional certificate thumbprint
40
- """
41
- self.site_url = site_url.rstrip("/")
42
- self.client_id = client_id
43
- self.client_secret = client_secret
44
- self.tenant_id = tenant_id
45
- self.cert_path = cert_path
46
- self.cert_thumbprint = cert_thumbprint
47
-
48
- def get_context_with_msal(self) -> ClientContext:
49
- """
50
- Get ClientContext using MSAL for modern Azure AD authentication.
51
- This is the recommended method for new tenants.
52
-
53
- Returns:
54
- Authenticated ClientContext
55
- """
56
- def acquire_token():
57
- """Acquire token using MSAL"""
58
- authority_url = f'https://login.microsoftonline.com/{self.tenant_id}'
59
-
60
- app = msal.ConfidentialClientApplication(
61
- authority=authority_url,
62
- client_id=self.client_id,
63
- client_credential=self.client_secret
64
- )
65
-
66
- # SharePoint requires the site-specific scope
67
- scopes = [f"{self.site_url}/.default"]
68
-
69
- result = app.acquire_token_for_client(scopes=scopes)
70
-
71
- if "access_token" not in result:
72
- error_desc = result.get("error_description", "Unknown error")
73
- raise ValueError(f"Failed to acquire token: {error_desc}")
74
-
75
- return result
76
-
77
- ctx = ClientContext(self.site_url).with_access_token(acquire_token)
78
- logger.info("Successfully authenticated using MSAL (Modern Azure AD)")
79
- return ctx
80
-
81
- def get_context_with_certificate(self) -> ClientContext:
82
- """
83
- Get ClientContext using certificate-based authentication.
84
- This is an alternative modern authentication method.
85
-
86
- Returns:
87
- Authenticated ClientContext
88
-
89
- Raises:
90
- ValueError: If certificate credentials are not provided
91
- """
92
- if not self.cert_path or not self.cert_thumbprint:
93
- raise ValueError(
94
- "Certificate path and thumbprint are required for cert-based auth"
95
- )
96
-
97
- ctx = ClientContext(self.site_url).with_client_certificate(
98
- tenant=self.tenant_id,
99
- client_id=self.client_id,
100
- thumbprint=self.cert_thumbprint,
101
- cert_path=self.cert_path
102
- )
103
-
104
- logger.info("Successfully authenticated using certificate")
105
- return ctx
106
-
107
- def get_context_legacy(self) -> ClientContext:
108
- """
109
- Get ClientContext using legacy ACS authentication (deprecated).
110
- This method is included for backwards compatibility but may not work
111
- with new tenants where ACS app-only is disabled.
112
-
113
- Returns:
114
- Authenticated ClientContext
115
- """
116
- logger.warning(
117
- "Using legacy ACS authentication. This may fail on new tenants. "
118
- "Consider using MSAL or certificate-based auth instead."
119
- )
120
-
121
- credentials = ClientCredential(self.client_id, self.client_secret)
122
- ctx = ClientContext(self.site_url).with_credentials(credentials)
123
-
124
- return ctx
125
-
126
- def get_context(self, auth_method: str = "msal") -> ClientContext:
127
- """
128
- Get authenticated ClientContext using the specified method.
129
-
130
- Args:
131
- auth_method: Authentication method to use.
132
- Options: "msal" (default), "certificate", "legacy"
133
-
134
- Returns:
135
- Authenticated ClientContext
136
-
137
- Raises:
138
- ValueError: If invalid auth method specified
139
- """
140
- auth_methods = {
141
- "msal": self.get_context_with_msal,
142
- "certificate": self.get_context_with_certificate,
143
- "legacy": self.get_context_legacy
144
- }
145
-
146
- if auth_method not in auth_methods:
147
- raise ValueError(
148
- f"Invalid auth method: {auth_method}. "
149
- f"Must be one of: {', '.join(auth_methods.keys())}"
150
- )
151
-
152
- try:
153
- return auth_methods[auth_method]()
154
- except Exception as e:
155
- logger.error(f"Authentication failed with method '{auth_method}': {e}")
156
- raise
157
-
158
-
159
- def create_sharepoint_context() -> ClientContext:
160
- """
161
- Factory function to create SharePoint context from environment variables.
162
- Tries modern authentication methods first, falls back to legacy if needed.
163
-
164
- Environment variables required:
165
- - SHP_SITE_URL: SharePoint site URL
166
- - SHP_ID_APP: Azure AD application client ID
167
- - SHP_ID_APP_SECRET: Azure AD application client secret
168
- - SHP_TENANT_ID: Azure AD tenant ID
169
-
170
- Optional environment variables:
171
- - SHP_AUTH_METHOD: Authentication method (msal, certificate, legacy)
172
- - SHP_CERT_PATH: Path to certificate file
173
- - SHP_CERT_THUMBPRINT: Certificate thumbprint
174
-
175
- Returns:
176
- Authenticated ClientContext
177
-
178
- Raises:
179
- ValueError: If required environment variables are missing
180
- """
181
- # Get required environment variables
182
- site_url = os.getenv("SHP_SITE_URL")
183
- client_id = os.getenv("SHP_ID_APP")
184
- client_secret = os.getenv("SHP_ID_APP_SECRET")
185
- tenant_id = os.getenv("SHP_TENANT_ID")
186
-
187
- # Validate required variables
188
- missing_vars = []
189
- if not site_url:
190
- missing_vars.append("SHP_SITE_URL")
191
- if not client_id:
192
- missing_vars.append("SHP_ID_APP")
193
- if not client_secret:
194
- missing_vars.append("SHP_ID_APP_SECRET")
195
- if not tenant_id:
196
- missing_vars.append("SHP_TENANT_ID")
197
-
198
- if missing_vars:
199
- raise ValueError(
200
- f"Missing required environment variables: {', '.join(missing_vars)}"
201
- )
202
-
203
- # Get optional environment variables
204
- auth_method = os.getenv("SHP_AUTH_METHOD", "msal")
205
- cert_path = os.getenv("SHP_CERT_PATH")
206
- cert_thumbprint = os.getenv("SHP_CERT_THUMBPRINT")
207
-
208
- # Create authenticator
209
- authenticator = SharePointAuthenticator(
210
- site_url=site_url,
211
- client_id=client_id,
212
- client_secret=client_secret,
213
- tenant_id=tenant_id,
214
- cert_path=cert_path,
215
- cert_thumbprint=cert_thumbprint
216
- )
217
-
218
- # Try to authenticate
219
- try:
220
- ctx = authenticator.get_context(auth_method=auth_method)
221
- logger.info(f"Successfully created SharePoint context using {auth_method} auth")
222
- return ctx
223
- except Exception as e:
224
- logger.error(f"Failed to create SharePoint context: {e}")
225
-
226
- # If MSAL failed and we haven't tried legacy, suggest it
227
- if auth_method == "msal":
228
- logger.info(
229
- "MSAL authentication failed. If you're using an older tenant, "
230
- "you can try setting SHP_AUTH_METHOD=legacy, but note that "
231
- "legacy ACS authentication is deprecated and may not work on new tenants."
232
- )
233
-
234
- raise
1
+ """
2
+ Authentication module for SharePoint MCP Server
3
+ Supports Azure US Government Cloud and Commercial Cloud
4
+ """
5
+ import os
6
+ import logging
7
+ from typing import Optional
8
+ from office365.sharepoint.client_context import ClientContext
9
+ from office365.runtime.auth.client_credential import ClientCredential
10
+ import msal
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class SharePointAuthenticator:
16
+ """
17
+ Handles authentication to SharePoint using modern Azure AD methods.
18
+ Supports both Commercial and US Government clouds.
19
+ """
20
+
21
+ def __init__(
22
+ self,
23
+ site_url: str,
24
+ client_id: str,
25
+ client_secret: str,
26
+ tenant_id: str,
27
+ cert_path: Optional[str] = None,
28
+ cert_thumbprint: Optional[str] = None,
29
+ cloud: str = "government" # Default to US Government
30
+ ):
31
+ """
32
+ Initialize SharePoint authenticator.
33
+
34
+ Args:
35
+ site_url: SharePoint site URL
36
+ client_id: Azure AD application client ID
37
+ client_secret: Azure AD application client secret
38
+ tenant_id: Azure AD tenant ID
39
+ cert_path: Optional path to certificate file for cert-based auth
40
+ cert_thumbprint: Optional certificate thumbprint
41
+ cloud: Cloud environment - "commercial" or "government" (default)
42
+ """
43
+ self.site_url = site_url.rstrip("/")
44
+ self.client_id = client_id
45
+ self.client_secret = client_secret
46
+ self.tenant_id = tenant_id
47
+ self.cert_path = cert_path
48
+ self.cert_thumbprint = cert_thumbprint
49
+ self.cloud = cloud.lower()
50
+
51
+ def get_context_with_msal(self) -> ClientContext:
52
+ """
53
+ Get ClientContext using MSAL for modern Azure AD authentication.
54
+ Supports both Commercial and US Government clouds.
55
+
56
+ Returns:
57
+ Authenticated ClientContext
58
+ """
59
+ def acquire_token():
60
+ """Acquire token using MSAL"""
61
+ # Set authority URL based on cloud environment
62
+ if self.cloud == "government" or self.cloud == "us":
63
+ # Azure US Government Cloud
64
+ authority_url = f'https://login.microsoftonline.us/{self.tenant_id}'
65
+ logger.info("Using Azure US Government Cloud endpoints")
66
+ else:
67
+ # Commercial Cloud
68
+ authority_url = f'https://login.microsoftonline.com/{self.tenant_id}'
69
+ logger.info("Using Azure Commercial Cloud endpoints")
70
+
71
+ app = msal.ConfidentialClientApplication(
72
+ authority=authority_url,
73
+ client_id=self.client_id,
74
+ client_credential=self.client_secret
75
+ )
76
+
77
+ # SharePoint requires the site-specific scope
78
+ scopes = [f"{self.site_url}/.default"]
79
+
80
+ result = app.acquire_token_for_client(scopes=scopes)
81
+
82
+ if "access_token" not in result:
83
+ error_desc = result.get("error_description", "Unknown error")
84
+ error = result.get("error", "Unknown")
85
+ raise ValueError(
86
+ f"Failed to acquire token: {error} - {error_desc}\n"
87
+ f"Authority: {authority_url}\n"
88
+ f"Scopes: {scopes}"
89
+ )
90
+
91
+ logger.info(f"Successfully acquired token for {self.site_url}")
92
+ return result
93
+
94
+ ctx = ClientContext(self.site_url).with_access_token(acquire_token)
95
+ logger.info("Successfully authenticated using MSAL (Modern Azure AD)")
96
+ return ctx
97
+
98
+ def get_context_with_certificate(self) -> ClientContext:
99
+ """
100
+ Get ClientContext using certificate-based authentication.
101
+ This is an alternative modern authentication method.
102
+
103
+ Returns:
104
+ Authenticated ClientContext
105
+
106
+ Raises:
107
+ ValueError: If certificate credentials are not provided
108
+ """
109
+ if not self.cert_path or not self.cert_thumbprint:
110
+ raise ValueError(
111
+ "Certificate path and thumbprint are required for cert-based auth"
112
+ )
113
+
114
+ ctx = ClientContext(self.site_url).with_client_certificate(
115
+ tenant=self.tenant_id,
116
+ client_id=self.client_id,
117
+ thumbprint=self.cert_thumbprint,
118
+ cert_path=self.cert_path
119
+ )
120
+
121
+ logger.info("Successfully authenticated using certificate")
122
+ return ctx
123
+
124
+ def get_context_legacy(self) -> ClientContext:
125
+ """
126
+ Get ClientContext using legacy ACS authentication (deprecated).
127
+ This method is included for backwards compatibility but may not work
128
+ with new tenants where ACS app-only is disabled.
129
+
130
+ Returns:
131
+ Authenticated ClientContext
132
+ """
133
+ logger.warning(
134
+ "Using legacy ACS authentication. This may fail on new tenants. "
135
+ "Consider using MSAL or certificate-based auth instead."
136
+ )
137
+
138
+ credentials = ClientCredential(self.client_id, self.client_secret)
139
+ ctx = ClientContext(self.site_url).with_credentials(credentials)
140
+
141
+ return ctx
142
+
143
+ def get_context(self, auth_method: str = "msal") -> ClientContext:
144
+ """
145
+ Get authenticated ClientContext using the specified method.
146
+
147
+ Args:
148
+ auth_method: Authentication method to use.
149
+ Options: "msal" (default), "certificate", "legacy"
150
+
151
+ Returns:
152
+ Authenticated ClientContext
153
+
154
+ Raises:
155
+ ValueError: If invalid auth method specified
156
+ """
157
+ auth_methods = {
158
+ "msal": self.get_context_with_msal,
159
+ "certificate": self.get_context_with_certificate,
160
+ "legacy": self.get_context_legacy
161
+ }
162
+
163
+ if auth_method not in auth_methods:
164
+ raise ValueError(
165
+ f"Invalid auth method: {auth_method}. "
166
+ f"Must be one of: {', '.join(auth_methods.keys())}"
167
+ )
168
+
169
+ try:
170
+ return auth_methods[auth_method]()
171
+ except Exception as e:
172
+ logger.error(f"Authentication failed with method '{auth_method}': {e}")
173
+ raise
174
+
175
+
176
+ def create_sharepoint_context() -> ClientContext:
177
+ """
178
+ Factory function to create SharePoint context from environment variables.
179
+ Automatically detects cloud environment and uses appropriate endpoints.
180
+
181
+ Environment variables required:
182
+ - SHP_SITE_URL: SharePoint site URL
183
+ - SHP_ID_APP: Azure AD application client ID
184
+ - SHP_ID_APP_SECRET: Azure AD application client secret
185
+ - SHP_TENANT_ID: Azure AD tenant ID
186
+
187
+ Optional environment variables:
188
+ - SHP_CLOUD: Cloud environment ("commercial" or "government")
189
+ Auto-detected from site URL if not specified
190
+ - SHP_AUTH_METHOD: Authentication method (msal, certificate, legacy)
191
+ - SHP_CERT_PATH: Path to certificate file
192
+ - SHP_CERT_THUMBPRINT: Certificate thumbprint
193
+
194
+ Returns:
195
+ Authenticated ClientContext
196
+
197
+ Raises:
198
+ ValueError: If required environment variables are missing
199
+ """
200
+ # Get required environment variables
201
+ site_url = os.getenv("SHP_SITE_URL")
202
+ client_id = os.getenv("SHP_ID_APP")
203
+ client_secret = os.getenv("SHP_ID_APP_SECRET")
204
+ tenant_id = os.getenv("SHP_TENANT_ID")
205
+
206
+ # Validate required variables
207
+ missing_vars = []
208
+ if not site_url:
209
+ missing_vars.append("SHP_SITE_URL")
210
+ if not client_id:
211
+ missing_vars.append("SHP_ID_APP")
212
+ if not client_secret:
213
+ missing_vars.append("SHP_ID_APP_SECRET")
214
+ if not tenant_id:
215
+ missing_vars.append("SHP_TENANT_ID")
216
+
217
+ if missing_vars:
218
+ raise ValueError(
219
+ f"Missing required environment variables: {', '.join(missing_vars)}"
220
+ )
221
+
222
+ # Detect cloud environment from site URL if not explicitly set
223
+ cloud = os.getenv("SHP_CLOUD", "").lower()
224
+ if not cloud:
225
+ # Auto-detect based on SharePoint URL
226
+ if ".sharepoint.us" in site_url:
227
+ cloud = "government"
228
+ logger.info("Auto-detected Azure US Government Cloud from site URL")
229
+ elif ".sharepoint.com" in site_url:
230
+ cloud = "commercial"
231
+ logger.info("Auto-detected Azure Commercial Cloud from site URL")
232
+ else:
233
+ # Default to government for safety
234
+ cloud = "government"
235
+ logger.warning(
236
+ f"Could not auto-detect cloud from URL: {site_url}. "
237
+ "Defaulting to US Government Cloud. Set SHP_CLOUD explicitly if needed."
238
+ )
239
+
240
+ # Get optional environment variables
241
+ auth_method = os.getenv("SHP_AUTH_METHOD", "msal")
242
+ cert_path = os.getenv("SHP_CERT_PATH")
243
+ cert_thumbprint = os.getenv("SHP_CERT_THUMBPRINT")
244
+
245
+ # Log configuration
246
+ logger.info(f"Cloud environment: {cloud}")
247
+ logger.info(f"Authentication method: {auth_method}")
248
+ logger.info(f"Site URL: {site_url}")
249
+
250
+ # Create authenticator
251
+ authenticator = SharePointAuthenticator(
252
+ site_url=site_url,
253
+ client_id=client_id,
254
+ client_secret=client_secret,
255
+ tenant_id=tenant_id,
256
+ cert_path=cert_path,
257
+ cert_thumbprint=cert_thumbprint,
258
+ cloud=cloud
259
+ )
260
+
261
+ # Try to authenticate
262
+ try:
263
+ ctx = authenticator.get_context(auth_method=auth_method)
264
+ logger.info(f"Successfully created SharePoint context using {auth_method} auth")
265
+ return ctx
266
+ except Exception as e:
267
+ logger.error(f"Failed to create SharePoint context: {e}")
268
+
269
+ # If MSAL failed and we haven't tried legacy, suggest it
270
+ if auth_method == "msal":
271
+ logger.info(
272
+ "MSAL authentication failed. If you're using an older tenant, "
273
+ "you can try setting SHP_AUTH_METHOD=legacy, but note that "
274
+ "legacy ACS authentication is deprecated and may not work on new tenants."
275
+ )
276
+
277
+ raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-sharepoint-us
3
- Version: 2.0.2
3
+ Version: 2.0.3
4
4
  Summary: SharePoint MCP Server with Modern Azure AD Authentication
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/mdev26/mcp-sharepoint-us
@@ -0,0 +1,9 @@
1
+ mcp_sharepoint/__init__.py,sha256=rm3OXtkIFtpDjVfoBPZQRy3N3w7vptvaRPEnEnDQGiY,19305
2
+ mcp_sharepoint/__main__.py,sha256=4iVDdDZx4rQ4Zo-x0RaCrT-NKeGObIz_ks3YF8di2nA,132
3
+ mcp_sharepoint/auth.py,sha256=ni0T-zcrTFuv6mPXqI49Pxk4pDUuUAAo4LGsri7ynJU,10152
4
+ mcp_sharepoint_us-2.0.3.dist-info/licenses/LICENSE,sha256=SRM8juGH4GjIqnl5rrp-P-S5mW5h2mINOPx5-wOZG6s,1112
5
+ mcp_sharepoint_us-2.0.3.dist-info/METADATA,sha256=TFaCfed-BetgpGiAQHaCc_hHub7XYAEU3eoVXqFpGEA,11379
6
+ mcp_sharepoint_us-2.0.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
7
+ mcp_sharepoint_us-2.0.3.dist-info/entry_points.txt,sha256=UZOa_7OLI41rmsErbvnSz9RahPMGQVcqZUFMphOcjbY,57
8
+ mcp_sharepoint_us-2.0.3.dist-info/top_level.txt,sha256=R6mRoWe61lz4kUSKGV6S2XVbE7825xfC_J-ouZIYpuo,15
9
+ mcp_sharepoint_us-2.0.3.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- mcp_sharepoint/__init__.py,sha256=QdMtJFpeyY_xm05R-Ly5829YJx6tzIvgVw9xCvukEt0,19843
2
- mcp_sharepoint/__main__.py,sha256=HAV6LtLss9FL5CdMcp3ssbaDe-i669Vsc90sqXCB7Mk,140
3
- mcp_sharepoint/auth.py,sha256=ihQmvPViAA5jwNNFZt3c0yAfScTADiQM1VmYpTM1EHI,8383
4
- mcp_sharepoint_us-2.0.2.dist-info/licenses/LICENSE,sha256=SRM8juGH4GjIqnl5rrp-P-S5mW5h2mINOPx5-wOZG6s,1112
5
- mcp_sharepoint_us-2.0.2.dist-info/METADATA,sha256=D0F6kjzLC_jyGh00aMU_Ukqw3MJSaFqh4jP0kNVput0,11379
6
- mcp_sharepoint_us-2.0.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
7
- mcp_sharepoint_us-2.0.2.dist-info/entry_points.txt,sha256=UZOa_7OLI41rmsErbvnSz9RahPMGQVcqZUFMphOcjbY,57
8
- mcp_sharepoint_us-2.0.2.dist-info/top_level.txt,sha256=R6mRoWe61lz4kUSKGV6S2XVbE7825xfC_J-ouZIYpuo,15
9
- mcp_sharepoint_us-2.0.2.dist-info/RECORD,,