mcp-atlassian 0.1.0__tar.gz
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.
Potentially problematic release.
This version of mcp-atlassian might be problematic. Click here for more details.
- mcp_atlassian-0.1.0/.env +3 -0
- mcp_atlassian-0.1.0/.env.example +3 -0
- mcp_atlassian-0.1.0/PKG-INFO +106 -0
- mcp_atlassian-0.1.0/README.md +93 -0
- mcp_atlassian-0.1.0/pyproject.toml +23 -0
- mcp_atlassian-0.1.0/src/mcp_atlassian/__init__.py +11 -0
- mcp_atlassian-0.1.0/src/mcp_atlassian/confluence.py +154 -0
- mcp_atlassian-0.1.0/src/mcp_atlassian/server.py +176 -0
- mcp_atlassian-0.1.0/uv.lock +418 -0
mcp_atlassian-0.1.0/.env
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
CONFLUENCE_CLOUD_URL=https://lunit.atlassian.net/wiki
|
|
2
|
+
CONFLUENCE_CLOUD_USER=hslee@lunit.io
|
|
3
|
+
CONFLUENCE_CLOUD_TOKEN=ATATT3xFfGF0Kc0ls46wfOZlSkxQ-7rrD4cTZXUmFfug9uFJDRjs4saEG-F4eKQmC87KM9sLaQ5PouzrueMjDohkiW43XDEGLBn7RLNWXt3dxAtze_-x0NGJFZ4OWrZ1IqAeM0ItffsR54anvLxDcjpb_iZShYeETIUWB0EubvD0YWYUBy8rWhE=BE4C0ABA
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: mcp-atlassian
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The Model Context Protocol (MCP) Atlassian integration is an open-source implementation that bridges Atlassian products (Jira and Confluence) with AI language models following Anthropic's MCP specification. This project enables secure, contextual AI interactions with Atlassian tools while maintaining data privacy and security. Key features include:
|
|
5
|
+
Author-email: sooperset <soomiles.dev@gmail.com>
|
|
6
|
+
Requires-Python: >=3.13
|
|
7
|
+
Requires-Dist: atlassian-python-api>=3.41.16
|
|
8
|
+
Requires-Dist: beautifulsoup4>=4.12.3
|
|
9
|
+
Requires-Dist: httpx>=0.28.0
|
|
10
|
+
Requires-Dist: mcp>=1.0.0
|
|
11
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# mcp-atlassian
|
|
15
|
+
|
|
16
|
+
MCP server to interact with Atlassian products (currently supporting Confluence).
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
### Tools
|
|
21
|
+
|
|
22
|
+
- search_confluence: Search Confluence content using natural language
|
|
23
|
+
- get_page_content: Get content of a specific Confluence page
|
|
24
|
+
- get_page_comments: Get comments for a specific page
|
|
25
|
+
|
|
26
|
+
### Example prompts
|
|
27
|
+
|
|
28
|
+
- "Search for all documentation related to authentication and summarize the key points"
|
|
29
|
+
- "Get the content of the onboarding guide and create a checklist from it"
|
|
30
|
+
- "Find all comments on the project requirements page and highlight any concerns raised"
|
|
31
|
+
|
|
32
|
+
## Setup
|
|
33
|
+
|
|
34
|
+
### Requirements
|
|
35
|
+
|
|
36
|
+
Create a `.env` file with:
|
|
37
|
+
```
|
|
38
|
+
CONFLUENCE_CLOUD_URL=your_confluence_url
|
|
39
|
+
CONFLUENCE_CLOUD_USER=your_username
|
|
40
|
+
CONFLUENCE_CLOUD_TOKEN=your_api_token
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
To get an API token:
|
|
44
|
+
1. Log in to https://id.atlassian.com/manage-profile/security/api-tokens
|
|
45
|
+
2. Click Create API token
|
|
46
|
+
3. Enter a memorable Label for your token and click Create
|
|
47
|
+
4. Click Copy to clipboard to save your token securely
|
|
48
|
+
|
|
49
|
+
### Claude Desktop Configuration
|
|
50
|
+
|
|
51
|
+
Location:
|
|
52
|
+
- MacOS: `~/Library/Application\ Support/Claude/claude_desktop_config.json`
|
|
53
|
+
- Windows: `%APPDATA%/Claude/claude_desktop_config.json`
|
|
54
|
+
|
|
55
|
+
Configuration:
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"mcp-atlassian": {
|
|
60
|
+
"command": "uv",
|
|
61
|
+
"args": [
|
|
62
|
+
"--directory",
|
|
63
|
+
"<dir_to>/mcp-atlassian",
|
|
64
|
+
"run",
|
|
65
|
+
"mcp-atlassian"
|
|
66
|
+
],
|
|
67
|
+
"env": {
|
|
68
|
+
"CONFLUENCE_CLOUD_URL": "your_confluence_url",
|
|
69
|
+
"CONFLUENCE_CLOUD_USER": "your_username",
|
|
70
|
+
"CONFLUENCE_CLOUD_TOKEN": "your_api_token"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Development
|
|
78
|
+
|
|
79
|
+
### Building
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Install dependencies
|
|
83
|
+
uv sync
|
|
84
|
+
|
|
85
|
+
# Build package
|
|
86
|
+
uv build
|
|
87
|
+
|
|
88
|
+
# Publish to PyPI
|
|
89
|
+
uv publish
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Debugging
|
|
93
|
+
|
|
94
|
+
Use MCP Inspector:
|
|
95
|
+
```bash
|
|
96
|
+
npx @modelcontextprotocol/inspector uv --directory /path/to/mcp-atlassian run mcp-atlassian
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
View logs:
|
|
100
|
+
```bash
|
|
101
|
+
tail -n 20 -f ~/Library/Logs/Claude/mcp-server-mcp-atlassian.log
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Todo
|
|
105
|
+
|
|
106
|
+
- [ ] Jira integration
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# mcp-atlassian
|
|
2
|
+
|
|
3
|
+
MCP server to interact with Atlassian products (currently supporting Confluence).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
### Tools
|
|
8
|
+
|
|
9
|
+
- search_confluence: Search Confluence content using natural language
|
|
10
|
+
- get_page_content: Get content of a specific Confluence page
|
|
11
|
+
- get_page_comments: Get comments for a specific page
|
|
12
|
+
|
|
13
|
+
### Example prompts
|
|
14
|
+
|
|
15
|
+
- "Search for all documentation related to authentication and summarize the key points"
|
|
16
|
+
- "Get the content of the onboarding guide and create a checklist from it"
|
|
17
|
+
- "Find all comments on the project requirements page and highlight any concerns raised"
|
|
18
|
+
|
|
19
|
+
## Setup
|
|
20
|
+
|
|
21
|
+
### Requirements
|
|
22
|
+
|
|
23
|
+
Create a `.env` file with:
|
|
24
|
+
```
|
|
25
|
+
CONFLUENCE_CLOUD_URL=your_confluence_url
|
|
26
|
+
CONFLUENCE_CLOUD_USER=your_username
|
|
27
|
+
CONFLUENCE_CLOUD_TOKEN=your_api_token
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
To get an API token:
|
|
31
|
+
1. Log in to https://id.atlassian.com/manage-profile/security/api-tokens
|
|
32
|
+
2. Click Create API token
|
|
33
|
+
3. Enter a memorable Label for your token and click Create
|
|
34
|
+
4. Click Copy to clipboard to save your token securely
|
|
35
|
+
|
|
36
|
+
### Claude Desktop Configuration
|
|
37
|
+
|
|
38
|
+
Location:
|
|
39
|
+
- MacOS: `~/Library/Application\ Support/Claude/claude_desktop_config.json`
|
|
40
|
+
- Windows: `%APPDATA%/Claude/claude_desktop_config.json`
|
|
41
|
+
|
|
42
|
+
Configuration:
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"mcpServers": {
|
|
46
|
+
"mcp-atlassian": {
|
|
47
|
+
"command": "uv",
|
|
48
|
+
"args": [
|
|
49
|
+
"--directory",
|
|
50
|
+
"<dir_to>/mcp-atlassian",
|
|
51
|
+
"run",
|
|
52
|
+
"mcp-atlassian"
|
|
53
|
+
],
|
|
54
|
+
"env": {
|
|
55
|
+
"CONFLUENCE_CLOUD_URL": "your_confluence_url",
|
|
56
|
+
"CONFLUENCE_CLOUD_USER": "your_username",
|
|
57
|
+
"CONFLUENCE_CLOUD_TOKEN": "your_api_token"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Development
|
|
65
|
+
|
|
66
|
+
### Building
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Install dependencies
|
|
70
|
+
uv sync
|
|
71
|
+
|
|
72
|
+
# Build package
|
|
73
|
+
uv build
|
|
74
|
+
|
|
75
|
+
# Publish to PyPI
|
|
76
|
+
uv publish
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Debugging
|
|
80
|
+
|
|
81
|
+
Use MCP Inspector:
|
|
82
|
+
```bash
|
|
83
|
+
npx @modelcontextprotocol/inspector uv --directory /path/to/mcp-atlassian run mcp-atlassian
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
View logs:
|
|
87
|
+
```bash
|
|
88
|
+
tail -n 20 -f ~/Library/Logs/Claude/mcp-server-mcp-atlassian.log
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Todo
|
|
92
|
+
|
|
93
|
+
- [ ] Jira integration
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "mcp-atlassian"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "The Model Context Protocol (MCP) Atlassian integration is an open-source implementation that bridges Atlassian products (Jira and Confluence) with AI language models following Anthropic's MCP specification. This project enables secure, contextual AI interactions with Atlassian tools while maintaining data privacy and security. Key features include:"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.13"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"atlassian-python-api>=3.41.16",
|
|
9
|
+
"beautifulsoup4>=4.12.3",
|
|
10
|
+
"httpx>=0.28.0",
|
|
11
|
+
"mcp>=1.0.0",
|
|
12
|
+
"python-dotenv>=1.0.1",
|
|
13
|
+
]
|
|
14
|
+
[[project.authors]]
|
|
15
|
+
name = "sooperset"
|
|
16
|
+
email = "soomiles.dev@gmail.com"
|
|
17
|
+
|
|
18
|
+
[build-system]
|
|
19
|
+
requires = [ "hatchling",]
|
|
20
|
+
build-backend = "hatchling.build"
|
|
21
|
+
|
|
22
|
+
[project.scripts]
|
|
23
|
+
mcp-atlassian = "mcp_atlassian:main"
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Dict, Optional
|
|
5
|
+
|
|
6
|
+
from atlassian import Confluence
|
|
7
|
+
from bs4 import BeautifulSoup
|
|
8
|
+
from dotenv import load_dotenv
|
|
9
|
+
|
|
10
|
+
# Load environment variables
|
|
11
|
+
load_dotenv()
|
|
12
|
+
|
|
13
|
+
# Configure logging
|
|
14
|
+
logger = logging.getLogger("mcp-atlassian")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class Document:
|
|
19
|
+
"""Class to represent a document with content and metadata."""
|
|
20
|
+
|
|
21
|
+
page_content: str
|
|
22
|
+
metadata: Dict[str, any]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ConfluenceFetcher:
|
|
26
|
+
"""Handles fetching and parsing content from Confluence."""
|
|
27
|
+
|
|
28
|
+
def __init__(self):
|
|
29
|
+
self.url = os.getenv("CONFLUENCE_CLOUD_URL")
|
|
30
|
+
self.username = os.getenv("CONFLUENCE_CLOUD_USER")
|
|
31
|
+
self.api_key = os.getenv("CONFLUENCE_CLOUD_TOKEN")
|
|
32
|
+
|
|
33
|
+
if not all([self.url, self.username, self.api_key]):
|
|
34
|
+
raise ValueError("Missing required Confluence environment variables")
|
|
35
|
+
|
|
36
|
+
self.confluence = Confluence(url=self.url, username=self.username, password=self.api_key, cloud=True)
|
|
37
|
+
|
|
38
|
+
def _clean_html_content(self, html_content: str) -> str:
|
|
39
|
+
"""Clean HTML content and return plain text."""
|
|
40
|
+
soup = BeautifulSoup(html_content, "html.parser")
|
|
41
|
+
return soup.get_text(separator=" ", strip=True)
|
|
42
|
+
|
|
43
|
+
def get_spaces(self, start: int = 0, limit: int = 10):
|
|
44
|
+
"""Get all available spaces."""
|
|
45
|
+
return self.confluence.get_all_spaces(start=start, limit=limit)
|
|
46
|
+
|
|
47
|
+
def get_page_content(self, page_id: str, clean_html: bool = True) -> Document:
|
|
48
|
+
"""Get content of a specific page."""
|
|
49
|
+
page = self.confluence.get_page_by_id(page_id=page_id, expand="body.storage,version")
|
|
50
|
+
|
|
51
|
+
content = page["body"]["storage"]["value"]
|
|
52
|
+
if clean_html:
|
|
53
|
+
content = self._clean_html_content(content)
|
|
54
|
+
|
|
55
|
+
metadata = {
|
|
56
|
+
"page_id": page_id,
|
|
57
|
+
"title": page["title"],
|
|
58
|
+
"version": page.get("version", {}).get("number"),
|
|
59
|
+
"url": f"{self.url}/wiki/spaces/{page.get('space', {}).get('key')}/pages/{page_id}",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return Document(page_content=content, metadata=metadata)
|
|
63
|
+
|
|
64
|
+
def get_page_by_title(self, space_key: str, title: str, clean_html: bool = True) -> Optional[Document]:
|
|
65
|
+
"""Get page content by space key and title."""
|
|
66
|
+
try:
|
|
67
|
+
page = self.confluence.get_page_by_title(space=space_key, title=title, expand="body.storage,version")
|
|
68
|
+
|
|
69
|
+
if not page:
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
content = page["body"]["storage"]["value"]
|
|
73
|
+
if clean_html:
|
|
74
|
+
content = self._clean_html_content(content)
|
|
75
|
+
|
|
76
|
+
metadata = {
|
|
77
|
+
"page_id": page["id"],
|
|
78
|
+
"title": page["title"],
|
|
79
|
+
"version": page.get("version", {}).get("number"),
|
|
80
|
+
"space_key": space_key,
|
|
81
|
+
"url": f"{self.url}/wiki/spaces/{space_key}/pages/{page['id']}",
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return Document(page_content=content, metadata=metadata)
|
|
85
|
+
|
|
86
|
+
except Exception as e:
|
|
87
|
+
logger.error(f"Error fetching page: {str(e)}")
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
def get_space_pages(
|
|
91
|
+
self, space_key: str, start: int = 0, limit: int = 10, clean_html: bool = True
|
|
92
|
+
) -> list[Document]:
|
|
93
|
+
"""Get all pages from a specific space."""
|
|
94
|
+
pages = self.confluence.get_all_pages_from_space(
|
|
95
|
+
space=space_key, start=start, limit=limit, expand="body.storage"
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
documents = []
|
|
99
|
+
for page in pages:
|
|
100
|
+
content = page["body"]["storage"]["value"]
|
|
101
|
+
if clean_html:
|
|
102
|
+
content = self._clean_html_content(content)
|
|
103
|
+
|
|
104
|
+
metadata = {
|
|
105
|
+
"page_id": page["id"],
|
|
106
|
+
"title": page["title"],
|
|
107
|
+
"space_key": space_key,
|
|
108
|
+
"version": page.get("version", {}).get("number"),
|
|
109
|
+
"url": f"{self.url}/wiki/spaces/{space_key}/pages/{page['id']}",
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
documents.append(Document(page_content=content, metadata=metadata))
|
|
113
|
+
|
|
114
|
+
return documents
|
|
115
|
+
|
|
116
|
+
def get_page_comments(self, page_id: str, clean_html: bool = True) -> list[Document]:
|
|
117
|
+
"""Get all comments for a specific page."""
|
|
118
|
+
comments = self.confluence.get_page_comments(content_id=page_id, expand="body.view.value", depth="all")[
|
|
119
|
+
"results"
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
comment_documents = []
|
|
123
|
+
for comment in comments:
|
|
124
|
+
body = comment["body"]["view"]["value"]
|
|
125
|
+
if clean_html:
|
|
126
|
+
body = self._clean_html_content(body)
|
|
127
|
+
|
|
128
|
+
metadata = {
|
|
129
|
+
"page_id": page_id,
|
|
130
|
+
"comment_id": comment["id"],
|
|
131
|
+
"created": comment.get("created"),
|
|
132
|
+
"type": "comment",
|
|
133
|
+
"author": comment.get("author", {}).get("displayName"),
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
comment_documents.append(Document(page_content=body, metadata=metadata))
|
|
137
|
+
|
|
138
|
+
return comment_documents
|
|
139
|
+
|
|
140
|
+
def search(self, cql: str, limit: int = 10, clean_html: bool = True) -> list[Document]:
|
|
141
|
+
"""Search content using Confluence Query Language (CQL)."""
|
|
142
|
+
results = self.confluence.cql(cql=cql, limit=limit, expand="body.storage")
|
|
143
|
+
|
|
144
|
+
documents = []
|
|
145
|
+
for result in results.get("results", []):
|
|
146
|
+
content = result.get("content", {})
|
|
147
|
+
if content.get("type") == "page":
|
|
148
|
+
doc = self.get_page_content(content["id"], clean_html)
|
|
149
|
+
# Add page ID to metadata if not already present
|
|
150
|
+
if "page_id" not in doc.metadata:
|
|
151
|
+
doc.metadata["page_id"] = content["id"]
|
|
152
|
+
documents.append(doc)
|
|
153
|
+
|
|
154
|
+
return documents
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from mcp.server import Server
|
|
7
|
+
from mcp.types import Resource, TextContent, Tool
|
|
8
|
+
from pydantic import AnyUrl
|
|
9
|
+
|
|
10
|
+
from .confluence import ConfluenceFetcher
|
|
11
|
+
|
|
12
|
+
# Configure logging
|
|
13
|
+
logging.basicConfig(level=logging.INFO)
|
|
14
|
+
logger = logging.getLogger("mcp-atlassian")
|
|
15
|
+
|
|
16
|
+
# Initialize the content fetcher
|
|
17
|
+
fetcher = ConfluenceFetcher()
|
|
18
|
+
app = Server("mcp-atlassian")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@app.list_resources()
|
|
22
|
+
async def list_resources() -> list[Resource]:
|
|
23
|
+
"""List available Confluence spaces as resources."""
|
|
24
|
+
spaces = fetcher.get_spaces()
|
|
25
|
+
return [
|
|
26
|
+
Resource(
|
|
27
|
+
uri=AnyUrl(f"confluence://{space['key']}"),
|
|
28
|
+
name=f"Confluence Space: {space['name']}",
|
|
29
|
+
mimeType="text/plain",
|
|
30
|
+
description=space.get("description", {}).get("plain", {}).get("value", ""),
|
|
31
|
+
)
|
|
32
|
+
for space in spaces
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@app.read_resource()
|
|
37
|
+
async def read_resource(uri: AnyUrl) -> str:
|
|
38
|
+
"""Read content from Confluence."""
|
|
39
|
+
parts = str(uri).replace("confluence://", "").split("/")
|
|
40
|
+
|
|
41
|
+
# Handle space listing
|
|
42
|
+
if len(parts) == 1:
|
|
43
|
+
space_key = parts[0]
|
|
44
|
+
documents = fetcher.get_space_pages(space_key)
|
|
45
|
+
content = []
|
|
46
|
+
for doc in documents:
|
|
47
|
+
content.append(f"# {doc.metadata['title']}\n\n{doc.page_content}\n---")
|
|
48
|
+
return "\n\n".join(content)
|
|
49
|
+
|
|
50
|
+
# Handle specific page
|
|
51
|
+
elif len(parts) >= 3 and parts[1] == "pages":
|
|
52
|
+
space_key = parts[0]
|
|
53
|
+
title = parts[2]
|
|
54
|
+
doc = fetcher.get_page_by_title(space_key, title)
|
|
55
|
+
|
|
56
|
+
if not doc:
|
|
57
|
+
raise ValueError(f"Page not found: {title}")
|
|
58
|
+
|
|
59
|
+
return doc.page_content
|
|
60
|
+
|
|
61
|
+
raise ValueError(f"Invalid resource URI: {uri}")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@app.list_tools()
|
|
65
|
+
async def list_tools() -> list[Tool]:
|
|
66
|
+
"""List available Confluence tools."""
|
|
67
|
+
return [
|
|
68
|
+
Tool(
|
|
69
|
+
name="search_confluence",
|
|
70
|
+
description="Search Confluence content using CQL",
|
|
71
|
+
inputSchema={
|
|
72
|
+
"type": "object",
|
|
73
|
+
"properties": {
|
|
74
|
+
"query": {"type": "string", "description": "CQL query string (e.g. 'type=page AND space=DEV')"},
|
|
75
|
+
"limit": {
|
|
76
|
+
"type": "number",
|
|
77
|
+
"description": "Maximum number of results (1-50)",
|
|
78
|
+
"default": 10,
|
|
79
|
+
"minimum": 1,
|
|
80
|
+
"maximum": 50,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
"required": ["query"],
|
|
84
|
+
},
|
|
85
|
+
),
|
|
86
|
+
Tool(
|
|
87
|
+
name="get_page_content",
|
|
88
|
+
description="Get content of a specific Confluence page by ID",
|
|
89
|
+
inputSchema={
|
|
90
|
+
"type": "object",
|
|
91
|
+
"properties": {
|
|
92
|
+
"page_id": {"type": "string", "description": "Confluence page ID"},
|
|
93
|
+
"include_metadata": {
|
|
94
|
+
"type": "boolean",
|
|
95
|
+
"description": "Whether to include page metadata",
|
|
96
|
+
"default": True,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
"required": ["page_id"],
|
|
100
|
+
},
|
|
101
|
+
),
|
|
102
|
+
Tool(
|
|
103
|
+
name="get_page_comments",
|
|
104
|
+
description="Get comments for a specific Confluence page",
|
|
105
|
+
inputSchema={
|
|
106
|
+
"type": "object",
|
|
107
|
+
"properties": {"page_id": {"type": "string", "description": "Confluence page ID"}},
|
|
108
|
+
"required": ["page_id"],
|
|
109
|
+
},
|
|
110
|
+
),
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@app.call_tool()
|
|
115
|
+
async def call_tool(name: str, arguments: Any) -> Sequence[TextContent]:
|
|
116
|
+
"""Handle tool calls for Confluence operations."""
|
|
117
|
+
try:
|
|
118
|
+
if name == "search_confluence":
|
|
119
|
+
limit = min(int(arguments.get("limit", 10)), 50)
|
|
120
|
+
documents = fetcher.search(arguments["query"], limit)
|
|
121
|
+
search_results = [
|
|
122
|
+
{
|
|
123
|
+
"page_id": doc.metadata["page_id"],
|
|
124
|
+
"title": doc.metadata["title"],
|
|
125
|
+
"space": doc.metadata.get("space_key"),
|
|
126
|
+
"excerpt": doc.page_content[:500] + "...",
|
|
127
|
+
"url": doc.metadata.get("url", ""),
|
|
128
|
+
}
|
|
129
|
+
for doc in documents
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
return [TextContent(type="text", text=json.dumps(search_results, indent=2))]
|
|
133
|
+
|
|
134
|
+
elif name == "get_page_content":
|
|
135
|
+
doc = fetcher.get_page_content(arguments["page_id"])
|
|
136
|
+
include_metadata = arguments.get("include_metadata", True)
|
|
137
|
+
|
|
138
|
+
if include_metadata:
|
|
139
|
+
result = {"content": doc.page_content, "metadata": doc.metadata}
|
|
140
|
+
else:
|
|
141
|
+
result = {"content": doc.page_content}
|
|
142
|
+
|
|
143
|
+
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
|
144
|
+
|
|
145
|
+
elif name == "get_page_comments":
|
|
146
|
+
comments = fetcher.get_page_comments(arguments["page_id"])
|
|
147
|
+
formatted_comments = [
|
|
148
|
+
{
|
|
149
|
+
"author": comment.metadata["author"],
|
|
150
|
+
"created": comment.metadata["created"],
|
|
151
|
+
"content": comment.page_content,
|
|
152
|
+
}
|
|
153
|
+
for comment in comments
|
|
154
|
+
]
|
|
155
|
+
|
|
156
|
+
return [TextContent(type="text", text=json.dumps(formatted_comments, indent=2))]
|
|
157
|
+
|
|
158
|
+
raise ValueError(f"Unknown tool: {name}")
|
|
159
|
+
|
|
160
|
+
except Exception as e:
|
|
161
|
+
logger.error(f"Tool execution error: {str(e)}")
|
|
162
|
+
raise RuntimeError(f"Tool execution failed: {str(e)}")
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
async def main():
|
|
166
|
+
# Import here to avoid issues with event loops
|
|
167
|
+
from mcp.server.stdio import stdio_server
|
|
168
|
+
|
|
169
|
+
async with stdio_server() as (read_stream, write_stream):
|
|
170
|
+
await app.run(read_stream, write_stream, app.create_initialization_options())
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
if __name__ == "__main__":
|
|
174
|
+
import asyncio
|
|
175
|
+
|
|
176
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
requires-python = ">=3.13"
|
|
3
|
+
|
|
4
|
+
[[package]]
|
|
5
|
+
name = "annotated-types"
|
|
6
|
+
version = "0.7.0"
|
|
7
|
+
source = { registry = "https://pypi.org/simple" }
|
|
8
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
|
|
9
|
+
wheels = [
|
|
10
|
+
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
[[package]]
|
|
14
|
+
name = "anyio"
|
|
15
|
+
version = "4.6.2.post1"
|
|
16
|
+
source = { registry = "https://pypi.org/simple" }
|
|
17
|
+
dependencies = [
|
|
18
|
+
{ name = "idna" },
|
|
19
|
+
{ name = "sniffio" },
|
|
20
|
+
]
|
|
21
|
+
sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 }
|
|
22
|
+
wheels = [
|
|
23
|
+
{ url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 },
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[[package]]
|
|
27
|
+
name = "atlassian-python-api"
|
|
28
|
+
version = "3.41.16"
|
|
29
|
+
source = { registry = "https://pypi.org/simple" }
|
|
30
|
+
dependencies = [
|
|
31
|
+
{ name = "beautifulsoup4" },
|
|
32
|
+
{ name = "deprecated" },
|
|
33
|
+
{ name = "jmespath" },
|
|
34
|
+
{ name = "oauthlib" },
|
|
35
|
+
{ name = "requests" },
|
|
36
|
+
{ name = "requests-oauthlib" },
|
|
37
|
+
{ name = "six" },
|
|
38
|
+
]
|
|
39
|
+
sdist = { url = "https://files.pythonhosted.org/packages/9a/04/15839ae4b60f8f15195a75bf512ab926374832affdbd83463da8edae2b62/atlassian_python_api-3.41.16.tar.gz", hash = "sha256:dc0144ff8b8884562bb2af650586292524ad25f120cd21940df80f0d2ac64411", size = 382425 }
|
|
40
|
+
wheels = [
|
|
41
|
+
{ url = "https://files.pythonhosted.org/packages/28/5b/73d6e52274fa35c3a08f62336945b49eedd50aa02c6929f1ed62ae5874c2/atlassian_python_api-3.41.16-py3-none-any.whl", hash = "sha256:99e5587233a96d22c45a61b19523dd98e8266c620ba2d289f23e4ea35c9cf316", size = 177883 },
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[[package]]
|
|
45
|
+
name = "beautifulsoup4"
|
|
46
|
+
version = "4.12.3"
|
|
47
|
+
source = { registry = "https://pypi.org/simple" }
|
|
48
|
+
dependencies = [
|
|
49
|
+
{ name = "soupsieve" },
|
|
50
|
+
]
|
|
51
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 }
|
|
52
|
+
wheels = [
|
|
53
|
+
{ url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 },
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[[package]]
|
|
57
|
+
name = "certifi"
|
|
58
|
+
version = "2024.8.30"
|
|
59
|
+
source = { registry = "https://pypi.org/simple" }
|
|
60
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 }
|
|
61
|
+
wheels = [
|
|
62
|
+
{ url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 },
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[[package]]
|
|
66
|
+
name = "charset-normalizer"
|
|
67
|
+
version = "3.4.0"
|
|
68
|
+
source = { registry = "https://pypi.org/simple" }
|
|
69
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 }
|
|
70
|
+
wheels = [
|
|
71
|
+
{ url = "https://files.pythonhosted.org/packages/f3/89/68a4c86f1a0002810a27f12e9a7b22feb198c59b2f05231349fbce5c06f4/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", size = 194617 },
|
|
72
|
+
{ url = "https://files.pythonhosted.org/packages/4f/cd/8947fe425e2ab0aa57aceb7807af13a0e4162cd21eee42ef5b053447edf5/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", size = 125310 },
|
|
73
|
+
{ url = "https://files.pythonhosted.org/packages/5b/f0/b5263e8668a4ee9becc2b451ed909e9c27058337fda5b8c49588183c267a/charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", size = 119126 },
|
|
74
|
+
{ url = "https://files.pythonhosted.org/packages/ff/6e/e445afe4f7fda27a533f3234b627b3e515a1b9429bc981c9a5e2aa5d97b6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", size = 139342 },
|
|
75
|
+
{ url = "https://files.pythonhosted.org/packages/a1/b2/4af9993b532d93270538ad4926c8e37dc29f2111c36f9c629840c57cd9b3/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", size = 149383 },
|
|
76
|
+
{ url = "https://files.pythonhosted.org/packages/fb/6f/4e78c3b97686b871db9be6f31d64e9264e889f8c9d7ab33c771f847f79b7/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", size = 142214 },
|
|
77
|
+
{ url = "https://files.pythonhosted.org/packages/2b/c9/1c8fe3ce05d30c87eff498592c89015b19fade13df42850aafae09e94f35/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", size = 144104 },
|
|
78
|
+
{ url = "https://files.pythonhosted.org/packages/ee/68/efad5dcb306bf37db7db338338e7bb8ebd8cf38ee5bbd5ceaaaa46f257e6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", size = 146255 },
|
|
79
|
+
{ url = "https://files.pythonhosted.org/packages/0c/75/1ed813c3ffd200b1f3e71121c95da3f79e6d2a96120163443b3ad1057505/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", size = 140251 },
|
|
80
|
+
{ url = "https://files.pythonhosted.org/packages/7d/0d/6f32255c1979653b448d3c709583557a4d24ff97ac4f3a5be156b2e6a210/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", size = 148474 },
|
|
81
|
+
{ url = "https://files.pythonhosted.org/packages/ac/a0/c1b5298de4670d997101fef95b97ac440e8c8d8b4efa5a4d1ef44af82f0d/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", size = 151849 },
|
|
82
|
+
{ url = "https://files.pythonhosted.org/packages/04/4f/b3961ba0c664989ba63e30595a3ed0875d6790ff26671e2aae2fdc28a399/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", size = 149781 },
|
|
83
|
+
{ url = "https://files.pythonhosted.org/packages/d8/90/6af4cd042066a4adad58ae25648a12c09c879efa4849c705719ba1b23d8c/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482", size = 144970 },
|
|
84
|
+
{ url = "https://files.pythonhosted.org/packages/cc/67/e5e7e0cbfefc4ca79025238b43cdf8a2037854195b37d6417f3d0895c4c2/charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", size = 94973 },
|
|
85
|
+
{ url = "https://files.pythonhosted.org/packages/65/97/fc9bbc54ee13d33dc54a7fcf17b26368b18505500fc01e228c27b5222d80/charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", size = 102308 },
|
|
86
|
+
{ url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 },
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
[[package]]
|
|
90
|
+
name = "click"
|
|
91
|
+
version = "8.1.7"
|
|
92
|
+
source = { registry = "https://pypi.org/simple" }
|
|
93
|
+
dependencies = [
|
|
94
|
+
{ name = "colorama", marker = "platform_system == 'Windows'" },
|
|
95
|
+
]
|
|
96
|
+
sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 }
|
|
97
|
+
wheels = [
|
|
98
|
+
{ url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 },
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
[[package]]
|
|
102
|
+
name = "colorama"
|
|
103
|
+
version = "0.4.6"
|
|
104
|
+
source = { registry = "https://pypi.org/simple" }
|
|
105
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
|
|
106
|
+
wheels = [
|
|
107
|
+
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
[[package]]
|
|
111
|
+
name = "deprecated"
|
|
112
|
+
version = "1.2.15"
|
|
113
|
+
source = { registry = "https://pypi.org/simple" }
|
|
114
|
+
dependencies = [
|
|
115
|
+
{ name = "wrapt" },
|
|
116
|
+
]
|
|
117
|
+
sdist = { url = "https://files.pythonhosted.org/packages/2e/a3/53e7d78a6850ffdd394d7048a31a6f14e44900adedf190f9a165f6b69439/deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d", size = 2977612 }
|
|
118
|
+
wheels = [
|
|
119
|
+
{ url = "https://files.pythonhosted.org/packages/1d/8f/c7f227eb42cfeaddce3eb0c96c60cbca37797fa7b34f8e1aeadf6c5c0983/Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320", size = 9941 },
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
[[package]]
|
|
123
|
+
name = "h11"
|
|
124
|
+
version = "0.14.0"
|
|
125
|
+
source = { registry = "https://pypi.org/simple" }
|
|
126
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
|
|
127
|
+
wheels = [
|
|
128
|
+
{ url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
[[package]]
|
|
132
|
+
name = "httpcore"
|
|
133
|
+
version = "1.0.7"
|
|
134
|
+
source = { registry = "https://pypi.org/simple" }
|
|
135
|
+
dependencies = [
|
|
136
|
+
{ name = "certifi" },
|
|
137
|
+
{ name = "h11" },
|
|
138
|
+
]
|
|
139
|
+
sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 }
|
|
140
|
+
wheels = [
|
|
141
|
+
{ url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 },
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
[[package]]
|
|
145
|
+
name = "httpx"
|
|
146
|
+
version = "0.28.0"
|
|
147
|
+
source = { registry = "https://pypi.org/simple" }
|
|
148
|
+
dependencies = [
|
|
149
|
+
{ name = "anyio" },
|
|
150
|
+
{ name = "certifi" },
|
|
151
|
+
{ name = "httpcore" },
|
|
152
|
+
{ name = "idna" },
|
|
153
|
+
]
|
|
154
|
+
sdist = { url = "https://files.pythonhosted.org/packages/10/df/676b7cf674dd1bdc71a64ad393c89879f75e4a0ab8395165b498262ae106/httpx-0.28.0.tar.gz", hash = "sha256:0858d3bab51ba7e386637f22a61d8ccddaeec5f3fe4209da3a6168dbb91573e0", size = 141307 }
|
|
155
|
+
wheels = [
|
|
156
|
+
{ url = "https://files.pythonhosted.org/packages/8f/fb/a19866137577ba60c6d8b69498dc36be479b13ba454f691348ddf428f185/httpx-0.28.0-py3-none-any.whl", hash = "sha256:dc0b419a0cfeb6e8b34e85167c0da2671206f5095f1baa9663d23bcfd6b535fc", size = 73551 },
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
[[package]]
|
|
160
|
+
name = "httpx-sse"
|
|
161
|
+
version = "0.4.0"
|
|
162
|
+
source = { registry = "https://pypi.org/simple" }
|
|
163
|
+
sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
|
|
164
|
+
wheels = [
|
|
165
|
+
{ url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 },
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
[[package]]
|
|
169
|
+
name = "idna"
|
|
170
|
+
version = "3.10"
|
|
171
|
+
source = { registry = "https://pypi.org/simple" }
|
|
172
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
|
|
173
|
+
wheels = [
|
|
174
|
+
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
|
|
175
|
+
]
|
|
176
|
+
|
|
177
|
+
[[package]]
|
|
178
|
+
name = "jmespath"
|
|
179
|
+
version = "1.0.1"
|
|
180
|
+
source = { registry = "https://pypi.org/simple" }
|
|
181
|
+
sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843 }
|
|
182
|
+
wheels = [
|
|
183
|
+
{ url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256 },
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
[[package]]
|
|
187
|
+
name = "mcp"
|
|
188
|
+
version = "1.0.0"
|
|
189
|
+
source = { registry = "https://pypi.org/simple" }
|
|
190
|
+
dependencies = [
|
|
191
|
+
{ name = "anyio" },
|
|
192
|
+
{ name = "httpx" },
|
|
193
|
+
{ name = "httpx-sse" },
|
|
194
|
+
{ name = "pydantic" },
|
|
195
|
+
{ name = "sse-starlette" },
|
|
196
|
+
{ name = "starlette" },
|
|
197
|
+
]
|
|
198
|
+
sdist = { url = "https://files.pythonhosted.org/packages/97/de/a9ec0a1b6439f90ea59f89004bb2e7ec6890dfaeef809751d9e6577dca7e/mcp-1.0.0.tar.gz", hash = "sha256:dba51ce0b5c6a80e25576f606760c49a91ee90210fed805b530ca165d3bbc9b7", size = 82891 }
|
|
199
|
+
wheels = [
|
|
200
|
+
{ url = "https://files.pythonhosted.org/packages/56/89/900c0c8445ec001d3725e475fc553b0feb2e8a51be018f3bb7de51e683db/mcp-1.0.0-py3-none-any.whl", hash = "sha256:bbe70ffa3341cd4da78b5eb504958355c68381fb29971471cea1e642a2af5b8a", size = 36361 },
|
|
201
|
+
]
|
|
202
|
+
|
|
203
|
+
[[package]]
|
|
204
|
+
name = "mcp-atlassian"
|
|
205
|
+
version = "0.1.0"
|
|
206
|
+
source = { editable = "." }
|
|
207
|
+
dependencies = [
|
|
208
|
+
{ name = "atlassian-python-api" },
|
|
209
|
+
{ name = "beautifulsoup4" },
|
|
210
|
+
{ name = "httpx" },
|
|
211
|
+
{ name = "mcp" },
|
|
212
|
+
{ name = "python-dotenv" },
|
|
213
|
+
]
|
|
214
|
+
|
|
215
|
+
[package.metadata]
|
|
216
|
+
requires-dist = [
|
|
217
|
+
{ name = "atlassian-python-api", specifier = ">=3.41.16" },
|
|
218
|
+
{ name = "beautifulsoup4", specifier = ">=4.12.3" },
|
|
219
|
+
{ name = "httpx", specifier = ">=0.28.0" },
|
|
220
|
+
{ name = "mcp", specifier = ">=1.0.0" },
|
|
221
|
+
{ name = "python-dotenv", specifier = ">=1.0.1" },
|
|
222
|
+
]
|
|
223
|
+
|
|
224
|
+
[[package]]
|
|
225
|
+
name = "oauthlib"
|
|
226
|
+
version = "3.2.2"
|
|
227
|
+
source = { registry = "https://pypi.org/simple" }
|
|
228
|
+
sdist = { url = "https://files.pythonhosted.org/packages/6d/fa/fbf4001037904031639e6bfbfc02badfc7e12f137a8afa254df6c4c8a670/oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918", size = 177352 }
|
|
229
|
+
wheels = [
|
|
230
|
+
{ url = "https://files.pythonhosted.org/packages/7e/80/cab10959dc1faead58dc8384a781dfbf93cb4d33d50988f7a69f1b7c9bbe/oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", size = 151688 },
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
[[package]]
|
|
234
|
+
name = "pydantic"
|
|
235
|
+
version = "2.10.2"
|
|
236
|
+
source = { registry = "https://pypi.org/simple" }
|
|
237
|
+
dependencies = [
|
|
238
|
+
{ name = "annotated-types" },
|
|
239
|
+
{ name = "pydantic-core" },
|
|
240
|
+
{ name = "typing-extensions" },
|
|
241
|
+
]
|
|
242
|
+
sdist = { url = "https://files.pythonhosted.org/packages/41/86/a03390cb12cf64e2a8df07c267f3eb8d5035e0f9a04bb20fb79403d2a00e/pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa", size = 785401 }
|
|
243
|
+
wheels = [
|
|
244
|
+
{ url = "https://files.pythonhosted.org/packages/d5/74/da832196702d0c56eb86b75bfa346db9238617e29b0b7ee3b8b4eccfe654/pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e", size = 456364 },
|
|
245
|
+
]
|
|
246
|
+
|
|
247
|
+
[[package]]
|
|
248
|
+
name = "pydantic-core"
|
|
249
|
+
version = "2.27.1"
|
|
250
|
+
source = { registry = "https://pypi.org/simple" }
|
|
251
|
+
dependencies = [
|
|
252
|
+
{ name = "typing-extensions" },
|
|
253
|
+
]
|
|
254
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a6/9f/7de1f19b6aea45aeb441838782d68352e71bfa98ee6fa048d5041991b33e/pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235", size = 412785 }
|
|
255
|
+
wheels = [
|
|
256
|
+
{ url = "https://files.pythonhosted.org/packages/0f/d6/91cb99a3c59d7b072bded9959fbeab0a9613d5a4935773c0801f1764c156/pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073", size = 1895033 },
|
|
257
|
+
{ url = "https://files.pythonhosted.org/packages/07/42/d35033f81a28b27dedcade9e967e8a40981a765795c9ebae2045bcef05d3/pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08", size = 1807542 },
|
|
258
|
+
{ url = "https://files.pythonhosted.org/packages/41/c2/491b59e222ec7e72236e512108ecad532c7f4391a14e971c963f624f7569/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf", size = 1827854 },
|
|
259
|
+
{ url = "https://files.pythonhosted.org/packages/e3/f3/363652651779113189cefdbbb619b7b07b7a67ebb6840325117cc8cc3460/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737", size = 1857389 },
|
|
260
|
+
{ url = "https://files.pythonhosted.org/packages/5f/97/be804aed6b479af5a945daec7538d8bf358d668bdadde4c7888a2506bdfb/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2", size = 2037934 },
|
|
261
|
+
{ url = "https://files.pythonhosted.org/packages/42/01/295f0bd4abf58902917e342ddfe5f76cf66ffabfc57c2e23c7681a1a1197/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107", size = 2735176 },
|
|
262
|
+
{ url = "https://files.pythonhosted.org/packages/9d/a0/cd8e9c940ead89cc37812a1a9f310fef59ba2f0b22b4e417d84ab09fa970/pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51", size = 2160720 },
|
|
263
|
+
{ url = "https://files.pythonhosted.org/packages/73/ae/9d0980e286627e0aeca4c352a60bd760331622c12d576e5ea4441ac7e15e/pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a", size = 1992972 },
|
|
264
|
+
{ url = "https://files.pythonhosted.org/packages/bf/ba/ae4480bc0292d54b85cfb954e9d6bd226982949f8316338677d56541b85f/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc", size = 2001477 },
|
|
265
|
+
{ url = "https://files.pythonhosted.org/packages/55/b7/e26adf48c2f943092ce54ae14c3c08d0d221ad34ce80b18a50de8ed2cba8/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960", size = 2091186 },
|
|
266
|
+
{ url = "https://files.pythonhosted.org/packages/ba/cc/8491fff5b608b3862eb36e7d29d36a1af1c945463ca4c5040bf46cc73f40/pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23", size = 2154429 },
|
|
267
|
+
{ url = "https://files.pythonhosted.org/packages/78/d8/c080592d80edd3441ab7f88f865f51dae94a157fc64283c680e9f32cf6da/pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05", size = 1833713 },
|
|
268
|
+
{ url = "https://files.pythonhosted.org/packages/83/84/5ab82a9ee2538ac95a66e51f6838d6aba6e0a03a42aa185ad2fe404a4e8f/pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337", size = 1987897 },
|
|
269
|
+
{ url = "https://files.pythonhosted.org/packages/df/c3/b15fb833926d91d982fde29c0624c9f225da743c7af801dace0d4e187e71/pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5", size = 1882983 },
|
|
270
|
+
]
|
|
271
|
+
|
|
272
|
+
[[package]]
|
|
273
|
+
name = "python-dotenv"
|
|
274
|
+
version = "1.0.1"
|
|
275
|
+
source = { registry = "https://pypi.org/simple" }
|
|
276
|
+
sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 }
|
|
277
|
+
wheels = [
|
|
278
|
+
{ url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 },
|
|
279
|
+
]
|
|
280
|
+
|
|
281
|
+
[[package]]
|
|
282
|
+
name = "requests"
|
|
283
|
+
version = "2.32.3"
|
|
284
|
+
source = { registry = "https://pypi.org/simple" }
|
|
285
|
+
dependencies = [
|
|
286
|
+
{ name = "certifi" },
|
|
287
|
+
{ name = "charset-normalizer" },
|
|
288
|
+
{ name = "idna" },
|
|
289
|
+
{ name = "urllib3" },
|
|
290
|
+
]
|
|
291
|
+
sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 }
|
|
292
|
+
wheels = [
|
|
293
|
+
{ url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 },
|
|
294
|
+
]
|
|
295
|
+
|
|
296
|
+
[[package]]
|
|
297
|
+
name = "requests-oauthlib"
|
|
298
|
+
version = "2.0.0"
|
|
299
|
+
source = { registry = "https://pypi.org/simple" }
|
|
300
|
+
dependencies = [
|
|
301
|
+
{ name = "oauthlib" },
|
|
302
|
+
{ name = "requests" },
|
|
303
|
+
]
|
|
304
|
+
sdist = { url = "https://files.pythonhosted.org/packages/42/f2/05f29bc3913aea15eb670be136045bf5c5bbf4b99ecb839da9b422bb2c85/requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9", size = 55650 }
|
|
305
|
+
wheels = [
|
|
306
|
+
{ url = "https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", size = 24179 },
|
|
307
|
+
]
|
|
308
|
+
|
|
309
|
+
[[package]]
|
|
310
|
+
name = "six"
|
|
311
|
+
version = "1.16.0"
|
|
312
|
+
source = { registry = "https://pypi.org/simple" }
|
|
313
|
+
sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 }
|
|
314
|
+
wheels = [
|
|
315
|
+
{ url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 },
|
|
316
|
+
]
|
|
317
|
+
|
|
318
|
+
[[package]]
|
|
319
|
+
name = "sniffio"
|
|
320
|
+
version = "1.3.1"
|
|
321
|
+
source = { registry = "https://pypi.org/simple" }
|
|
322
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
|
|
323
|
+
wheels = [
|
|
324
|
+
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
|
|
325
|
+
]
|
|
326
|
+
|
|
327
|
+
[[package]]
|
|
328
|
+
name = "soupsieve"
|
|
329
|
+
version = "2.6"
|
|
330
|
+
source = { registry = "https://pypi.org/simple" }
|
|
331
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 }
|
|
332
|
+
wheels = [
|
|
333
|
+
{ url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 },
|
|
334
|
+
]
|
|
335
|
+
|
|
336
|
+
[[package]]
|
|
337
|
+
name = "sse-starlette"
|
|
338
|
+
version = "2.1.3"
|
|
339
|
+
source = { registry = "https://pypi.org/simple" }
|
|
340
|
+
dependencies = [
|
|
341
|
+
{ name = "anyio" },
|
|
342
|
+
{ name = "starlette" },
|
|
343
|
+
{ name = "uvicorn" },
|
|
344
|
+
]
|
|
345
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/fc/56ab9f116b2133521f532fce8d03194cf04dcac25f583cf3d839be4c0496/sse_starlette-2.1.3.tar.gz", hash = "sha256:9cd27eb35319e1414e3d2558ee7414487f9529ce3b3cf9b21434fd110e017169", size = 19678 }
|
|
346
|
+
wheels = [
|
|
347
|
+
{ url = "https://files.pythonhosted.org/packages/52/aa/36b271bc4fa1d2796311ee7c7283a3a1c348bad426d37293609ca4300eef/sse_starlette-2.1.3-py3-none-any.whl", hash = "sha256:8ec846438b4665b9e8c560fcdea6bc8081a3abf7942faa95e5a744999d219772", size = 9383 },
|
|
348
|
+
]
|
|
349
|
+
|
|
350
|
+
[[package]]
|
|
351
|
+
name = "starlette"
|
|
352
|
+
version = "0.41.3"
|
|
353
|
+
source = { registry = "https://pypi.org/simple" }
|
|
354
|
+
dependencies = [
|
|
355
|
+
{ name = "anyio" },
|
|
356
|
+
]
|
|
357
|
+
sdist = { url = "https://files.pythonhosted.org/packages/1a/4c/9b5764bd22eec91c4039ef4c55334e9187085da2d8a2df7bd570869aae18/starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", size = 2574159 }
|
|
358
|
+
wheels = [
|
|
359
|
+
{ url = "https://files.pythonhosted.org/packages/96/00/2b325970b3060c7cecebab6d295afe763365822b1306a12eeab198f74323/starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7", size = 73225 },
|
|
360
|
+
]
|
|
361
|
+
|
|
362
|
+
[[package]]
|
|
363
|
+
name = "typing-extensions"
|
|
364
|
+
version = "4.12.2"
|
|
365
|
+
source = { registry = "https://pypi.org/simple" }
|
|
366
|
+
sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
|
|
367
|
+
wheels = [
|
|
368
|
+
{ url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
|
|
369
|
+
]
|
|
370
|
+
|
|
371
|
+
[[package]]
|
|
372
|
+
name = "urllib3"
|
|
373
|
+
version = "2.2.3"
|
|
374
|
+
source = { registry = "https://pypi.org/simple" }
|
|
375
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 }
|
|
376
|
+
wheels = [
|
|
377
|
+
{ url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 },
|
|
378
|
+
]
|
|
379
|
+
|
|
380
|
+
[[package]]
|
|
381
|
+
name = "uvicorn"
|
|
382
|
+
version = "0.32.1"
|
|
383
|
+
source = { registry = "https://pypi.org/simple" }
|
|
384
|
+
dependencies = [
|
|
385
|
+
{ name = "click" },
|
|
386
|
+
{ name = "h11" },
|
|
387
|
+
]
|
|
388
|
+
sdist = { url = "https://files.pythonhosted.org/packages/6a/3c/21dba3e7d76138725ef307e3d7ddd29b763119b3aa459d02cc05fefcff75/uvicorn-0.32.1.tar.gz", hash = "sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175", size = 77630 }
|
|
389
|
+
wheels = [
|
|
390
|
+
{ url = "https://files.pythonhosted.org/packages/50/c1/2d27b0a15826c2b71dcf6e2f5402181ef85acf439617bb2f1453125ce1f3/uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e", size = 63828 },
|
|
391
|
+
]
|
|
392
|
+
|
|
393
|
+
[[package]]
|
|
394
|
+
name = "wrapt"
|
|
395
|
+
version = "1.17.0"
|
|
396
|
+
source = { registry = "https://pypi.org/simple" }
|
|
397
|
+
sdist = { url = "https://files.pythonhosted.org/packages/24/a1/fc03dca9b0432725c2e8cdbf91a349d2194cf03d8523c124faebe581de09/wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801", size = 55542 }
|
|
398
|
+
wheels = [
|
|
399
|
+
{ url = "https://files.pythonhosted.org/packages/67/9c/38294e1bb92b055222d1b8b6591604ca4468b77b1250f59c15256437644f/wrapt-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181", size = 38904 },
|
|
400
|
+
{ url = "https://files.pythonhosted.org/packages/78/b6/76597fb362cbf8913a481d41b14b049a8813cd402a5d2f84e57957c813ae/wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393", size = 88608 },
|
|
401
|
+
{ url = "https://files.pythonhosted.org/packages/bc/69/b500884e45b3881926b5f69188dc542fb5880019d15c8a0df1ab1dfda1f7/wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4", size = 80879 },
|
|
402
|
+
{ url = "https://files.pythonhosted.org/packages/52/31/f4cc58afe29eab8a50ac5969963010c8b60987e719c478a5024bce39bc42/wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b", size = 89119 },
|
|
403
|
+
{ url = "https://files.pythonhosted.org/packages/aa/9c/05ab6bf75dbae7a9d34975fb6ee577e086c1c26cde3b6cf6051726d33c7c/wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721", size = 86778 },
|
|
404
|
+
{ url = "https://files.pythonhosted.org/packages/0e/6c/4b8d42e3db355603d35fe5c9db79c28f2472a6fd1ccf4dc25ae46739672a/wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90", size = 79793 },
|
|
405
|
+
{ url = "https://files.pythonhosted.org/packages/69/23/90e3a2ee210c0843b2c2a49b3b97ffcf9cad1387cb18cbeef9218631ed5a/wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a", size = 87606 },
|
|
406
|
+
{ url = "https://files.pythonhosted.org/packages/5f/06/3683126491ca787d8d71d8d340e775d40767c5efedb35039d987203393b7/wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045", size = 36651 },
|
|
407
|
+
{ url = "https://files.pythonhosted.org/packages/f1/bc/3bf6d2ca0d2c030d324ef9272bea0a8fdaff68f3d1fa7be7a61da88e51f7/wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838", size = 38835 },
|
|
408
|
+
{ url = "https://files.pythonhosted.org/packages/ce/b5/251165c232d87197a81cd362eeb5104d661a2dd3aa1f0b33e4bf61dda8b8/wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b", size = 40146 },
|
|
409
|
+
{ url = "https://files.pythonhosted.org/packages/89/33/1e1bdd3e866eeb73d8c4755db1ceb8a80d5bd51ee4648b3f2247adec4e67/wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379", size = 113444 },
|
|
410
|
+
{ url = "https://files.pythonhosted.org/packages/9f/7c/94f53b065a43f5dc1fbdd8b80fd8f41284315b543805c956619c0b8d92f0/wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d", size = 101246 },
|
|
411
|
+
{ url = "https://files.pythonhosted.org/packages/62/5d/640360baac6ea6018ed5e34e6e80e33cfbae2aefde24f117587cd5efd4b7/wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f", size = 109320 },
|
|
412
|
+
{ url = "https://files.pythonhosted.org/packages/e3/cf/6c7a00ae86a2e9482c91170aefe93f4ccda06c1ac86c4de637c69133da59/wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c", size = 110193 },
|
|
413
|
+
{ url = "https://files.pythonhosted.org/packages/cd/cc/aa718df0d20287e8f953ce0e2f70c0af0fba1d3c367db7ee8bdc46ea7003/wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b", size = 100460 },
|
|
414
|
+
{ url = "https://files.pythonhosted.org/packages/f7/16/9f3ac99fe1f6caaa789d67b4e3c562898b532c250769f5255fa8b8b93983/wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab", size = 106347 },
|
|
415
|
+
{ url = "https://files.pythonhosted.org/packages/64/85/c77a331b2c06af49a687f8b926fc2d111047a51e6f0b0a4baa01ff3a673a/wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf", size = 37971 },
|
|
416
|
+
{ url = "https://files.pythonhosted.org/packages/05/9b/b2469f8be9efed24283fd7b9eeb8e913e9bc0715cf919ea8645e428ab7af/wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a", size = 40755 },
|
|
417
|
+
{ url = "https://files.pythonhosted.org/packages/4b/d9/a8ba5e9507a9af1917285d118388c5eb7a81834873f45df213a6fe923774/wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371", size = 23592 },
|
|
418
|
+
]
|