Initial commit
This commit is contained in:
160
skills/mxcp-expert/assets/project-templates/jira-oauth/README.md
Normal file
160
skills/mxcp-expert/assets/project-templates/jira-oauth/README.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# Connect Jira to MXCP with OAuth
|
||||
|
||||
This example shows how to connect JIRA to MXCP using secure OAuth authentication.
|
||||
|
||||
## What You Get
|
||||
|
||||
Once configured, you can query your Jira data directly from MXCP:
|
||||
|
||||
```sql
|
||||
-- Find all issues assigned to you
|
||||
SELECT jql_query_jira('assignee = currentUser()') AS my_issues;
|
||||
|
||||
-- Get recent bugs in a project
|
||||
SELECT jql_query_jira('project = MYPROJECT AND type = Bug AND created >= -7d') AS recent_bugs;
|
||||
|
||||
-- List all your accessible projects
|
||||
SELECT list_projects_jira() AS projects;
|
||||
|
||||
-- Get user information
|
||||
SELECT get_user_jira('john.doe@company.com') AS user_info;
|
||||
```
|
||||
|
||||
## Quick Setup Guide
|
||||
|
||||
### Step 1: Create Your OAuth App in Atlassian
|
||||
|
||||
1. Go to [Atlassian Developer Console](https://developer.atlassian.com/console/myapps/)
|
||||
2. Click **Create** → **OAuth 2.0 (3LO)**
|
||||
3. Fill in your app details:
|
||||
- **App name**: `MXCP Jira Integration` (or whatever you prefer)
|
||||
- **Description**: `OAuth integration for MXCP`
|
||||
4. Click **Create**
|
||||
|
||||
### Step 2: Configure OAuth Settings
|
||||
|
||||
After creating your app:
|
||||
|
||||
1. Click on your newly created app
|
||||
2. Go to **Permissions** → **Add** → **Jira API**
|
||||
3. Add these scopes:
|
||||
- `read:me` (to read your own profile information)
|
||||
- `read:jira-work` (to read issues and projects)
|
||||
- `read:jira-user` (to read user information)
|
||||
- `offline_access` (to refresh tokens)
|
||||
|
||||
4. Go to **Authorization** → **OAuth 2.0 (3LO)**
|
||||
5. Add your callback URL based on your deployment:
|
||||
- **For production**: `https://your-domain.com/atlassian/callback`
|
||||
- **For local development**: `http://localhost:8000/atlassian/callback`
|
||||
- **For ngrok testing**: `https://your-ngrok-url.ngrok.io/atlassian/callback`
|
||||
|
||||
6. **Important**: Save your **Client ID** and **Client Secret** - you'll need these next!
|
||||
|
||||
### Step 3: Set Up Environment Variables
|
||||
|
||||
Create a `.env` file or set these environment variables:
|
||||
|
||||
```bash
|
||||
export ATLASSIAN_CLIENT_ID="your-client-id-here"
|
||||
export ATLASSIAN_CLIENT_SECRET="your-client-secret-here"
|
||||
```
|
||||
|
||||
### Step 4: Configure MXCP
|
||||
|
||||
This example includes a ready-to-use `config.yml` file that you can customize with your OAuth credentials. You can either:
|
||||
|
||||
- **Use the included file**: Edit the existing `config.yml` in this directory
|
||||
- **Create your own**: Use the template below
|
||||
|
||||
Configuration template:
|
||||
|
||||
```yaml
|
||||
mxcp: 1.0.0
|
||||
transport:
|
||||
http:
|
||||
port: 8000
|
||||
host: 0.0.0.0
|
||||
# Set base_url to your server's public URL for production
|
||||
base_url: http://localhost:8000
|
||||
|
||||
projects:
|
||||
my-jira-project:
|
||||
profiles:
|
||||
dev:
|
||||
# OAuth Configuration
|
||||
auth:
|
||||
provider: atlassian
|
||||
clients:
|
||||
- client_id: "${ATLASSIAN_CLIENT_ID}"
|
||||
client_secret: "${ATLASSIAN_CLIENT_SECRET}"
|
||||
name: "MXCP Jira Integration"
|
||||
redirect_uris:
|
||||
# For production, use your actual domain (must match base_url above)
|
||||
- "https://your-domain.com/atlassian/callback"
|
||||
# For local development, uncomment the line below:
|
||||
# - "http://localhost:8000/atlassian/callback"
|
||||
scopes:
|
||||
- "mxcp:access"
|
||||
atlassian:
|
||||
client_id: "${ATLASSIAN_CLIENT_ID}"
|
||||
client_secret: "${ATLASSIAN_CLIENT_SECRET}"
|
||||
scope: "read:me read:jira-work read:jira-user offline_access"
|
||||
callback_path: "/atlassian/callback"
|
||||
auth_url: "https://auth.atlassian.com/authorize"
|
||||
token_url: "https://auth.atlassian.com/oauth/token"
|
||||
|
||||
# Plugin Configuration (minimal setup required!)
|
||||
plugin:
|
||||
config:
|
||||
jira_oauth: {} # Named 'jira_oauth' here, but UDFs use 'jira' suffix from mxcp-site.yml
|
||||
```
|
||||
|
||||
### Step 5: Install and Run
|
||||
|
||||
1. **Install dependencies**:
|
||||
```bash
|
||||
pip install atlassian-python-api requests
|
||||
```
|
||||
|
||||
2. **Start MXCP**:
|
||||
```bash
|
||||
# From the examples/jira-oauth directory:
|
||||
MXCP_CONFIG=config.yml mxcp serve
|
||||
```
|
||||
|
||||
3. **Authenticate**:
|
||||
- Configure the MXCP server in your MCP client (e.g., Claude Desktop)
|
||||
- When the client connects, you'll be redirected to Atlassian to authorize the app
|
||||
- After authorization, you'll be redirected back to your MCP client
|
||||
- You're now ready to query Jira!
|
||||
|
||||
## Available Functions
|
||||
|
||||
| Function | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `jql_query_jira(query, start, limit)` | Execute JQL queries | `SELECT jql_query_jira('project = TEST')` |
|
||||
| `list_projects_jira()` | List all your accessible projects | `SELECT list_projects_jira()` |
|
||||
| `get_project_jira(key)` | Get details for a specific project | `SELECT get_project_jira('TEST')` |
|
||||
| `get_user_jira(username)` | Get user information | `SELECT get_user_jira('john@company.com')` |
|
||||
|
||||
## Example Queries
|
||||
|
||||
```sql
|
||||
-- Get your assigned issues
|
||||
SELECT jql_query_jira('assignee = currentUser() AND status != Done', 0, 20) AS my_open_issues;
|
||||
|
||||
-- Find high priority bugs
|
||||
SELECT jql_query_jira('priority = High AND type = Bug', 0, 10) AS high_priority_bugs;
|
||||
|
||||
-- Recent activity in a project
|
||||
SELECT jql_query_jira('project = MYPROJECT AND updated >= -3d') AS recent_activity;
|
||||
|
||||
-- Get project information
|
||||
SELECT
|
||||
list_projects_jira() AS all_projects,
|
||||
get_project_jira('MYPROJECT') AS project_details;
|
||||
|
||||
-- Find issues by reporter
|
||||
SELECT jql_query_jira('reporter = "john.doe@company.com"') AS johns_issues;
|
||||
```
|
||||
@@ -0,0 +1,36 @@
|
||||
mxcp: 1
|
||||
transport:
|
||||
http:
|
||||
port: 8000
|
||||
host: 0.0.0.0
|
||||
# Set base_url to your server's public URL for production
|
||||
base_url: http://localhost:8000
|
||||
|
||||
projects:
|
||||
jira-oauth-demo:
|
||||
profiles:
|
||||
dev:
|
||||
# OAuth Authentication Configuration
|
||||
auth:
|
||||
provider: atlassian
|
||||
clients:
|
||||
- client_id: "${ATLASSIAN_CLIENT_ID}"
|
||||
client_secret: "${ATLASSIAN_CLIENT_SECRET}"
|
||||
name: "MXCP Jira OAuth Integration"
|
||||
redirect_uris:
|
||||
# For production, use your actual domain (must match base_url above)
|
||||
- "http://localhost:8000/atlassian/callback"
|
||||
scopes:
|
||||
- "mxcp:access"
|
||||
atlassian:
|
||||
client_id: "${ATLASSIAN_CLIENT_ID}"
|
||||
client_secret: "${ATLASSIAN_CLIENT_SECRET}"
|
||||
scope: "read:me read:jira-work read:jira-user offline_access"
|
||||
callback_path: "/atlassian/callback"
|
||||
auth_url: "https://auth.atlassian.com/authorize"
|
||||
token_url: "https://auth.atlassian.com/oauth/token"
|
||||
|
||||
# Plugin Configuration (minimal configuration - uses OAuth context!)
|
||||
plugin:
|
||||
config:
|
||||
jira_oauth: {} # Named 'jira_oauth' here, but UDFs use 'jira' suffix from mxcp-site.yml
|
||||
@@ -0,0 +1,8 @@
|
||||
mxcp: 1
|
||||
project: jira-oauth-demo
|
||||
profile: dev
|
||||
|
||||
plugin:
|
||||
- name: jira
|
||||
module: mxcp_plugin_jira_oauth
|
||||
config: jira_oauth
|
||||
@@ -0,0 +1,10 @@
|
||||
"""
|
||||
MXCP Jira OAuth Plugin
|
||||
|
||||
This plugin provides UDFs for querying Atlassian Jira using OAuth authentication.
|
||||
Unlike the API token version, this plugin uses OAuth tokens from authenticated users.
|
||||
"""
|
||||
|
||||
from .plugin import MXCPPlugin
|
||||
|
||||
__all__ = ["MXCPPlugin"]
|
||||
@@ -0,0 +1,250 @@
|
||||
"""
|
||||
Jira OAuth Plugin Implementation
|
||||
|
||||
This module provides UDFs for querying Atlassian Jira using JQL with OAuth 2.0 authentication.
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import requests
|
||||
from atlassian import Jira
|
||||
|
||||
from mxcp.plugins import MXCPBasePlugin, udf
|
||||
from mxcp.sdk.auth.context import get_user_context
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MXCPPlugin(MXCPBasePlugin):
|
||||
"""Jira OAuth plugin that provides JQL query functionality using OAuth 2.0 Bearer tokens."""
|
||||
|
||||
def __init__(self, config: Dict[str, Any]):
|
||||
"""Initialize the Jira OAuth plugin.
|
||||
|
||||
Args:
|
||||
config: Plugin configuration containing optional settings
|
||||
Optional keys:
|
||||
- oauth_token: Fallback OAuth Bearer token (if not using user context)
|
||||
"""
|
||||
super().__init__(config)
|
||||
self.fallback_oauth_token = config.get("oauth_token", "")
|
||||
self.instance_url: Optional[str] = None
|
||||
|
||||
def _get_oauth_token(self) -> str:
|
||||
"""Get OAuth token from user context or fallback configuration.
|
||||
|
||||
Returns:
|
||||
OAuth Bearer token
|
||||
|
||||
Raises:
|
||||
ValueError: If no OAuth token is available
|
||||
"""
|
||||
# First try to get token from user context (preferred)
|
||||
user_context = get_user_context()
|
||||
if user_context and user_context.external_token:
|
||||
logger.debug("Using OAuth token from user context")
|
||||
return user_context.external_token
|
||||
|
||||
# Fall back to configured token
|
||||
if self.fallback_oauth_token:
|
||||
logger.debug("Using fallback OAuth token from configuration")
|
||||
return self.fallback_oauth_token
|
||||
|
||||
raise ValueError("No OAuth token available from user context or configuration")
|
||||
|
||||
def _get_cloud_id_and_url(self, oauth_token: str) -> tuple[str, str]:
|
||||
"""Get the cloud ID and instance URL for the first accessible Jira instance using the OAuth token.
|
||||
|
||||
Args:
|
||||
oauth_token: OAuth Bearer token
|
||||
|
||||
Returns:
|
||||
Tuple of (cloud_id, instance_url) for the first accessible Jira instance
|
||||
|
||||
Raises:
|
||||
ValueError: If cloud ID and URL cannot be retrieved
|
||||
"""
|
||||
try:
|
||||
response = requests.get(
|
||||
"https://api.atlassian.com/oauth/token/accessible-resources",
|
||||
headers={"Authorization": f"Bearer {oauth_token}", "Accept": "application/json"},
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
resources = response.json()
|
||||
logger.debug(f"Found {len(resources)} accessible resources")
|
||||
|
||||
# Use the first accessible resource
|
||||
if resources:
|
||||
cloud_id = resources[0].get("id")
|
||||
instance_url = resources[0].get("url")
|
||||
logger.info(f"Using cloud ID: {cloud_id} for instance: {instance_url}")
|
||||
return cloud_id, instance_url
|
||||
|
||||
raise ValueError(f"No accessible resources found for OAuth token")
|
||||
|
||||
except requests.RequestException as e:
|
||||
logger.error(f"Failed to get cloud ID and URL: {e}")
|
||||
raise ValueError(f"Failed to retrieve cloud ID and URL: {e}")
|
||||
|
||||
def _create_jira_client(self) -> Jira:
|
||||
"""Create a Jira client with OAuth authentication using the correct API gateway URL.
|
||||
|
||||
Returns:
|
||||
Configured Jira client instance
|
||||
"""
|
||||
oauth_token = self._get_oauth_token()
|
||||
|
||||
# Get the cloud ID and instance URL for the first accessible Jira instance
|
||||
cloud_id, instance_url = self._get_cloud_id_and_url(oauth_token)
|
||||
|
||||
# Store the instance URL for constructing web UI URLs
|
||||
self.instance_url = instance_url
|
||||
|
||||
# Construct the API gateway URL for OAuth requests
|
||||
api_gateway_url = f"https://api.atlassian.com/ex/jira/{cloud_id}"
|
||||
logger.info("API Gateway URL: %s", api_gateway_url)
|
||||
|
||||
# Create a requests session with OAuth Bearer token
|
||||
session = requests.Session()
|
||||
session.headers["Authorization"] = f"Bearer {oauth_token}"
|
||||
|
||||
# Create and return Jira client with the OAuth session and API gateway URL
|
||||
# Explicitly set cloud=True since we're using Jira Cloud with OAuth
|
||||
return Jira(url=api_gateway_url, session=session, cloud=True)
|
||||
|
||||
@udf
|
||||
def jql_query(self, query: str, start: Optional[int] = 0, limit: Optional[int] = None) -> str:
|
||||
"""Execute a JQL query against Jira using OAuth authentication.
|
||||
|
||||
Args:
|
||||
query: The JQL query string
|
||||
start: Starting index for pagination (default: 0)
|
||||
limit: Maximum number of results to return (default: None, meaning no limit)
|
||||
|
||||
Returns:
|
||||
JSON string containing Jira issues matching the query
|
||||
"""
|
||||
logger.info(
|
||||
"Executing JQL query with OAuth: %s with start=%s, limit=%s", query, start, limit
|
||||
)
|
||||
|
||||
# Create Jira client with current user's OAuth token
|
||||
jira = self._create_jira_client()
|
||||
|
||||
raw = jira.jql(
|
||||
jql=query,
|
||||
start=start,
|
||||
limit=limit,
|
||||
fields=(
|
||||
"key,summary,status,resolution,resolutiondate,"
|
||||
"assignee,reporter,issuetype,priority,"
|
||||
"created,updated,labels,fixVersions,parent"
|
||||
),
|
||||
)
|
||||
|
||||
def _name(obj: Optional[Dict[str, Any]]) -> Optional[str]:
|
||||
"""Return obj['name'] if present, else None."""
|
||||
return obj.get("name") if obj else None
|
||||
|
||||
def _key(obj: Optional[Dict[str, Any]]) -> Optional[str]:
|
||||
return obj.get("key") if obj else None
|
||||
|
||||
cleaned: List[Dict[str, Any]] = []
|
||||
for issue in raw.get("issues", []):
|
||||
f = issue["fields"]
|
||||
|
||||
cleaned.append(
|
||||
{
|
||||
"key": issue["key"],
|
||||
"summary": f.get("summary"),
|
||||
"status": _name(f.get("status")),
|
||||
"resolution": _name(f.get("resolution")),
|
||||
"resolution_date": f.get("resolutiondate"),
|
||||
"assignee": _name(f.get("assignee")),
|
||||
"reporter": _name(f.get("reporter")),
|
||||
"type": _name(f.get("issuetype")),
|
||||
"priority": _name(f.get("priority")),
|
||||
"created": f.get("created"),
|
||||
"updated": f.get("updated"),
|
||||
"labels": f.get("labels") or [],
|
||||
"fix_versions": [_name(v) for v in f.get("fixVersions", [])],
|
||||
"parent": _key(f.get("parent")),
|
||||
"url": f"{self.instance_url}/browse/{issue['key']}", # web UI URL
|
||||
}
|
||||
)
|
||||
|
||||
return json.dumps(cleaned)
|
||||
|
||||
@udf
|
||||
def get_user(self, username: str) -> str:
|
||||
"""Get details for a specific user by username using OAuth.
|
||||
|
||||
Args:
|
||||
username: The username to search for
|
||||
|
||||
Returns:
|
||||
JSON string containing the user details
|
||||
"""
|
||||
logger.info("Getting user details with OAuth for username: %s", username)
|
||||
|
||||
# Create Jira client with current user's OAuth token
|
||||
jira = self._create_jira_client()
|
||||
|
||||
return json.dumps(jira.user_find_by_user_string(query=username))
|
||||
|
||||
@udf
|
||||
def list_projects(self) -> str:
|
||||
"""List all accessible Jira projects using OAuth authentication.
|
||||
|
||||
Returns:
|
||||
JSON string containing an array of accessible Jira projects
|
||||
"""
|
||||
logger.info("Listing all projects with OAuth")
|
||||
|
||||
# Create Jira client with current user's OAuth token
|
||||
jira = self._create_jira_client()
|
||||
|
||||
raw_projects: List[Dict[str, Any]] = jira.projects()
|
||||
|
||||
def safe_name(obj: Optional[Dict[str, Any]]) -> Optional[str]:
|
||||
return obj.get("displayName") or obj.get("name") if obj else None
|
||||
|
||||
concise: List[Dict[str, Any]] = []
|
||||
for p in raw_projects:
|
||||
concise.append(
|
||||
{
|
||||
"key": p.get("key"),
|
||||
"name": p.get("name"),
|
||||
"type": p.get("projectTypeKey"), # e.g. software, business
|
||||
"lead": safe_name(p.get("lead")),
|
||||
"url": f"{self.instance_url}/projects/{p.get('key')}", # web UI URL
|
||||
}
|
||||
)
|
||||
|
||||
return json.dumps(concise)
|
||||
|
||||
@udf
|
||||
def get_project(self, project_key: str) -> str:
|
||||
"""Get details for a specific project by its key using OAuth.
|
||||
|
||||
Args:
|
||||
project_key: The project key (e.g., 'TEST' for project TEST)
|
||||
|
||||
Returns:
|
||||
JSON string containing the project details
|
||||
"""
|
||||
logger.info("Getting project details with OAuth for key: %s", project_key)
|
||||
|
||||
# Create Jira client with current user's OAuth token
|
||||
jira = self._create_jira_client()
|
||||
|
||||
info = jira.project(project_key)
|
||||
# remove the self key if it exists
|
||||
if "self" in info:
|
||||
info.pop("self")
|
||||
# Add web UI URL
|
||||
info["url"] = f"{self.instance_url}/projects/{project_key}"
|
||||
return json.dumps(info)
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Get the username of the currently authenticated user
|
||||
SELECT get_username() as authenticated_user;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Get details for a specific Jira project using OAuth authentication
|
||||
SELECT get_project_jira($project_key) as result;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Get details for a specific Jira user using OAuth authentication
|
||||
SELECT get_user_jira($username) as result;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Example JQL query endpoint using OAuth authentication
|
||||
SELECT jql_query_jira($query, $start, $limit) as result;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- List all projects in Jira using OAuth authentication
|
||||
SELECT list_projects_jira() as result;
|
||||
@@ -0,0 +1,25 @@
|
||||
mxcp: 1
|
||||
|
||||
tool:
|
||||
name: get_current_user
|
||||
description: |
|
||||
Get the username of the currently authenticated user in MXCP.
|
||||
This tool returns the username of the person who is authenticated via OAuth with Jira.
|
||||
It's useful for understanding whose credentials are being used for Jira API calls,
|
||||
and can help verify that the OAuth authentication flow completed successfully.
|
||||
The username typically corresponds to the Atlassian account email address.
|
||||
type: tool
|
||||
annotations:
|
||||
title: Get Current Authenticated User
|
||||
readOnlyHint: true
|
||||
destructiveHint: false
|
||||
idempotentHint: true
|
||||
openWorldHint: false
|
||||
return:
|
||||
type: string
|
||||
description: |
|
||||
The username (typically email address) of the currently authenticated user.
|
||||
Returns NULL if no user is authenticated.
|
||||
language: "sql"
|
||||
source:
|
||||
file: "../sql/get_current_user.sql"
|
||||
@@ -0,0 +1,32 @@
|
||||
mxcp: 1
|
||||
|
||||
tool:
|
||||
name: get_project
|
||||
description: |
|
||||
Get details for a specific project in your Jira instance by its project key using OAuth authentication.
|
||||
Returns a JSON string containing the project's details.
|
||||
type: tool
|
||||
annotations:
|
||||
title: Get Project Details (OAuth)
|
||||
readOnlyHint: true
|
||||
destructiveHint: false
|
||||
idempotentHint: true
|
||||
openWorldHint: true
|
||||
parameters:
|
||||
- name: project_key
|
||||
type: string
|
||||
description: |
|
||||
The project key to search for. This is the short identifier for the project (e.g., 'TEST' for project TEST).
|
||||
Project keys are typically uppercase and contain only letters and numbers.
|
||||
examples: [
|
||||
"TEST",
|
||||
"PROJ",
|
||||
"DEV"
|
||||
]
|
||||
return:
|
||||
type: string
|
||||
description: |
|
||||
A JSON string containing the project's details.
|
||||
language: "sql"
|
||||
source:
|
||||
file: "../sql/get_project.sql"
|
||||
@@ -0,0 +1,30 @@
|
||||
mxcp: 1
|
||||
|
||||
tool:
|
||||
name: get_user
|
||||
description: |
|
||||
Get details for a specific user in your Jira instance by their username using OAuth authentication.
|
||||
Returns a JSON string containing the user's details.
|
||||
type: tool
|
||||
annotations:
|
||||
title: Get User Details (OAuth)
|
||||
readOnlyHint: true
|
||||
destructiveHint: false
|
||||
idempotentHint: true
|
||||
openWorldHint: true
|
||||
parameters:
|
||||
- name: username
|
||||
type: string
|
||||
description: |
|
||||
The username to search for. This is typically the user's email address or username in Jira.
|
||||
examples: [
|
||||
"john.doe@example.com",
|
||||
"jane.smith"
|
||||
]
|
||||
return:
|
||||
type: string
|
||||
description: |
|
||||
A JSON string containing the user's details.
|
||||
language: "sql"
|
||||
source:
|
||||
file: "../sql/get_user.sql"
|
||||
@@ -0,0 +1,50 @@
|
||||
mxcp: 1
|
||||
|
||||
tool:
|
||||
name: jql
|
||||
description: |
|
||||
Execute a JQL (Jira Query Language) query to search for issues in your Jira instance using OAuth authentication.
|
||||
Returns a JSON string containing the matching issues with their details.
|
||||
Use the start and limit parameters to paginate through large result sets.
|
||||
type: tool
|
||||
annotations:
|
||||
title: JQL Query (OAuth)
|
||||
readOnlyHint: true
|
||||
destructiveHint: false
|
||||
idempotentHint: true
|
||||
openWorldHint: true
|
||||
parameters:
|
||||
- name: query
|
||||
type: string
|
||||
description: |
|
||||
The JQL query string to execute. Examples:
|
||||
- "project = TEST" to find all issues in the TEST project
|
||||
- "assignee = currentUser()" to find issues assigned to you
|
||||
- "status = 'In Progress'" to find issues in progress
|
||||
examples: [
|
||||
"project = TEST",
|
||||
"status = 'In Progress'",
|
||||
"project = TEST AND status = 'Done'",
|
||||
"created >= -30d ORDER BY created DESC"
|
||||
]
|
||||
- name: start
|
||||
type: integer
|
||||
description: |
|
||||
The index of the first result to return (0-based).
|
||||
Use this for pagination: start=0 for first page, start=50 for second page, etc.
|
||||
Defaults to 0 if not specified.
|
||||
examples: [0, 50, 100]
|
||||
- name: limit
|
||||
type: integer
|
||||
description: |
|
||||
Maximum number of results to return.
|
||||
If not specified, returns all matching results.
|
||||
Recommended to use with start parameter for pagination.
|
||||
examples: [50, 100, 200]
|
||||
return:
|
||||
type: string
|
||||
description: |
|
||||
A JSON string containing an array of Jira issues.
|
||||
language: "sql"
|
||||
source:
|
||||
file: "../sql/jql.sql"
|
||||
@@ -0,0 +1,21 @@
|
||||
mxcp: 1
|
||||
|
||||
tool:
|
||||
name: list_projects
|
||||
description: |
|
||||
List all projects in your Jira instance using OAuth authentication.
|
||||
Returns a JSON string containing an array of projects with their details.
|
||||
type: tool
|
||||
annotations:
|
||||
title: List Projects (OAuth)
|
||||
readOnlyHint: true
|
||||
destructiveHint: false
|
||||
idempotentHint: true
|
||||
openWorldHint: true
|
||||
return:
|
||||
type: string
|
||||
description: |
|
||||
A JSON string containing an array of Jira projects.
|
||||
language: "sql"
|
||||
source:
|
||||
file: "../sql/list_projects.sql"
|
||||
Reference in New Issue
Block a user