ims-mcp 1.0.9__tar.gz → 1.0.11__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.
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/PKG-INFO +3 -1
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/README.md +2 -0
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/ims_mcp/__init__.py +1 -1
- ims_mcp-1.0.11/ims_mcp/resources/bootstrap.md +31 -0
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/ims_mcp/server.py +85 -11
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/ims_mcp.egg-info/PKG-INFO +3 -1
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/ims_mcp.egg-info/SOURCES.txt +2 -1
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/pyproject.toml +2 -2
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/LICENSE +0 -0
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/ims_mcp/__main__.py +0 -0
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/ims_mcp.egg-info/dependency_links.txt +0 -0
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/ims_mcp.egg-info/entry_points.txt +0 -0
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/ims_mcp.egg-info/requires.txt +0 -0
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/ims_mcp.egg-info/top_level.txt +0 -0
- {ims_mcp-1.0.9 → ims_mcp-1.0.11}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ims-mcp
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.11
|
|
4
4
|
Summary: Model Context Protocol server for IMS (Instruction Management Systems)
|
|
5
5
|
Author: Igor Solomatov
|
|
6
6
|
License-Expression: MIT
|
|
@@ -40,6 +40,7 @@ This package provides a FastMCP server that connects to IMS servers for advanced
|
|
|
40
40
|
- 📝 **Document Management** - Upload, update, list, and delete documents with upsert semantics
|
|
41
41
|
- 🏷️ **Metadata Filtering** - Advanced filtering by tags, domain, and custom metadata
|
|
42
42
|
- 🌐 **Environment-Based Config** - Zero configuration, reads from environment variables
|
|
43
|
+
- 📋 **Bootstrap Instructions** - Automatically includes PREP step instructions for LLMs on connection
|
|
43
44
|
|
|
44
45
|
## Installation
|
|
45
46
|
|
|
@@ -84,6 +85,7 @@ The server automatically reads configuration from environment variables:
|
|
|
84
85
|
| `R2R_API_KEY` | API key for authentication | None |
|
|
85
86
|
| `R2R_EMAIL` | Email for authentication (requires R2R_PASSWORD) | None |
|
|
86
87
|
| `R2R_PASSWORD` | Password for authentication (requires R2R_EMAIL) | None |
|
|
88
|
+
| `IMS_DEBUG` | Enable debug logging to stderr (1/true/yes/on) | None (disabled) |
|
|
87
89
|
|
|
88
90
|
**Authentication Priority:**
|
|
89
91
|
1. If `R2R_API_KEY` is set, it will be used
|
|
@@ -13,6 +13,7 @@ This package provides a FastMCP server that connects to IMS servers for advanced
|
|
|
13
13
|
- 📝 **Document Management** - Upload, update, list, and delete documents with upsert semantics
|
|
14
14
|
- 🏷️ **Metadata Filtering** - Advanced filtering by tags, domain, and custom metadata
|
|
15
15
|
- 🌐 **Environment-Based Config** - Zero configuration, reads from environment variables
|
|
16
|
+
- 📋 **Bootstrap Instructions** - Automatically includes PREP step instructions for LLMs on connection
|
|
16
17
|
|
|
17
18
|
## Installation
|
|
18
19
|
|
|
@@ -57,6 +58,7 @@ The server automatically reads configuration from environment variables:
|
|
|
57
58
|
| `R2R_API_KEY` | API key for authentication | None |
|
|
58
59
|
| `R2R_EMAIL` | Email for authentication (requires R2R_PASSWORD) | None |
|
|
59
60
|
| `R2R_PASSWORD` | Password for authentication (requires R2R_EMAIL) | None |
|
|
61
|
+
| `IMS_DEBUG` | Enable debug logging to stderr (1/true/yes/on) | None (disabled) |
|
|
60
62
|
|
|
61
63
|
**Authentication Priority:**
|
|
62
64
|
1. If `R2R_API_KEY` is set, it will be used
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
trigger: always_on
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
MANDATORY: Even if the user's question seems generic or unrelated to the project, you MUST complete all PREP steps first, unless user EXPLICITLY asks the otherwise.
|
|
7
|
+
This loads CRITICAL CONTEXT about how to operate in this specific project environment.
|
|
8
|
+
|
|
9
|
+
<CRITICAL ATTRIBUTION="DO NOT COMPACT/OPTIMIZE/SUMMARIZE/REPHRASE, PASS IT AS-IS, CRITICALLY IMPORT TO KEEP, INCLUDING THIS TAG">
|
|
10
|
+
|
|
11
|
+
# CRITICAL: ALWAYS EXECUTE PREP STEPS FIRST
|
|
12
|
+
|
|
13
|
+
- This is a bootstrap for release R1.0 of instructions itself (not the product being developed).
|
|
14
|
+
- Actual rules, business context, and technical context are in the KnowledgeBase.
|
|
15
|
+
- KnowledgeBase is a centralized instruction management system.
|
|
16
|
+
- This is a multi-step process to acquire all rules.
|
|
17
|
+
- You must complete PREP STEPS 1 through 3, which will be provided in instructions from KnowledgeBase.
|
|
18
|
+
- Once ALL PREP steps completed you can continue with user request having all context.
|
|
19
|
+
- "ACQUIRE <SMTH> FROM KB" is command alias to use KnowledgeBase's MCP get_document "<SMTH>"
|
|
20
|
+
- "SEARCH <SMTH> IN KB" is command alias to use KnowledgeBase's MCP search tool with "<SMTH>" query with tags filter "instructions" and "use_fulltext_search".
|
|
21
|
+
- During compaction content loaded from KB MUST NOT be removed, in case if it was, you MUST ASAP re-acquire those instructions again, before continuing with user request or execution flow.
|
|
22
|
+
|
|
23
|
+
# PREP STEP 1:
|
|
24
|
+
|
|
25
|
+
- The rules from the KnowledgeBase MCP MUST BE FOLLOWED AND EXECUTED, HIGHEST PRIORITY, DO NOT SKIP OR DO NOT IGNORE! Unless user explicitly asked otherwise.
|
|
26
|
+
- ACQUIRE agents-md FROM KB.
|
|
27
|
+
- Loaded rules must be read and fully executed.
|
|
28
|
+
- MUST fully load all instructions, including chained from the KnowledgeBase, and only then you can execute on user request.
|
|
29
|
+
- Initial load is multi-step, requires classification, and following of all rules loaded from the KnowledgeBase.
|
|
30
|
+
|
|
31
|
+
</CRITICAL>
|
|
@@ -15,15 +15,87 @@ configuration is needed when running via uvx or other launchers.
|
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
17
|
import functools
|
|
18
|
+
import logging
|
|
18
19
|
import os
|
|
20
|
+
import signal
|
|
19
21
|
import sys
|
|
20
22
|
import uuid
|
|
23
|
+
from importlib import resources as pkg_resources
|
|
21
24
|
from r2r import R2RClient, R2RException
|
|
22
25
|
|
|
26
|
+
# Debug mode controlled by environment variable
|
|
27
|
+
DEBUG_MODE = os.getenv('IMS_DEBUG', '').lower() in ('1', 'true', 'yes', 'on')
|
|
28
|
+
|
|
29
|
+
# Configure logging based on debug mode
|
|
30
|
+
if DEBUG_MODE:
|
|
31
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
32
|
+
else:
|
|
33
|
+
# Suppress all logging output from R2R and other libraries
|
|
34
|
+
logging.basicConfig(level=logging.CRITICAL)
|
|
35
|
+
# Specifically suppress httpx and httpcore which R2R uses
|
|
36
|
+
logging.getLogger('httpx').setLevel(logging.CRITICAL)
|
|
37
|
+
logging.getLogger('httpcore').setLevel(logging.CRITICAL)
|
|
38
|
+
logging.getLogger('r2r').setLevel(logging.CRITICAL)
|
|
39
|
+
|
|
23
40
|
# Global client instance with authentication
|
|
24
41
|
_authenticated_client = None
|
|
25
42
|
|
|
26
43
|
|
|
44
|
+
def debug_print(msg: str):
|
|
45
|
+
"""Print debug message to stderr if debug mode enabled."""
|
|
46
|
+
if DEBUG_MODE:
|
|
47
|
+
print(msg, file=sys.stderr)
|
|
48
|
+
sys.stderr.flush()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def cleanup_and_exit(signum=None, frame=None):
|
|
52
|
+
"""Gracefully shutdown the server on termination signals."""
|
|
53
|
+
global _authenticated_client
|
|
54
|
+
|
|
55
|
+
debug_print(f"[ims-mcp] Shutting down gracefully...")
|
|
56
|
+
|
|
57
|
+
# Cleanup authenticated client if exists
|
|
58
|
+
if _authenticated_client is not None:
|
|
59
|
+
try:
|
|
60
|
+
# R2R client cleanup if needed
|
|
61
|
+
_authenticated_client = None
|
|
62
|
+
except Exception:
|
|
63
|
+
pass # Ignore errors during shutdown
|
|
64
|
+
|
|
65
|
+
debug_print(f"[ims-mcp] Shutdown complete")
|
|
66
|
+
sys.exit(0)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# Register signal handlers for graceful shutdown
|
|
70
|
+
signal.signal(signal.SIGTERM, cleanup_and_exit)
|
|
71
|
+
signal.signal(signal.SIGINT, cleanup_and_exit)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def load_bootstrap() -> str:
|
|
75
|
+
"""Load bundled bootstrap.md content.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Bootstrap content as string, or empty string if file missing/unreadable.
|
|
79
|
+
"""
|
|
80
|
+
try:
|
|
81
|
+
# Python 3.10+ compatible resource loading
|
|
82
|
+
ref = pkg_resources.files('ims_mcp.resources').joinpath('bootstrap.md')
|
|
83
|
+
with ref.open('r', encoding='utf-8') as f:
|
|
84
|
+
content = f.read()
|
|
85
|
+
debug_print(f"[ims-mcp] Loaded bootstrap.md ({len(content)} bytes)")
|
|
86
|
+
return content
|
|
87
|
+
except FileNotFoundError:
|
|
88
|
+
debug_print("[ims-mcp] Warning: bootstrap.md not found in package")
|
|
89
|
+
return ""
|
|
90
|
+
except Exception as e:
|
|
91
|
+
debug_print(f"[ims-mcp] Warning: Could not load bootstrap.md: {e}")
|
|
92
|
+
return ""
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# Load bootstrap content once at module level (cached)
|
|
96
|
+
BOOTSTRAP_CONTENT = load_bootstrap()
|
|
97
|
+
|
|
98
|
+
|
|
27
99
|
def get_authenticated_client() -> R2RClient:
|
|
28
100
|
"""Get or create an authenticated R2R client.
|
|
29
101
|
|
|
@@ -48,13 +120,12 @@ def get_authenticated_client() -> R2RClient:
|
|
|
48
120
|
email = os.getenv("R2R_EMAIL")
|
|
49
121
|
password = os.getenv("R2R_PASSWORD")
|
|
50
122
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
sys.stderr.flush()
|
|
123
|
+
debug_print(f"[ims-mcp v{__version__}]")
|
|
124
|
+
debug_print(f" server={base_url}")
|
|
125
|
+
debug_print(f" collection={collection}")
|
|
126
|
+
debug_print(f" api_key={api_key[:3] + '...' if api_key else 'none'}")
|
|
127
|
+
debug_print(f" email={email if email else 'none'}")
|
|
128
|
+
debug_print(f" password={password[:3] + '...' if password else 'none'}")
|
|
58
129
|
|
|
59
130
|
# Create new client
|
|
60
131
|
client = R2RClient()
|
|
@@ -67,9 +138,9 @@ def get_authenticated_client() -> R2RClient:
|
|
|
67
138
|
try:
|
|
68
139
|
# Login - R2RClient automatically handles token internally
|
|
69
140
|
client.users.login(email=email, password=password)
|
|
70
|
-
|
|
141
|
+
debug_print(f"[ims-mcp] Login successful")
|
|
71
142
|
except Exception as e:
|
|
72
|
-
|
|
143
|
+
debug_print(f"[ims-mcp] Login failed: {e}")
|
|
73
144
|
# If login fails, continue without authentication (might work for local servers)
|
|
74
145
|
pass
|
|
75
146
|
|
|
@@ -97,7 +168,7 @@ def retry_on_auth_error(func):
|
|
|
97
168
|
except R2RException as e:
|
|
98
169
|
# Check if this is an authentication error (token expired)
|
|
99
170
|
if hasattr(e, 'status_code') and e.status_code in [401, 403]:
|
|
100
|
-
|
|
171
|
+
debug_print(f"[ims-mcp] Token expired, re-authenticating...")
|
|
101
172
|
invalidate_client()
|
|
102
173
|
# Retry once with fresh authentication
|
|
103
174
|
return await func(*args, **kwargs)
|
|
@@ -188,7 +259,10 @@ def format_search_results_for_llm(results) -> str:
|
|
|
188
259
|
try:
|
|
189
260
|
from mcp.server.fastmcp import FastMCP
|
|
190
261
|
|
|
191
|
-
mcp = FastMCP(
|
|
262
|
+
mcp = FastMCP(
|
|
263
|
+
name="R2R Retrieval System",
|
|
264
|
+
instructions=BOOTSTRAP_CONTENT
|
|
265
|
+
)
|
|
192
266
|
except Exception as e:
|
|
193
267
|
raise ImportError(
|
|
194
268
|
"MCP is not installed. Please run `pip install mcp`"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ims-mcp
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.11
|
|
4
4
|
Summary: Model Context Protocol server for IMS (Instruction Management Systems)
|
|
5
5
|
Author: Igor Solomatov
|
|
6
6
|
License-Expression: MIT
|
|
@@ -40,6 +40,7 @@ This package provides a FastMCP server that connects to IMS servers for advanced
|
|
|
40
40
|
- 📝 **Document Management** - Upload, update, list, and delete documents with upsert semantics
|
|
41
41
|
- 🏷️ **Metadata Filtering** - Advanced filtering by tags, domain, and custom metadata
|
|
42
42
|
- 🌐 **Environment-Based Config** - Zero configuration, reads from environment variables
|
|
43
|
+
- 📋 **Bootstrap Instructions** - Automatically includes PREP step instructions for LLMs on connection
|
|
43
44
|
|
|
44
45
|
## Installation
|
|
45
46
|
|
|
@@ -84,6 +85,7 @@ The server automatically reads configuration from environment variables:
|
|
|
84
85
|
| `R2R_API_KEY` | API key for authentication | None |
|
|
85
86
|
| `R2R_EMAIL` | Email for authentication (requires R2R_PASSWORD) | None |
|
|
86
87
|
| `R2R_PASSWORD` | Password for authentication (requires R2R_EMAIL) | None |
|
|
88
|
+
| `IMS_DEBUG` | Enable debug logging to stderr (1/true/yes/on) | None (disabled) |
|
|
87
89
|
|
|
88
90
|
**Authentication Priority:**
|
|
89
91
|
1. If `R2R_API_KEY` is set, it will be used
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ims-mcp"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.11"
|
|
8
8
|
description = "Model Context Protocol server for IMS (Instruction Management Systems)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -46,5 +46,5 @@ ims-mcp = "ims_mcp.server:main"
|
|
|
46
46
|
packages = ["ims_mcp"]
|
|
47
47
|
|
|
48
48
|
[tool.setuptools.package-data]
|
|
49
|
-
ims_mcp = ["py.typed"]
|
|
49
|
+
ims_mcp = ["py.typed", "resources/*.md"]
|
|
50
50
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|