ims-mcp 1.0.1__py3-none-any.whl → 1.0.2__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.
ims_mcp/__init__.py CHANGED
@@ -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.1"
14
+ __version__ = "1.0.2"
15
15
  __author__ = "Igor Solomatov"
16
16
 
17
17
  from ims_mcp.server import mcp
ims_mcp/server.py CHANGED
@@ -7,14 +7,58 @@ Environment Variables:
7
7
  R2R_API_BASE or R2R_BASE_URL: R2R server URL (default: http://localhost:7272)
8
8
  R2R_COLLECTION: Collection name for queries (optional, uses server default)
9
9
  R2R_API_KEY: API key for authentication (optional)
10
+ R2R_EMAIL: Email for authentication (optional, requires R2R_PASSWORD)
11
+ R2R_PASSWORD: Password for authentication (optional, requires R2R_EMAIL)
10
12
 
11
13
  The R2RClient automatically reads these environment variables, so no manual
12
14
  configuration is needed when running via uvx or other launchers.
13
15
  """
14
16
 
17
+ import os
15
18
  import uuid
16
19
  from r2r import R2RClient
17
20
 
21
+ # Global client instance with authentication
22
+ _authenticated_client = None
23
+
24
+
25
+ def get_authenticated_client() -> R2RClient:
26
+ """Get or create an authenticated R2R client.
27
+
28
+ This function handles authentication using either:
29
+ 1. API key (R2R_API_KEY) - preferred method
30
+ 2. Email/password (R2R_EMAIL + R2R_PASSWORD) - fallback method
31
+
32
+ Returns:
33
+ Authenticated R2RClient instance
34
+ """
35
+ global _authenticated_client
36
+
37
+ # If client already exists and is authenticated, reuse it
38
+ if _authenticated_client is not None:
39
+ return _authenticated_client
40
+
41
+ # Create new client
42
+ client = R2RClient()
43
+
44
+ # Check for email/password authentication
45
+ email = os.getenv("R2R_EMAIL")
46
+ password = os.getenv("R2R_PASSWORD")
47
+
48
+ if email and password:
49
+ try:
50
+ # Login to get access token
51
+ result = client.users.login(email=email, password=password)
52
+ # Set the access token for subsequent requests
53
+ client.access_token = result.results.access_token.token
54
+ except Exception as e:
55
+ # If login fails, continue without authentication (might work for local servers)
56
+ pass
57
+
58
+ # Cache the client for reuse
59
+ _authenticated_client = client
60
+ return client
61
+
18
62
 
19
63
  def id_to_shorthand(id: str) -> str:
20
64
  """Convert a full ID to shortened version for display."""
@@ -127,7 +171,7 @@ async def search(
127
171
  Returns:
128
172
  Formatted search results from the knowledge base
129
173
  """
130
- client = R2RClient()
174
+ client = get_authenticated_client()
131
175
 
132
176
  # Only build search_settings if user provided any parameters
133
177
  # This preserves original behavior: search("query") → search(query=query) with NO search_settings
@@ -178,7 +222,7 @@ async def rag(
178
222
  Returns:
179
223
  Generated answer from RAG
180
224
  """
181
- client = R2RClient()
225
+ client = get_authenticated_client()
182
226
 
183
227
  # Only build configs if user provided parameters
184
228
  # This preserves original behavior: rag("query") → rag(query=query) with NO configs
@@ -228,7 +272,7 @@ async def put_document(
228
272
  Returns:
229
273
  Status message with document_id and operation type
230
274
  """
231
- client = R2RClient()
275
+ client = get_authenticated_client()
232
276
 
233
277
  # Build metadata with title
234
278
  final_metadata = {"title": title}
@@ -299,7 +343,7 @@ async def list_documents(
299
343
  Returns:
300
344
  Formatted list of documents
301
345
  """
302
- client = R2RClient()
346
+ client = get_authenticated_client()
303
347
 
304
348
  # Build kwargs for list call
305
349
  kwargs = {"offset": int(offset), "limit": min(int(limit), 100)} # Convert to int, cap at 100
@@ -394,7 +438,7 @@ async def get_document(
394
438
  Returns:
395
439
  Formatted document details
396
440
  """
397
- client = R2RClient()
441
+ client = get_authenticated_client()
398
442
 
399
443
  # Validate that at least one parameter is provided
400
444
  if not document_id and not title:
@@ -480,7 +524,7 @@ async def delete_document(document_id: str) -> str:
480
524
  Returns:
481
525
  Status message confirming deletion or describing error
482
526
  """
483
- client = R2RClient()
527
+ client = get_authenticated_client()
484
528
 
485
529
  try:
486
530
  # Delete the document
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ims-mcp
3
- Version: 1.0.1
3
+ Version: 1.0.2
4
4
  Summary: Model Context Protocol server for IMS (Instruction Management Systems)
5
5
  Author: Igor Solomatov
6
6
  License-Expression: MIT
@@ -82,6 +82,13 @@ The server automatically reads configuration from environment variables:
82
82
  | `R2R_API_BASE` or `R2R_BASE_URL` | IMS server URL | `http://localhost:7272` |
83
83
  | `R2R_COLLECTION` | Collection name for queries | Server default |
84
84
  | `R2R_API_KEY` | API key for authentication | None |
85
+ | `R2R_EMAIL` | Email for authentication (requires R2R_PASSWORD) | None |
86
+ | `R2R_PASSWORD` | Password for authentication (requires R2R_EMAIL) | None |
87
+
88
+ **Authentication Priority:**
89
+ 1. If `R2R_API_KEY` is set, it will be used
90
+ 2. If `R2R_EMAIL` and `R2R_PASSWORD` are set, they will be used to login and obtain an access token
91
+ 3. If neither is set, the client will attempt unauthenticated access (works for local servers)
85
92
 
86
93
  **Note:** Environment variables use `R2R_` prefix for compatibility with the underlying R2R SDK.
87
94
 
@@ -89,6 +96,8 @@ The server automatically reads configuration from environment variables:
89
96
 
90
97
  ### Cursor IDE
91
98
 
99
+ **Local server (no authentication):**
100
+
92
101
  Add to `.cursor/mcp.json`:
93
102
 
94
103
  ```json
@@ -106,6 +115,25 @@ Add to `.cursor/mcp.json`:
106
115
  }
107
116
  ```
108
117
 
118
+ **Remote server (with email/password authentication):**
119
+
120
+ ```json
121
+ {
122
+ "mcpServers": {
123
+ "KnowledgeBase": {
124
+ "command": "uvx",
125
+ "args": ["ims-mcp"],
126
+ "env": {
127
+ "R2R_API_BASE": "https://your-server.example.com/",
128
+ "R2R_COLLECTION": "your-collection",
129
+ "R2R_EMAIL": "your-email@example.com",
130
+ "R2R_PASSWORD": "your-password"
131
+ }
132
+ }
133
+ }
134
+ }
135
+ ```
136
+
109
137
  ### Claude Desktop
110
138
 
111
139
  Add to Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
@@ -0,0 +1,9 @@
1
+ ims_mcp/__init__.py,sha256=_6NlDOhSJOSX3jaL2jl2rXydaa2CWsV6pN1BCrYnOtw,631
2
+ ims_mcp/__main__.py,sha256=z4P1aCVfOgS3cTM2wgJd2pxjMmKCkGkiqYDRGgrspxw,191
3
+ ims_mcp/server.py,sha256=QOjniyXYYcZVeUDhD_w73NLBWE2KUejOTp4vqawubMg,20925
4
+ ims_mcp-1.0.2.dist-info/licenses/LICENSE,sha256=4d1dlH04mbnN3ya4lybcVOUwljRHGy-aSc9MYqGYW44,2534
5
+ ims_mcp-1.0.2.dist-info/METADATA,sha256=40x-xkXd7POWXBB-8Lg0x44-p-Nl5oODsE9V6nh-oi8,9200
6
+ ims_mcp-1.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ ims_mcp-1.0.2.dist-info/entry_points.txt,sha256=xCH9I8g1pTTEqrfjnE-ANHaZo4W6EBJVy0Lg5z8SaIQ,48
8
+ ims_mcp-1.0.2.dist-info/top_level.txt,sha256=wEXA33qFr_eov3S1PY2OF6EQBA2rtAWB_ZNJOzNNQuM,8
9
+ ims_mcp-1.0.2.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- ims_mcp/__init__.py,sha256=dIRAdqSZq-o4id0nSxuiW276aWMGIaqRgJdXHOuFeZE,631
2
- ims_mcp/__main__.py,sha256=z4P1aCVfOgS3cTM2wgJd2pxjMmKCkGkiqYDRGgrspxw,191
3
- ims_mcp/server.py,sha256=Gk3-R8g6E3ULxuMCCfNmqpAa6_cw4boiy5WTWO5smqc,19384
4
- ims_mcp-1.0.1.dist-info/licenses/LICENSE,sha256=4d1dlH04mbnN3ya4lybcVOUwljRHGy-aSc9MYqGYW44,2534
5
- ims_mcp-1.0.1.dist-info/METADATA,sha256=UiLxBGHePFVUvQXaVGZ_a08I7ZWIoCcoNBdv2_5M6xU,8350
6
- ims_mcp-1.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
- ims_mcp-1.0.1.dist-info/entry_points.txt,sha256=xCH9I8g1pTTEqrfjnE-ANHaZo4W6EBJVy0Lg5z8SaIQ,48
8
- ims_mcp-1.0.1.dist-info/top_level.txt,sha256=wEXA33qFr_eov3S1PY2OF6EQBA2rtAWB_ZNJOzNNQuM,8
9
- ims_mcp-1.0.1.dist-info/RECORD,,