Skip to content

Commit 44ef605

Browse files
4erdenkomliq
authored andcommitted
feat: parse JSON additional_fields (#1)
* feat: parse additional_fields as JSON string Allow create_issue to accept dict or JSON string. Added test and docs. Signed-off-by: Michael Liquori <[email protected]>
1 parent 9ad2cbf commit 44ef605

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,8 @@ Here's a complete example of setting up multi-user authentication with streamabl
726726
727727
- `jira_get_issue`: Get details of a specific issue
728728
- `jira_search`: Search issues using JQL
729-
- `jira_create_issue`: Create a new issue
729+
- `jira_create_issue`: Create a new issue (supports `additional_fields` as a
730+
dictionary or JSON string)
730731
- `jira_update_issue`: Update an existing issue
731732
- `jira_transition_issue`: Transition an issue to a new status
732733
- `jira_add_comment`: Add a comment to an issue

src/mcp_atlassian/servers/jira.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ async def create_issue(
650650
),
651651
] = None,
652652
additional_fields: Annotated[
653-
dict[str, Any] | None,
653+
dict[str, Any] | str | None,
654654
Field(
655655
description=(
656656
"(Optional) Dictionary of additional fields to set. Examples:\n"
@@ -674,7 +674,7 @@ async def create_issue(
674674
assignee: Assignee's user identifier (string): Email, display name, or account ID (e.g., '[email protected]', 'John Doe', 'accountid:...').
675675
description: Issue description.
676676
components: Comma-separated list of component names.
677-
additional_fields: Dictionary of additional fields.
677+
additional_fields: Dictionary or JSON string of additional fields.
678678
679679
Returns:
680680
JSON string representing the created issue object.
@@ -691,9 +691,22 @@ async def create_issue(
691691
]
692692

693693
# Use additional_fields directly as dict
694-
extra_fields = additional_fields or {}
695-
if not isinstance(extra_fields, dict):
696-
raise ValueError("additional_fields must be a dictionary.")
694+
# Accept either dict or JSON string for additional fields
695+
if additional_fields is None:
696+
extra_fields: dict[str, Any] = {}
697+
elif isinstance(additional_fields, dict):
698+
extra_fields = additional_fields
699+
elif isinstance(additional_fields, str):
700+
try:
701+
extra_fields = json.loads(additional_fields)
702+
if not isinstance(extra_fields, dict):
703+
raise ValueError(
704+
"Parsed additional_fields is not a JSON object (dict)."
705+
)
706+
except json.JSONDecodeError as e:
707+
raise ValueError(f"additional_fields is not valid JSON: {e}") from e
708+
else:
709+
raise ValueError("additional_fields must be a dictionary or JSON string.")
697710

698711
issue = jira.create_issue(
699712
project_key=project_key,

tests/unit/servers/test_jira_server.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,31 @@ async def test_create_issue(jira_client, mock_jira_fetcher):
503503
)
504504

505505

506+
@pytest.mark.anyio
507+
async def test_create_issue_accepts_json_string(jira_client, mock_jira_fetcher):
508+
"""Ensure additional_fields can be a JSON string."""
509+
payload = {
510+
"project_key": "TEST",
511+
"summary": "JSON Issue",
512+
"issue_type": "Task",
513+
"additional_fields": '{"labels": ["ai", "test"]}',
514+
}
515+
response = await jira_client.call_tool("jira_create_issue", payload)
516+
assert response
517+
data = json.loads(response[0].text)
518+
assert data["message"] == "Issue created successfully"
519+
assert "issue" in data
520+
mock_jira_fetcher.create_issue.assert_called_with(
521+
project_key="TEST",
522+
summary="JSON Issue",
523+
issue_type="Task",
524+
description=None,
525+
assignee=None,
526+
components=None,
527+
labels=["ai", "test"],
528+
)
529+
530+
506531
@pytest.mark.anyio
507532
async def test_batch_create_issues(jira_client, mock_jira_fetcher):
508533
"""Test batch creation of Jira issues."""

0 commit comments

Comments
 (0)