@rishibhushan/jenkins-mcp-server 1.1.0 → 1.1.3
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.
- package/bin/jenkins-mcp.js +357 -17
- package/package.json +6 -4
- package/pyproject.toml +190 -0
- package/src/jenkins_mcp_server/jenkins_client.py +14 -12
- package/src/jenkins_mcp_server/server.py +19 -3
- package/src/jenkins_mcp_server/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/jenkins_mcp_server/__pycache__/__main__.cpython-313.pyc +0 -0
- package/src/jenkins_mcp_server/__pycache__/config.cpython-313.pyc +0 -0
- package/src/jenkins_mcp_server/__pycache__/jenkins_client.cpython-313.pyc +0 -0
- package/src/jenkins_mcp_server/__pycache__/server.cpython-313.pyc +0 -0
- package/src/jenkins_mcp_server.egg-info/PKG-INFO +0 -624
- package/src/jenkins_mcp_server.egg-info/SOURCES.txt +0 -13
- package/src/jenkins_mcp_server.egg-info/dependency_links.txt +0 -1
- package/src/jenkins_mcp_server.egg-info/entry_points.txt +0 -2
- package/src/jenkins_mcp_server.egg-info/requires.txt +0 -20
- package/src/jenkins_mcp_server.egg-info/top_level.txt +0 -1
|
@@ -40,12 +40,14 @@ class JenkinsClient:
|
|
|
40
40
|
timeout support.
|
|
41
41
|
"""
|
|
42
42
|
|
|
43
|
-
def __init__(self, settings: Optional[JenkinsSettings] = None):
|
|
43
|
+
def __init__(self, settings: Optional[JenkinsSettings] = None, test_connection: bool = False):
|
|
44
44
|
"""
|
|
45
45
|
Initialize Jenkins client.
|
|
46
46
|
|
|
47
47
|
Args:
|
|
48
48
|
settings: JenkinsSettings instance. If None, uses default settings.
|
|
49
|
+
test_connection: If True, test connection during initialization.
|
|
50
|
+
Set to False for MCP list_resources to avoid blocking.
|
|
49
51
|
|
|
50
52
|
Raises:
|
|
51
53
|
JenkinsConnectionError: If unable to connect to Jenkins
|
|
@@ -72,8 +74,10 @@ class JenkinsClient:
|
|
|
72
74
|
# Cache for python-jenkins server instance
|
|
73
75
|
self._server: Optional[jenkins.Jenkins] = None
|
|
74
76
|
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
+
# Only test connection if explicitly requested
|
|
78
|
+
# This prevents blocking during MCP initialization
|
|
79
|
+
if test_connection:
|
|
80
|
+
self._test_connection()
|
|
77
81
|
|
|
78
82
|
def _test_connection(self) -> None:
|
|
79
83
|
"""Test connection to Jenkins server (with configurable timeout)"""
|
|
@@ -475,12 +479,16 @@ class JenkinsClient:
|
|
|
475
479
|
_default_client: Optional[JenkinsClient] = None
|
|
476
480
|
|
|
477
481
|
|
|
478
|
-
def get_jenkins_client(
|
|
482
|
+
def get_jenkins_client(
|
|
483
|
+
settings: Optional[JenkinsSettings] = None,
|
|
484
|
+
test_connection: bool = False
|
|
485
|
+
) -> JenkinsClient:
|
|
479
486
|
"""
|
|
480
487
|
Get Jenkins client instance.
|
|
481
488
|
|
|
482
489
|
Args:
|
|
483
490
|
settings: Optional JenkinsSettings. If None, uses default settings.
|
|
491
|
+
test_connection: If True, test connection during initialization.
|
|
484
492
|
|
|
485
493
|
Returns:
|
|
486
494
|
JenkinsClient instance
|
|
@@ -492,16 +500,10 @@ def get_jenkins_client(settings: Optional[JenkinsSettings] = None) -> JenkinsCli
|
|
|
492
500
|
|
|
493
501
|
if settings is not None:
|
|
494
502
|
# Always create new client with custom settings
|
|
495
|
-
return JenkinsClient(settings)
|
|
503
|
+
return JenkinsClient(settings, test_connection=test_connection)
|
|
496
504
|
|
|
497
505
|
# Use cached default client
|
|
498
506
|
if _default_client is None:
|
|
499
|
-
_default_client = JenkinsClient()
|
|
507
|
+
_default_client = JenkinsClient(test_connection=test_connection)
|
|
500
508
|
|
|
501
509
|
return _default_client
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
def reset_default_client() -> None:
|
|
505
|
-
"""Reset the default client (useful for testing or reconfiguration)"""
|
|
506
|
-
global _default_client
|
|
507
|
-
_default_client = None
|
|
@@ -120,10 +120,15 @@ async def handle_list_resources() -> list[types.Resource]:
|
|
|
120
120
|
"""
|
|
121
121
|
List available Jenkins resources.
|
|
122
122
|
Each job is exposed as a resource with jenkins:// URI scheme.
|
|
123
|
+
|
|
124
|
+
Enhanced with timeout to prevent MCP initialization delays.
|
|
123
125
|
"""
|
|
124
126
|
try:
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
# Wrap in async timeout to prevent blocking MCP initialization
|
|
128
|
+
async with asyncio.timeout(3): # 3 second timeout
|
|
129
|
+
client = get_jenkins_client(get_settings())
|
|
130
|
+
# Run blocking get_jobs() in thread pool
|
|
131
|
+
jobs = await asyncio.to_thread(client.get_jobs)
|
|
127
132
|
|
|
128
133
|
return [
|
|
129
134
|
types.Resource(
|
|
@@ -134,13 +139,24 @@ async def handle_list_resources() -> list[types.Resource]:
|
|
|
134
139
|
)
|
|
135
140
|
for job in jobs
|
|
136
141
|
]
|
|
142
|
+
except asyncio.TimeoutError:
|
|
143
|
+
# Jenkins server not reachable (probably not on VPN/corporate network)
|
|
144
|
+
logger.warning("Jenkins server not reachable within 3 seconds - likely not on corporate network")
|
|
145
|
+
return [
|
|
146
|
+
types.Resource(
|
|
147
|
+
uri=AnyUrl("jenkins://offline"),
|
|
148
|
+
name="Jenkins Server Offline",
|
|
149
|
+
description="Jenkins server not reachable. Connect to VPN/corporate network and restart. Tools will still work when connected.",
|
|
150
|
+
mimeType="text/plain",
|
|
151
|
+
)
|
|
152
|
+
]
|
|
137
153
|
except Exception as e:
|
|
138
154
|
logger.error(f"Failed to list resources: {e}")
|
|
139
155
|
return [
|
|
140
156
|
types.Resource(
|
|
141
157
|
uri=AnyUrl("jenkins://error"),
|
|
142
158
|
name="Error connecting to Jenkins",
|
|
143
|
-
description=f"Error: {str(e)}",
|
|
159
|
+
description=f"Error: {str(e)}. Check your configuration and network connection.",
|
|
144
160
|
mimeType="text/plain",
|
|
145
161
|
)
|
|
146
162
|
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|