Skip to main content
Glama

get_plugins_with_problems

Identifies Jenkins plugins with issues such as missing dependencies or version mismatches, helping diagnose configuration problems.

Instructions

Get all plugins with problems from Jenkins

These are plugins that have issues such as missing dependencies, incompatible versions, core version mismatch, or other configuration problems.

Returns: A list of plugins with problems

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • MCP tool handler that returns plugins with problems, delegating to the Jenkins REST client method.
    @mcp.tool(tags={'read'})
    async def get_plugins_with_problems(ctx: Context) -> list[dict]:
        """Get all plugins with problems from Jenkins
    
        These are plugins that have issues such as missing dependencies,
        incompatible versions, core version mismatch, or other configuration problems.
    
        Returns:
            A list of plugins with problems
        """
        return jenkins(ctx).get_plugins_with_problems()
  • Core implementation that checks for plugin problems: incompatible core version, disabled plugins, missing dependencies (optional and required), and version mismatches.
    def get_plugins_with_problems(self) -> list[dict]:
        """Get a list of plugins that have dependency problems.
    
        Checks each plugin's dependencies against the installed plugins
        to identify missing dependencies or version mismatches.
    
        Returns:
            A list of plugins with dependency problems.
        """
        jenkins_version = self._get_jenkins_version()
        plugins = self.get_plugins(depth=2)
    
        installed = {p['shortName']: p for p in plugins}
    
        problems = []
        for plugin in plugins:
            short_name = plugin.get('shortName', '')
            version = plugin.get('version', '')
            required_core = plugin.get('requiredCoreVersion', '')
    
            if required_core and jenkins_version:
                if not self._is_core_compatible(jenkins_version, required_core):
                    problems.append(
                        {
                            'shortName': short_name,
                            'problem': 'incompatible_core_version',
                            'pluginVersion': version,
                            'requiredCoreVersion': required_core,
                            'jenkinsVersion': jenkins_version,
                            'severity': 'error',
                            'message': (
                                f'Plugin requires Jenkins {required_core}, but current version is {jenkins_version}'
                            ),
                        }
                    )
    
            if not plugin.get('enabled'):
                problems.append(
                    {
                        'shortName': short_name,
                        'problem': 'plugin_disabled',
                        'pluginVersion': version,
                        'severity': 'warning',
                        'message': 'Plugin is currently disabled',
                    }
                )
    
            deps = plugin.get('dependencies', [])
            for dep in deps:
                dep_name = dep.get('shortName', '')
                dep_version = dep.get('version', '')
                is_optional = dep.get('optional', False)
                is_bundled = dep.get('bundled', False)
    
                if dep_name not in installed:
                    if is_optional:
                        problems.append(
                            {
                                'shortName': short_name,
                                'problem': 'missing_optional_dependency',
                                'dependency': dep_name,
                                'requiredVersion': dep_version,
                                'severity': 'info',
                                'message': f'Missing optional dependency: {dep_name}',
                            }
                        )
                    elif not is_bundled:
                        problems.append(
                            {
                                'shortName': short_name,
                                'problem': 'missing_dependency',
                                'dependency': dep_name,
                                'requiredVersion': dep_version,
                                'severity': 'error',
                                'message': f'Missing required dependency: {dep_name}',
                            }
                        )
                else:
                    installed_ver = installed[dep_name].get('version', '')
                    if dep_version and installed_ver and installed_ver != dep_version:
                        if self._is_version_greater(installed_ver, dep_version):
                            continue
                        if is_optional:
                            problems.append(
                                {
                                    'shortName': short_name,
                                    'problem': 'version_mismatch_optional',
                                    'dependency': dep_name,
                                    'requiredVersion': dep_version,
                                    'installedVersion': installed_ver,
                                    'severity': 'info',
                                    'message': (
                                        f'Optional dependency {dep_name} version mismatch: '
                                        f'required {dep_version}, installed {installed_ver}'
                                    ),
                                }
                            )
                        else:
                            problems.append(
                                {
                                    'shortName': short_name,
                                    'problem': 'version_mismatch',
                                    'dependency': dep_name,
                                    'requiredVersion': dep_version,
                                    'installedVersion': installed_ver,
                                    'severity': 'error',
                                    'message': (
                                        f'Dependency {dep_name} version mismatch: '
                                        f'required {dep_version}, installed {installed_ver}'
                                    ),
                                }
                            )
    
        return problems
  • MCP server instance creation and plugin module import that registers the tool via @mcp.tool decorator.
    mcp = JenkinsMCP('mcp-jenkins', lifespan=lifespan)
    
    # Import tool modules to register them with the MCP server
    # This must happen after mcp is created so the @mcp.tool() decorators can reference it
    from mcp_jenkins.server import build, item, node, plugin, queue, view  # noqa: F401, E402
  • Helper method that retrieves the Jenkins core version from response headers.
    def _get_jenkins_version(self) -> str:
        """Get the Jenkins core version from response header."""
        response = self.request('GET', '', crumb=False)
        return response.headers.get('X-Jenkins', '')
  • Helper method that checks if the Jenkins core version is compatible with a plugin's required core version.
    def _is_core_compatible(self, jenkins_ver: str, required_ver: str) -> bool:
        """Check if Jenkins version is compatible with required core version."""
        if not isinstance(jenkins_ver, str) or not isinstance(required_ver, str):
            return True
    
        def normalize_version(v: str) -> tuple:
            parts = v.split('.')
            return tuple(int(p) if p.isdigit() else 0 for p in parts[:3])
    
        core = normalize_version(jenkins_ver)
        required = normalize_version(required_ver)
        return core >= required
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Describes the return type (a list of plugins with problems) and gives examples of issues. However, without annotations, it does not disclose safety or side effects (e.g., read-only, rate limits). The description is adequate but not thorough.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise paragraphs with front-loaded purpose, clear explanation of problem types, and a returns section. No extraneous content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no parameters and an output schema, the description covers purpose and examples of problems. It lacks mention of read-only nature or authentication, but overall is fairly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters, so the description adds no parameter information beyond the schema. Since schema coverage is 100% (no params), baseline 3; the lack of parameter info is not a deficiency, and the description is clear.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it gets all plugins with problems from Jenkins, defining what constitutes a problem (missing dependencies, incompatible versions, etc.). Differentiates from sibling tools like get_all_plugins and get_plugins_with_updates by focusing specifically on problematic plugins.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives (e.g., get_all_plugins for a complete list). The description does not specify prerequisites or scenarios where this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lanbaoshen/mcp-jenkins'

If you have feedback or need assistance with the MCP directory API, please join our Discord server