devrev-Python-SDK 3.0.3__py3-none-any.whl → 3.1.1__py3-none-any.whl
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.
- devrev_mcp/server.py +1 -0
- devrev_mcp/tools/webhooks.py +153 -0
- devrev_mcp/utils/don_id.py +2 -0
- {devrev_python_sdk-3.0.3.dist-info → devrev_python_sdk-3.1.1.dist-info}/METADATA +4 -4
- {devrev_python_sdk-3.0.3.dist-info → devrev_python_sdk-3.1.1.dist-info}/RECORD +7 -6
- {devrev_python_sdk-3.0.3.dist-info → devrev_python_sdk-3.1.1.dist-info}/WHEEL +1 -1
- {devrev_python_sdk-3.0.3.dist-info → devrev_python_sdk-3.1.1.dist-info}/entry_points.txt +0 -0
devrev_mcp/server.py
CHANGED
|
@@ -249,6 +249,7 @@ from devrev_mcp.tools import slas as _slas_tools # noqa: E402, F401
|
|
|
249
249
|
from devrev_mcp.tools import tags as _tags_tools # noqa: E402, F401
|
|
250
250
|
from devrev_mcp.tools import timeline as _timeline_tools # noqa: E402, F401
|
|
251
251
|
from devrev_mcp.tools import users as _users_tools # noqa: E402, F401
|
|
252
|
+
from devrev_mcp.tools import webhooks as _webhooks_tools # noqa: E402, F401
|
|
252
253
|
from devrev_mcp.tools import works as _works_tools # noqa: E402, F401
|
|
253
254
|
|
|
254
255
|
# Beta tools (only if beta tools are enabled)
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""MCP tools for DevRev webhook operations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from mcp.server.fastmcp import Context
|
|
9
|
+
|
|
10
|
+
from devrev.exceptions import DevRevError
|
|
11
|
+
from devrev.models.webhooks import (
|
|
12
|
+
WebhooksCreateRequest,
|
|
13
|
+
WebhooksDeleteRequest,
|
|
14
|
+
WebhooksGetRequest,
|
|
15
|
+
WebhooksListRequest,
|
|
16
|
+
WebhookStatus,
|
|
17
|
+
WebhooksUpdateRequest,
|
|
18
|
+
)
|
|
19
|
+
from devrev_mcp.server import _config, mcp
|
|
20
|
+
from devrev_mcp.utils.don_id import validate_don_id
|
|
21
|
+
from devrev_mcp.utils.errors import format_devrev_error
|
|
22
|
+
from devrev_mcp.utils.formatting import serialize_model, serialize_models
|
|
23
|
+
from devrev_mcp.utils.pagination import clamp_page_size
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@mcp.tool()
|
|
29
|
+
async def devrev_webhooks_list(
|
|
30
|
+
ctx: Context[Any, Any, Any],
|
|
31
|
+
cursor: str | None = None,
|
|
32
|
+
limit: int | None = None,
|
|
33
|
+
) -> dict[str, Any]:
|
|
34
|
+
"""List DevRev webhooks.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
cursor: Pagination cursor from a previous response.
|
|
38
|
+
limit: Maximum number of items to return (default: 25, max: 100).
|
|
39
|
+
"""
|
|
40
|
+
app = ctx.request_context.lifespan_context
|
|
41
|
+
try:
|
|
42
|
+
request = WebhooksListRequest(
|
|
43
|
+
cursor=cursor,
|
|
44
|
+
limit=clamp_page_size(
|
|
45
|
+
limit, default=app.config.default_page_size, maximum=app.config.max_page_size
|
|
46
|
+
),
|
|
47
|
+
)
|
|
48
|
+
webhooks = await app.get_client().webhooks.list(request)
|
|
49
|
+
items = serialize_models(list(webhooks))
|
|
50
|
+
return {"count": len(items), "webhooks": items}
|
|
51
|
+
except DevRevError as e:
|
|
52
|
+
raise RuntimeError(format_devrev_error(e)) from e
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@mcp.tool()
|
|
56
|
+
async def devrev_webhooks_get(
|
|
57
|
+
ctx: Context[Any, Any, Any],
|
|
58
|
+
id: str,
|
|
59
|
+
) -> dict[str, Any]:
|
|
60
|
+
"""Get a DevRev webhook by ID.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
id: Webhook ID (e.g., "don:integration:dvrv-us-1:devo/1:webhook/123").
|
|
64
|
+
"""
|
|
65
|
+
validate_don_id(id, "webhook", "devrev_webhooks_get")
|
|
66
|
+
app = ctx.request_context.lifespan_context
|
|
67
|
+
try:
|
|
68
|
+
request = WebhooksGetRequest(id=id)
|
|
69
|
+
webhook = await app.get_client().webhooks.get(request)
|
|
70
|
+
return serialize_model(webhook)
|
|
71
|
+
except DevRevError as e:
|
|
72
|
+
raise RuntimeError(format_devrev_error(e)) from e
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# Destructive tools (only registered when enabled)
|
|
76
|
+
if _config.enable_destructive_tools:
|
|
77
|
+
|
|
78
|
+
@mcp.tool()
|
|
79
|
+
async def devrev_webhooks_create(
|
|
80
|
+
ctx: Context[Any, Any, Any],
|
|
81
|
+
url: str,
|
|
82
|
+
event_types: list[str] | None = None,
|
|
83
|
+
secret: str | None = None,
|
|
84
|
+
) -> dict[str, Any]:
|
|
85
|
+
"""Create a new DevRev webhook.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
url: Target URL that will receive webhook event POSTs.
|
|
89
|
+
event_types: Event types to subscribe to (default: all events).
|
|
90
|
+
secret: Shared secret used to sign and verify webhook payloads.
|
|
91
|
+
"""
|
|
92
|
+
app = ctx.request_context.lifespan_context
|
|
93
|
+
try:
|
|
94
|
+
request = WebhooksCreateRequest(url=url, event_types=event_types, secret=secret)
|
|
95
|
+
webhook = await app.get_client().webhooks.create(request)
|
|
96
|
+
return serialize_model(webhook)
|
|
97
|
+
except DevRevError as e:
|
|
98
|
+
raise RuntimeError(format_devrev_error(e)) from e
|
|
99
|
+
|
|
100
|
+
@mcp.tool()
|
|
101
|
+
async def devrev_webhooks_update(
|
|
102
|
+
ctx: Context[Any, Any, Any],
|
|
103
|
+
id: str,
|
|
104
|
+
url: str | None = None,
|
|
105
|
+
event_types: list[str] | None = None,
|
|
106
|
+
status: str | None = None,
|
|
107
|
+
) -> dict[str, Any]:
|
|
108
|
+
"""Update a DevRev webhook.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
id: Webhook ID to update.
|
|
112
|
+
url: New target URL.
|
|
113
|
+
event_types: New list of event types to subscribe to.
|
|
114
|
+
status: New status (active, inactive, unverified).
|
|
115
|
+
"""
|
|
116
|
+
validate_don_id(id, "webhook", "devrev_webhooks_update")
|
|
117
|
+
app = ctx.request_context.lifespan_context
|
|
118
|
+
try:
|
|
119
|
+
resolved_status: WebhookStatus | None = None
|
|
120
|
+
if status is not None:
|
|
121
|
+
try:
|
|
122
|
+
resolved_status = WebhookStatus(status.lower())
|
|
123
|
+
except ValueError as e:
|
|
124
|
+
raise RuntimeError(
|
|
125
|
+
f"Invalid webhook status '{status}'. "
|
|
126
|
+
"Valid values: active, inactive, unverified."
|
|
127
|
+
) from e
|
|
128
|
+
request = WebhooksUpdateRequest(
|
|
129
|
+
id=id, url=url, event_types=event_types, status=resolved_status
|
|
130
|
+
)
|
|
131
|
+
webhook = await app.get_client().webhooks.update(request)
|
|
132
|
+
return serialize_model(webhook)
|
|
133
|
+
except DevRevError as e:
|
|
134
|
+
raise RuntimeError(format_devrev_error(e)) from e
|
|
135
|
+
|
|
136
|
+
@mcp.tool()
|
|
137
|
+
async def devrev_webhooks_delete(
|
|
138
|
+
ctx: Context[Any, Any, Any],
|
|
139
|
+
id: str,
|
|
140
|
+
) -> dict[str, Any]:
|
|
141
|
+
"""Delete a DevRev webhook.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
id: Webhook ID to delete.
|
|
145
|
+
"""
|
|
146
|
+
validate_don_id(id, "webhook", "devrev_webhooks_delete")
|
|
147
|
+
app = ctx.request_context.lifespan_context
|
|
148
|
+
try:
|
|
149
|
+
request = WebhooksDeleteRequest(id=id)
|
|
150
|
+
await app.get_client().webhooks.delete(request)
|
|
151
|
+
return {"deleted": True, "id": id}
|
|
152
|
+
except DevRevError as e:
|
|
153
|
+
raise RuntimeError(format_devrev_error(e)) from e
|
devrev_mcp/utils/don_id.py
CHANGED
|
@@ -35,6 +35,7 @@ DON_TYPE_MAP: dict[str, str] = {
|
|
|
35
35
|
"qa": "question_answer",
|
|
36
36
|
"question_answer": "question_answer",
|
|
37
37
|
"timeline_entry": "timeline_entry",
|
|
38
|
+
"webhook": "webhook",
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
TOOL_SUGGESTIONS: dict[str, str] = {
|
|
@@ -57,6 +58,7 @@ TOOL_SUGGESTIONS: dict[str, str] = {
|
|
|
57
58
|
"qa": "devrev_question_answers_get",
|
|
58
59
|
"question_answer": "devrev_question_answers_get",
|
|
59
60
|
"timeline_entry": "devrev_timeline_get",
|
|
61
|
+
"webhook": "devrev_webhooks_get",
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devrev-Python-SDK
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.1.1
|
|
4
4
|
Summary: A modern, type-safe Python SDK for the DevRev API
|
|
5
5
|
Project-URL: Homepage, https://github.com/mgmonteleone/py-dev-rev
|
|
6
6
|
Project-URL: Documentation, https://github.com/mgmonteleone/py-dev-rev
|
|
@@ -75,7 +75,7 @@ Description-Content-Type: text/markdown
|
|
|
75
75
|
|
|
76
76
|
# py-devrev
|
|
77
77
|
|
|
78
|
-
A modern, type-safe Python SDK for the DevRev API.
|
|
78
|
+
A modern, type-safe Python SDK and MCP for the DevRev API.
|
|
79
79
|
|
|
80
80
|
[](https://www.augmentcode.com/)
|
|
81
81
|
[](https://pypi.org/project/devrev-Python-SDK/)
|
|
@@ -159,7 +159,7 @@ This SDK is generated and maintained from the official DevRev OpenAPI specificat
|
|
|
159
159
|
|
|
160
160
|
### MCP Server (AI Integration)
|
|
161
161
|
|
|
162
|
-
- ✅ **
|
|
162
|
+
- ✅ **83+ MCP Tools** — Full CRUD for tickets, accounts, users, articles, webhooks, and all DevRev resources
|
|
163
163
|
- ✅ **7 Resource Templates** — `devrev://` URI scheme for AI-accessible data browsing
|
|
164
164
|
- ✅ **8 Workflow Prompts** — Pre-built triage, escalation, investigation, and reporting workflows
|
|
165
165
|
- ✅ **3 Transport Modes** — stdio (local), Streamable HTTP (production), SSE (legacy)
|
|
@@ -725,7 +725,7 @@ The DevRev MCP Server exposes the full DevRev platform as [Model Context Protoco
|
|
|
725
725
|
|
|
726
726
|
### MCP Server Features
|
|
727
727
|
|
|
728
|
-
- **
|
|
728
|
+
- **83+ MCP Tools** — Full CRUD for tickets, accounts, users, conversations, articles, parts, tags, groups, timeline, links, SLAs, webhooks, plus beta tools (search, recommendations, incidents, engagements)
|
|
729
729
|
- **7 Resource Templates** — `devrev://` URI scheme for browsing tickets, accounts, articles, users, parts, conversations
|
|
730
730
|
- **8 Workflow Prompts** — Triage, draft response, escalate, summarize account, investigate, weekly report, find similar, onboard customer
|
|
731
731
|
- **3 Transports** — stdio (local dev), Streamable HTTP (production), SSE (legacy)
|
|
@@ -73,7 +73,7 @@ devrev/utils/pagination.py,sha256=zsAZdGw2eGs2p5XEFX-Dng3zjsP-ERsUqQn7PWmI9Oc,48
|
|
|
73
73
|
devrev_mcp/__init__.py,sha256=-VAlWWe5rx2UqfOUK8L2Evr28FEfapEmMKgYpCbVxjQ,216
|
|
74
74
|
devrev_mcp/__main__.py,sha256=PfuBYR0I4yIj1CqTikFBcqB_TNo34R1I5_8bv0D2ekc,1521
|
|
75
75
|
devrev_mcp/config.py,sha256=4GllGfYM6k7OixEKfR9JH_TE1F7LFeCbDo1bLEC9ACA,4002
|
|
76
|
-
devrev_mcp/server.py,sha256=
|
|
76
|
+
devrev_mcp/server.py,sha256=4Zhkom-2LQ0qo91o70Uif9U0uSqwFAZ9Xip74ihhmxw,18674
|
|
77
77
|
devrev_mcp/middleware/__init__.py,sha256=QphqWGURVzKXWJ0oLJ5Qub6V33z5YyQwN5r6Gue6hd8,52
|
|
78
78
|
devrev_mcp/middleware/audit.py,sha256=PRnyNCobXSJnSqVh4Z5K8b7jauNOTMSiMEIjKcd1s2A,13459
|
|
79
79
|
devrev_mcp/middleware/auth.py,sha256=wgdYZEWxBIAj7XAc8c95ct9aZ1aUQ6s29SiWuUW6IiU,16214
|
|
@@ -111,13 +111,14 @@ devrev_mcp/tools/slas.py,sha256=q7eYC7nMxCGoHMDp1QbtCgSWiG4oHk78sydPtYwsh10,4902
|
|
|
111
111
|
devrev_mcp/tools/tags.py,sha256=zj_my9CkPQu8_TTOqszfLULPNgxm83kHux-rWFxHvXQ,4711
|
|
112
112
|
devrev_mcp/tools/timeline.py,sha256=p7P699Oq205jrzCVyYS6v4bXHEQizircHVyS5JE-GJ4,5326
|
|
113
113
|
devrev_mcp/tools/users.py,sha256=7CtrxjgxniEb5-DaPh0rwL680a2fDFLJSIU5huuTjYE,4896
|
|
114
|
+
devrev_mcp/tools/webhooks.py,sha256=UdoKxZprZygVopqYYf02RF84HVCL-gJBpTNm0jrw_QI,5166
|
|
114
115
|
devrev_mcp/tools/works.py,sha256=IFaIXYR4j_2pZ39ykZgdHdo5nCk8OfgWU5bxBdHwp5E,15241
|
|
115
116
|
devrev_mcp/utils/__init__.py,sha256=2_5b1KC5kjoUqFY1ZSdB2Tefd2ekjbZ-eHyFWBKI-0A,49
|
|
116
|
-
devrev_mcp/utils/don_id.py,sha256=
|
|
117
|
+
devrev_mcp/utils/don_id.py,sha256=jbVKXW_BeKjPHhz1F9p14fNmrXP2R36rgWZqdC4QlOc,6358
|
|
117
118
|
devrev_mcp/utils/errors.py,sha256=5mRAo76rJvvEVi6b1ZokPxDtX5JKkptaqmiYDLCkwBE,2110
|
|
118
119
|
devrev_mcp/utils/formatting.py,sha256=6JssG5x1BxjdgSiQ8Ou3H-9Wo3wgWTWmejsrGez4wKc,2431
|
|
119
120
|
devrev_mcp/utils/pagination.py,sha256=EOUgL-ZdSToM1Q-ydXmjhibsef5K1u1g3CaS9K8I2fY,1286
|
|
120
|
-
devrev_python_sdk-3.
|
|
121
|
-
devrev_python_sdk-3.
|
|
122
|
-
devrev_python_sdk-3.
|
|
123
|
-
devrev_python_sdk-3.
|
|
121
|
+
devrev_python_sdk-3.1.1.dist-info/METADATA,sha256=KuDpsWwhLZQ-048S8B7FchJkkjP1ATp3a2upRwVfxJM,40934
|
|
122
|
+
devrev_python_sdk-3.1.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
123
|
+
devrev_python_sdk-3.1.1.dist-info/entry_points.txt,sha256=XiV4J_yy0yzVZVxg7T66YERVIlqdPNp3O-NHTHkllqQ,63
|
|
124
|
+
devrev_python_sdk-3.1.1.dist-info/RECORD,,
|
|
File without changes
|