Commit f566467a authored by MD. SHAHIDUL ISLAM's avatar MD. SHAHIDUL ISLAM

feat: add active project management, issue commenting, work logging, and…

feat: add active project management, issue commenting, work logging, and comprehensive README documentation.
parent 7cdf77ac
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
import os import os
from mcp.server.fastmcp import FastMCP from mcp.server.fastmcp import FastMCP
from jira import JIRA from jira import JIRA
from typing import Optional
# Initialize FastMCP Server # Initialize FastMCP Server
mcp = FastMCP("Dohatec Jira Mcp") mcp = FastMCP("Dohatec Jira Mcp")
...@@ -31,6 +32,7 @@ mcp = FastMCP("Dohatec Jira Mcp") ...@@ -31,6 +32,7 @@ mcp = FastMCP("Dohatec Jira Mcp")
JIRA_SERVER = os.environ.get("JIRA_SERVER") JIRA_SERVER = os.environ.get("JIRA_SERVER")
JIRA_USERNAME = os.environ.get("JIRA_USERNAME") JIRA_USERNAME = os.environ.get("JIRA_USERNAME")
JIRA_PASSWORD = os.environ.get("JIRA_PASSWORD") JIRA_PASSWORD = os.environ.get("JIRA_PASSWORD")
ACTIVE_PROJECT = os.environ.get("JIRA_DEFAULT_PROJECT")
# We use Basic Auth explicitly for this local instance. # We use Basic Auth explicitly for this local instance.
try: try:
...@@ -50,6 +52,20 @@ def _get_jira(): ...@@ -50,6 +52,20 @@ def _get_jira():
raise RuntimeError("Jira client failed to initialize.") raise RuntimeError("Jira client failed to initialize.")
return jira_client return jira_client
@mcp.tool()
def set_active_project(project_key: str) -> str:
"""Sets the active Jira project for the current session."""
global ACTIVE_PROJECT
ACTIVE_PROJECT = project_key
return f"Active project successfully set to '{ACTIVE_PROJECT}'."
@mcp.tool()
def get_active_project() -> str:
"""Gets the currently active Jira project. Call this to check context if user doesn't specify a project."""
if ACTIVE_PROJECT:
return f"The current active project is '{ACTIVE_PROJECT}'."
return "No active project is currently set. Please specify a project key or use set_active_project."
@mcp.tool() @mcp.tool()
def get_my_assigned_issues() -> str: def get_my_assigned_issues() -> str:
"""Fetches all open Jira issues assigned to the current user.""" """Fetches all open Jira issues assigned to the current user."""
...@@ -95,12 +111,18 @@ def get_issue_details(issue_key: str) -> str: ...@@ -95,12 +111,18 @@ def get_issue_details(issue_key: str) -> str:
return f"Error fetching issue {issue_key}: {str(e)}" return f"Error fetching issue {issue_key}: {str(e)}"
@mcp.tool() @mcp.tool()
def create_issue(project_key: str, summary: str, description: str, issue_type: str = "Task") -> str: def create_issue(summary: str, description: str, project_key: str = None, issue_type: str = "Task") -> str:
"""Creates a new Jira issue in the specified project.""" """Creates a new Jira issue. If project_key is not provided, uses the active project."""
global ACTIVE_PROJECT
jira = _get_jira() jira = _get_jira()
target_project = project_key or ACTIVE_PROJECT
if not target_project:
return "Error: No project_key provided and no active project is set."
try: try:
issue_dict = { issue_dict = {
'project': {'key': project_key}, 'project': {'key': target_project},
'summary': summary, 'summary': summary,
'description': description, 'description': description,
'issuetype': {'name': issue_type}, 'issuetype': {'name': issue_type},
...@@ -185,6 +207,44 @@ def get_all_projects() -> str: ...@@ -185,6 +207,44 @@ def get_all_projects() -> str:
except Exception as e: except Exception as e:
return f"Error fetching projects: {str(e)}" return f"Error fetching projects: {str(e)}"
@mcp.tool()
def add_comment_to_issue(issue_key: str, comment: str) -> str:
"""Adds a new comment to a Jira issue."""
jira = _get_jira()
try:
jira.add_comment(issue_key, comment)
return f"Successfully added comment to {issue_key}."
except Exception as e:
return f"Error adding comment to {issue_key}: {str(e)}"
@mcp.tool()
def get_issue_comments(issue_key: str) -> str:
"""Retrieves all comments for a specific Jira issue."""
jira = _get_jira()
try:
issue = jira.issue(issue_key)
comments = issue.fields.comment.comments
if not comments:
return f"No comments found for {issue_key}."
result = [f"Comments for {issue_key}:"]
for c in comments:
author = c.author.displayName if c.author else "Unknown"
result.append(f"--- [{c.created}] {author} ---\n{c.body}\n")
return "\n".join(result)
except Exception as e:
return f"Error fetching comments for {issue_key}: {str(e)}"
@mcp.tool()
def log_work_on_issue(issue_key: str, time_spent: str) -> str:
"""Logs work (time spent) on a Jira issue. Format Example for time_spent: '2h 30m' or '1d'"""
jira = _get_jira()
try:
jira.add_worklog(issue_key, timeSpent=time_spent)
return f"Successfully logged {time_spent} of work on {issue_key}."
except Exception as e:
return f"Error logging work on {issue_key}: {str(e)}"
if __name__ == "__main__": if __name__ == "__main__":
# Start the FastMCP server # Start the FastMCP server
mcp.run() mcp.run()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment