ims-mcp 1.0.3__tar.gz → 1.0.5__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ims-mcp
3
- Version: 1.0.3
3
+ Version: 1.0.5
4
4
  Summary: Model Context Protocol server for IMS (Instruction Management Systems)
5
5
  Author: Igor Solomatov
6
6
  License-Expression: MIT
@@ -229,13 +229,16 @@ List documents with pagination and optional tag filtering.
229
229
  - `offset` (int, optional): Documents to skip (default: 0)
230
230
  - `limit` (int, optional): Max documents (default: 100)
231
231
  - `document_ids` (list[str], optional): Specific IDs to retrieve
232
- - `compact_view` (bool, optional): Show only ID and title (default: False)
232
+ - `compact_view` (bool, optional): Show only ID and title (default: True)
233
233
  - `tags` (list[str], optional): Filter by tags (e.g., `["agents", "r1"]`)
234
234
  - `match_all_tags` (bool, optional): If True, document must have ALL tags; if False (default), document must have ANY tag
235
235
 
236
236
  **Examples:**
237
237
  ```python
238
- # List all documents
238
+ # List all documents (compact view - ID and title only)
239
+ list_documents(offset=0, limit=10)
240
+
241
+ # List with full details
239
242
  list_documents(offset=0, limit=10, compact_view=False)
240
243
 
241
244
  # Filter by tags (ANY mode - documents with "research" OR "ml")
@@ -202,13 +202,16 @@ List documents with pagination and optional tag filtering.
202
202
  - `offset` (int, optional): Documents to skip (default: 0)
203
203
  - `limit` (int, optional): Max documents (default: 100)
204
204
  - `document_ids` (list[str], optional): Specific IDs to retrieve
205
- - `compact_view` (bool, optional): Show only ID and title (default: False)
205
+ - `compact_view` (bool, optional): Show only ID and title (default: True)
206
206
  - `tags` (list[str], optional): Filter by tags (e.g., `["agents", "r1"]`)
207
207
  - `match_all_tags` (bool, optional): If True, document must have ALL tags; if False (default), document must have ANY tag
208
208
 
209
209
  **Examples:**
210
210
  ```python
211
- # List all documents
211
+ # List all documents (compact view - ID and title only)
212
+ list_documents(offset=0, limit=10)
213
+
214
+ # List with full details
212
215
  list_documents(offset=0, limit=10, compact_view=False)
213
216
 
214
217
  # Filter by tags (ANY mode - documents with "research" OR "ml")
@@ -11,7 +11,7 @@ Environment Variables:
11
11
  Note: Environment variables use R2R_ prefix for compatibility with underlying R2R SDK.
12
12
  """
13
13
 
14
- __version__ = "1.0.3"
14
+ __version__ = "1.0.5"
15
15
  __author__ = "Igor Solomatov"
16
16
 
17
17
  from ims_mcp.server import mcp
@@ -14,10 +14,11 @@ The R2RClient automatically reads these environment variables, so no manual
14
14
  configuration is needed when running via uvx or other launchers.
15
15
  """
16
16
 
17
+ import functools
17
18
  import os
18
19
  import sys
19
20
  import uuid
20
- from r2r import R2RClient
21
+ from r2r import R2RClient, R2RException
21
22
 
22
23
  # Global client instance with authentication
23
24
  _authenticated_client = None
@@ -76,6 +77,34 @@ def get_authenticated_client() -> R2RClient:
76
77
  return client
77
78
 
78
79
 
80
+ def retry_on_auth_error(func):
81
+ """Decorator to handle token expiry and automatically re-authenticate.
82
+
83
+ When R2R server restarts, all authentication tokens are invalidated.
84
+ This decorator catches 401/403 errors, invalidates the cached client,
85
+ re-authenticates, and retries the request once.
86
+ """
87
+ def invalidate_client():
88
+ """Invalidate cached client to force re-authentication."""
89
+ global _authenticated_client
90
+ _authenticated_client = None
91
+
92
+ @functools.wraps(func)
93
+ async def wrapper(*args, **kwargs):
94
+ try:
95
+ return await func(*args, **kwargs)
96
+ except R2RException as e:
97
+ # Check if this is an authentication error (token expired)
98
+ if hasattr(e, 'status_code') and e.status_code in [401, 403]:
99
+ print(f"[ims-mcp] Token expired, re-authenticating...", file=sys.stderr)
100
+ invalidate_client()
101
+ # Retry once with fresh authentication
102
+ return await func(*args, **kwargs)
103
+ # Re-raise non-auth errors
104
+ raise
105
+ return wrapper
106
+
107
+
79
108
  def id_to_shorthand(id: str) -> str:
80
109
  """Convert a full ID to shortened version for display."""
81
110
  return str(id)[:7]
@@ -167,6 +196,7 @@ except Exception as e:
167
196
 
168
197
  # Search tool with filtering support
169
198
  @mcp.tool()
199
+ @retry_on_auth_error
170
200
  async def search(
171
201
  query: str,
172
202
  filters: dict | None = None,
@@ -216,6 +246,7 @@ async def search(
216
246
 
217
247
  # RAG query tool with filtering and generation config
218
248
  @mcp.tool()
249
+ @retry_on_auth_error
219
250
  async def rag(
220
251
  query: str,
221
252
  filters: dict | None = None,
@@ -270,6 +301,7 @@ async def rag(
270
301
 
271
302
  # Document upload tool with upsert semantics
272
303
  @mcp.tool()
304
+ @retry_on_auth_error
273
305
  async def put_document(
274
306
  content: str,
275
307
  title: str,
@@ -337,11 +369,12 @@ async def put_document(
337
369
 
338
370
  # List documents tool
339
371
  @mcp.tool()
372
+ @retry_on_auth_error
340
373
  async def list_documents(
341
374
  offset: float = 0, # Use float to accept JSON "number" type, convert to int internally
342
375
  limit: float = 100, # Use float to accept JSON "number" type, convert to int internally
343
376
  document_ids: list[str] | None = None,
344
- compact_view: bool = False,
377
+ compact_view: bool = True,
345
378
  tags: list[str] | None = None,
346
379
  match_all_tags: bool = False,
347
380
  ) -> str:
@@ -352,7 +385,7 @@ async def list_documents(
352
385
  offset: Number of documents to skip (default: 0)
353
386
  limit: Maximum number of documents to return (default: 100, max: 100)
354
387
  document_ids: Optional list of specific document IDs to retrieve
355
- compact_view: Show only ID and title (default: False - shows all details)
388
+ compact_view: Show only ID and title (default: True - compact view)
356
389
  tags: Optional list of tags to filter by (e.g., ["agents", "r1"])
357
390
  match_all_tags: If True, document must have ALL tags; if False (default), document must have ANY tag
358
391
 
@@ -440,6 +473,7 @@ async def list_documents(
440
473
 
441
474
  # Get document tool
442
475
  @mcp.tool()
476
+ @retry_on_auth_error
443
477
  async def get_document(
444
478
  document_id: str | None = None,
445
479
  title: str | None = None,
@@ -530,6 +564,7 @@ async def get_document(
530
564
 
531
565
  # Delete document tool
532
566
  @mcp.tool()
567
+ @retry_on_auth_error
533
568
  async def delete_document(document_id: str) -> str:
534
569
  """
535
570
  Delete a document by ID
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ims-mcp
3
- Version: 1.0.3
3
+ Version: 1.0.5
4
4
  Summary: Model Context Protocol server for IMS (Instruction Management Systems)
5
5
  Author: Igor Solomatov
6
6
  License-Expression: MIT
@@ -229,13 +229,16 @@ List documents with pagination and optional tag filtering.
229
229
  - `offset` (int, optional): Documents to skip (default: 0)
230
230
  - `limit` (int, optional): Max documents (default: 100)
231
231
  - `document_ids` (list[str], optional): Specific IDs to retrieve
232
- - `compact_view` (bool, optional): Show only ID and title (default: False)
232
+ - `compact_view` (bool, optional): Show only ID and title (default: True)
233
233
  - `tags` (list[str], optional): Filter by tags (e.g., `["agents", "r1"]`)
234
234
  - `match_all_tags` (bool, optional): If True, document must have ALL tags; if False (default), document must have ANY tag
235
235
 
236
236
  **Examples:**
237
237
  ```python
238
- # List all documents
238
+ # List all documents (compact view - ID and title only)
239
+ list_documents(offset=0, limit=10)
240
+
241
+ # List with full details
239
242
  list_documents(offset=0, limit=10, compact_view=False)
240
243
 
241
244
  # Filter by tags (ANY mode - documents with "research" OR "ml")
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ims-mcp"
7
- version = "1.0.3"
7
+ version = "1.0.5"
8
8
  description = "Model Context Protocol server for IMS (Instruction Management Systems)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes
File without changes