quickcall-integrations 0.1.2__py3-none-any.whl → 0.1.4__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.
@@ -0,0 +1,338 @@
1
+ """
2
+ GitHub Tools - Pull requests and commits via GitHub API.
3
+
4
+ These tools require authentication via QuickCall.
5
+ Connect using connect_quickcall tool first.
6
+ """
7
+
8
+ from typing import Optional
9
+ import logging
10
+
11
+ from fastmcp import FastMCP
12
+ from fastmcp.exceptions import ToolError
13
+ from pydantic import Field
14
+
15
+ from mcp_server.auth import get_credential_store, is_authenticated
16
+ from mcp_server.api_clients.github_client import GitHubClient
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ def _get_client() -> GitHubClient:
22
+ """Get the GitHub client, raising error if not configured."""
23
+ store = get_credential_store()
24
+
25
+ if not store.is_authenticated():
26
+ raise ToolError(
27
+ "Not connected to QuickCall. "
28
+ "Run connect_quickcall to authenticate and enable GitHub tools."
29
+ )
30
+
31
+ # Fetch fresh credentials from API
32
+ creds = store.get_api_credentials()
33
+
34
+ if not creds or not creds.github_connected:
35
+ raise ToolError(
36
+ "GitHub not connected. "
37
+ "Connect GitHub at quickcall.dev/assistant to enable GitHub tools."
38
+ )
39
+
40
+ if not creds.github_token:
41
+ raise ToolError(
42
+ "Could not fetch GitHub token. "
43
+ "Try reconnecting GitHub at quickcall.dev/assistant."
44
+ )
45
+
46
+ # Create client with fresh token and installation ID
47
+ return GitHubClient(
48
+ token=creds.github_token,
49
+ default_owner=creds.github_username,
50
+ installation_id=creds.github_installation_id,
51
+ )
52
+
53
+
54
+ def create_github_tools(mcp: FastMCP) -> None:
55
+ """Add GitHub tools to the MCP server."""
56
+
57
+ @mcp.tool(tags={"github", "repos"})
58
+ def list_repos(
59
+ limit: int = Field(
60
+ default=20,
61
+ description="Maximum number of repositories to return (default: 20)",
62
+ ),
63
+ ) -> dict:
64
+ """
65
+ List GitHub repositories accessible to the authenticated user.
66
+
67
+ Returns repositories sorted by last updated.
68
+ Requires QuickCall authentication with GitHub connected.
69
+ """
70
+ try:
71
+ client = _get_client()
72
+ repos = client.list_repos(limit=limit)
73
+
74
+ return {
75
+ "count": len(repos),
76
+ "repos": [repo.model_dump() for repo in repos],
77
+ }
78
+ except ToolError:
79
+ raise
80
+ except Exception as e:
81
+ raise ToolError(f"Failed to list repositories: {str(e)}")
82
+
83
+ @mcp.tool(tags={"github", "prs"})
84
+ def list_prs(
85
+ owner: Optional[str] = Field(
86
+ default=None,
87
+ description="Repository owner (username or org). Uses your GitHub username if not specified.",
88
+ ),
89
+ repo: Optional[str] = Field(
90
+ default=None,
91
+ description="Repository name. Required.",
92
+ ),
93
+ state: str = Field(
94
+ default="open",
95
+ description="PR state: 'open', 'closed', or 'all' (default: 'open')",
96
+ ),
97
+ limit: int = Field(
98
+ default=20,
99
+ description="Maximum number of PRs to return (default: 20)",
100
+ ),
101
+ ) -> dict:
102
+ """
103
+ List pull requests for a GitHub repository.
104
+
105
+ Returns PRs sorted by last updated.
106
+ Requires QuickCall authentication with GitHub connected.
107
+ """
108
+ try:
109
+ client = _get_client()
110
+ prs = client.list_prs(owner=owner, repo=repo, state=state, limit=limit)
111
+
112
+ return {
113
+ "count": len(prs),
114
+ "prs": [pr.model_dump() for pr in prs],
115
+ }
116
+ except ToolError:
117
+ raise
118
+ except ValueError as e:
119
+ raise ToolError(
120
+ f"Repository not specified: {str(e)}. "
121
+ f"Please provide both owner and repo parameters."
122
+ )
123
+ except Exception as e:
124
+ raise ToolError(f"Failed to list pull requests: {str(e)}")
125
+
126
+ @mcp.tool(tags={"github", "prs"})
127
+ def get_pr(
128
+ pr_number: int = Field(..., description="Pull request number", gt=0),
129
+ owner: Optional[str] = Field(
130
+ default=None,
131
+ description="Repository owner. Uses your GitHub username if not specified.",
132
+ ),
133
+ repo: Optional[str] = Field(
134
+ default=None,
135
+ description="Repository name. Required.",
136
+ ),
137
+ ) -> dict:
138
+ """
139
+ Get detailed information about a specific pull request.
140
+
141
+ Includes title, description, status, files changed, and review status.
142
+ Requires QuickCall authentication with GitHub connected.
143
+ """
144
+ try:
145
+ client = _get_client()
146
+ pr = client.get_pr(pr_number, owner=owner, repo=repo)
147
+
148
+ if not pr:
149
+ raise ToolError(f"Pull request #{pr_number} not found")
150
+
151
+ return {"pr": pr.model_dump()}
152
+ except ToolError:
153
+ raise
154
+ except ValueError as e:
155
+ raise ToolError(
156
+ f"Repository not specified: {str(e)}. "
157
+ f"Please provide both owner and repo parameters."
158
+ )
159
+ except Exception as e:
160
+ raise ToolError(f"Failed to get pull request #{pr_number}: {str(e)}")
161
+
162
+ @mcp.tool(tags={"github", "commits"})
163
+ def list_commits(
164
+ owner: Optional[str] = Field(
165
+ default=None,
166
+ description="Repository owner. Uses your GitHub username if not specified.",
167
+ ),
168
+ repo: Optional[str] = Field(
169
+ default=None,
170
+ description="Repository name. Required.",
171
+ ),
172
+ branch: Optional[str] = Field(
173
+ default=None,
174
+ description="Branch name to list commits from. Defaults to default branch.",
175
+ ),
176
+ author: Optional[str] = Field(
177
+ default=None,
178
+ description="Filter by author username",
179
+ ),
180
+ since: Optional[str] = Field(
181
+ default=None,
182
+ description="ISO datetime - only commits after this date (e.g., '2024-01-01T00:00:00Z')",
183
+ ),
184
+ limit: int = Field(
185
+ default=20,
186
+ description="Maximum number of commits to return (default: 20)",
187
+ ),
188
+ ) -> dict:
189
+ """
190
+ List commits for a GitHub repository.
191
+
192
+ Returns commits sorted by date (newest first).
193
+ Requires QuickCall authentication with GitHub connected.
194
+ """
195
+ try:
196
+ client = _get_client()
197
+ commits = client.list_commits(
198
+ owner=owner,
199
+ repo=repo,
200
+ sha=branch,
201
+ author=author,
202
+ since=since,
203
+ limit=limit,
204
+ )
205
+
206
+ return {
207
+ "count": len(commits),
208
+ "commits": [commit.model_dump() for commit in commits],
209
+ }
210
+ except ToolError:
211
+ raise
212
+ except ValueError as e:
213
+ raise ToolError(
214
+ f"Repository not specified: {str(e)}. "
215
+ f"Please provide both owner and repo parameters."
216
+ )
217
+ except Exception as e:
218
+ raise ToolError(f"Failed to list commits: {str(e)}")
219
+
220
+ @mcp.tool(tags={"github", "commits"})
221
+ def get_commit(
222
+ sha: str = Field(..., description="Commit SHA (full or abbreviated)"),
223
+ owner: Optional[str] = Field(
224
+ default=None,
225
+ description="Repository owner. Uses your GitHub username if not specified.",
226
+ ),
227
+ repo: Optional[str] = Field(
228
+ default=None,
229
+ description="Repository name. Required.",
230
+ ),
231
+ ) -> dict:
232
+ """
233
+ Get detailed information about a specific commit.
234
+
235
+ Includes commit message, author, stats, and file changes.
236
+ Requires QuickCall authentication with GitHub connected.
237
+ """
238
+ try:
239
+ client = _get_client()
240
+ commit = client.get_commit(sha, owner=owner, repo=repo)
241
+
242
+ if not commit:
243
+ raise ToolError(f"Commit {sha} not found")
244
+
245
+ return {"commit": commit}
246
+ except ToolError:
247
+ raise
248
+ except ValueError as e:
249
+ raise ToolError(
250
+ f"Repository not specified: {str(e)}. "
251
+ f"Please provide both owner and repo parameters."
252
+ )
253
+ except Exception as e:
254
+ raise ToolError(f"Failed to get commit {sha}: {str(e)}")
255
+
256
+ @mcp.tool(tags={"github", "branches"})
257
+ def list_branches(
258
+ owner: Optional[str] = Field(
259
+ default=None,
260
+ description="Repository owner. Uses your GitHub username if not specified.",
261
+ ),
262
+ repo: Optional[str] = Field(
263
+ default=None,
264
+ description="Repository name. Required.",
265
+ ),
266
+ limit: int = Field(
267
+ default=30,
268
+ description="Maximum number of branches to return (default: 30)",
269
+ ),
270
+ ) -> dict:
271
+ """
272
+ List branches for a GitHub repository.
273
+
274
+ Returns branch names with their latest commit SHA and protection status.
275
+ Requires QuickCall authentication with GitHub connected.
276
+ """
277
+ try:
278
+ client = _get_client()
279
+ branches = client.list_branches(owner=owner, repo=repo, limit=limit)
280
+
281
+ return {
282
+ "count": len(branches),
283
+ "branches": branches,
284
+ }
285
+ except ToolError:
286
+ raise
287
+ except ValueError as e:
288
+ raise ToolError(
289
+ f"Repository not specified: {str(e)}. "
290
+ f"Please provide both owner and repo parameters."
291
+ )
292
+ except Exception as e:
293
+ raise ToolError(f"Failed to list branches: {str(e)}")
294
+
295
+ @mcp.tool(tags={"github", "status"})
296
+ def check_github_connection() -> dict:
297
+ """
298
+ Check if GitHub is connected and working.
299
+
300
+ Tests the GitHub connection by fetching your account info.
301
+ Use this to verify your GitHub integration is working.
302
+ """
303
+ store = get_credential_store()
304
+
305
+ if not store.is_authenticated():
306
+ return {
307
+ "connected": False,
308
+ "error": "Not connected to QuickCall. Run connect_quickcall first.",
309
+ }
310
+
311
+ creds = store.get_api_credentials()
312
+
313
+ if not creds:
314
+ return {
315
+ "connected": False,
316
+ "error": "Could not fetch credentials from QuickCall.",
317
+ }
318
+
319
+ if not creds.github_connected:
320
+ return {
321
+ "connected": False,
322
+ "error": "GitHub not connected. Connect at quickcall.dev/assistant.",
323
+ }
324
+
325
+ try:
326
+ client = _get_client()
327
+ username = client.get_authenticated_user()
328
+
329
+ return {
330
+ "connected": True,
331
+ "username": username,
332
+ "installation_id": creds.github_installation_id,
333
+ }
334
+ except Exception as e:
335
+ return {
336
+ "connected": False,
337
+ "error": str(e),
338
+ }
@@ -0,0 +1,203 @@
1
+ """
2
+ Slack Tools - Messaging and channel operations.
3
+
4
+ These tools require authentication via QuickCall.
5
+ Connect using connect_quickcall tool first.
6
+ """
7
+
8
+ from typing import Optional
9
+ import logging
10
+
11
+ from fastmcp import FastMCP
12
+ from fastmcp.exceptions import ToolError
13
+ from pydantic import Field
14
+
15
+ from mcp_server.auth import get_credential_store
16
+ from mcp_server.api_clients.slack_client import SlackClient, SlackAPIError
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ def _get_client() -> SlackClient:
22
+ """Get the Slack client, raising error if not configured."""
23
+ store = get_credential_store()
24
+
25
+ if not store.is_authenticated():
26
+ raise ToolError(
27
+ "Not connected to QuickCall. "
28
+ "Run connect_quickcall to authenticate and enable Slack tools."
29
+ )
30
+
31
+ # Fetch fresh credentials from API
32
+ creds = store.get_api_credentials()
33
+
34
+ if not creds or not creds.slack_connected:
35
+ raise ToolError(
36
+ "Slack not connected. "
37
+ "Connect Slack at quickcall.dev/assistant to enable Slack tools."
38
+ )
39
+
40
+ if not creds.slack_bot_token:
41
+ raise ToolError(
42
+ "Could not fetch Slack token. "
43
+ "Try reconnecting Slack at quickcall.dev/assistant."
44
+ )
45
+
46
+ # Create client with fresh token
47
+ return SlackClient(bot_token=creds.slack_bot_token)
48
+
49
+
50
+ def create_slack_tools(mcp: FastMCP) -> None:
51
+ """Add Slack tools to the MCP server."""
52
+
53
+ @mcp.tool(tags={"slack", "channels"})
54
+ def list_slack_channels(
55
+ include_private: bool = Field(
56
+ default=True,
57
+ description="Include private channels the bot has access to (default: true)",
58
+ ),
59
+ limit: int = Field(
60
+ default=100,
61
+ description="Maximum number of channels to return (default: 100)",
62
+ ),
63
+ ) -> dict:
64
+ """
65
+ List Slack channels the bot has access to.
66
+
67
+ Returns channel names, IDs, and membership status.
68
+ Requires QuickCall authentication with Slack connected.
69
+ """
70
+ try:
71
+ client = _get_client()
72
+ channels = client.list_channels(
73
+ include_private=include_private, limit=limit
74
+ )
75
+
76
+ return {
77
+ "count": len(channels),
78
+ "channels": [ch.model_dump() for ch in channels],
79
+ }
80
+ except ToolError:
81
+ raise
82
+ except SlackAPIError as e:
83
+ raise ToolError(str(e))
84
+ except Exception as e:
85
+ raise ToolError(f"Failed to list Slack channels: {str(e)}")
86
+
87
+ @mcp.tool(tags={"slack", "messaging"})
88
+ def send_slack_message(
89
+ message: str = Field(
90
+ ...,
91
+ description="Message text to send. Supports Slack mrkdwn formatting.",
92
+ ),
93
+ channel: Optional[str] = Field(
94
+ default=None,
95
+ description="Channel name (with or without #) or channel ID. Required.",
96
+ ),
97
+ ) -> dict:
98
+ """
99
+ Send a message to a Slack channel.
100
+
101
+ The bot must be a member of the channel to send messages.
102
+ Requires QuickCall authentication with Slack connected.
103
+
104
+ Message formatting (mrkdwn):
105
+ - *bold* for bold text
106
+ - _italic_ for italic text
107
+ - `code` for inline code
108
+ - ```code block``` for code blocks
109
+ - <https://example.com|link text> for links
110
+ """
111
+ try:
112
+ client = _get_client()
113
+ result = client.send_message(text=message, channel=channel)
114
+
115
+ return {
116
+ "success": result.ok,
117
+ "channel": result.channel,
118
+ "message_ts": result.ts,
119
+ }
120
+ except ToolError:
121
+ raise
122
+ except SlackAPIError as e:
123
+ raise ToolError(str(e))
124
+ except ValueError as e:
125
+ raise ToolError(str(e))
126
+ except Exception as e:
127
+ raise ToolError(f"Failed to send Slack message: {str(e)}")
128
+
129
+ @mcp.tool(tags={"slack", "users"})
130
+ def list_slack_users(
131
+ limit: int = Field(
132
+ default=100,
133
+ description="Maximum number of users to return (default: 100)",
134
+ ),
135
+ include_bots: bool = Field(
136
+ default=False,
137
+ description="Include bot users in the list (default: false)",
138
+ ),
139
+ ) -> dict:
140
+ """
141
+ List users in the Slack workspace.
142
+
143
+ Returns user names, display names, and email addresses.
144
+ Requires QuickCall authentication with Slack connected.
145
+ """
146
+ try:
147
+ client = _get_client()
148
+ users = client.list_users(limit=limit, include_bots=include_bots)
149
+
150
+ return {
151
+ "count": len(users),
152
+ "users": [user.model_dump() for user in users],
153
+ }
154
+ except ToolError:
155
+ raise
156
+ except SlackAPIError as e:
157
+ raise ToolError(str(e))
158
+ except Exception as e:
159
+ raise ToolError(f"Failed to list Slack users: {str(e)}")
160
+
161
+ @mcp.tool(tags={"slack", "status"})
162
+ def check_slack_connection() -> dict:
163
+ """
164
+ Check if Slack is connected and working.
165
+
166
+ Tests the Slack bot token by calling auth.test.
167
+ Use this to verify your Slack integration is working.
168
+ """
169
+ store = get_credential_store()
170
+
171
+ if not store.is_authenticated():
172
+ return {
173
+ "connected": False,
174
+ "error": "Not connected to QuickCall. Run connect_quickcall first.",
175
+ }
176
+
177
+ creds = store.get_api_credentials()
178
+
179
+ if not creds:
180
+ return {
181
+ "connected": False,
182
+ "error": "Could not fetch credentials from QuickCall.",
183
+ }
184
+
185
+ if not creds.slack_connected:
186
+ return {
187
+ "connected": False,
188
+ "error": "Slack not connected. Connect at quickcall.dev/assistant.",
189
+ }
190
+
191
+ try:
192
+ client = _get_client()
193
+ status = client.health_check()
194
+
195
+ if status.get("connected"):
196
+ status["team_name"] = creds.slack_team_name
197
+ status["team_id"] = creds.slack_team_id
198
+ return status
199
+ except Exception as e:
200
+ return {
201
+ "connected": False,
202
+ "error": str(e),
203
+ }
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.4
2
+ Name: quickcall-integrations
3
+ Version: 0.1.4
4
+ Summary: MCP server with developer integrations for Claude Code and Cursor
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: fastmcp>=2.13.0
7
+ Requires-Dist: httpx>=0.28.0
8
+ Requires-Dist: pydantic>=2.11.7
9
+ Requires-Dist: pygithub>=2.8.1
10
+ Description-Content-Type: text/markdown
11
+
12
+ <p align="center">
13
+ <img src="assets/logo.png" alt="QuickCall" width="400">
14
+ </p>
15
+
16
+ <h3 align="center">Eliminate interruptions for developers</h3>
17
+
18
+ <p align="center">
19
+ <em>Ask about your work, get instant answers. No more context switching.</em>
20
+ </p>
21
+
22
+ <p align="center">
23
+ <a href="https://quickcall.dev"><img src="https://img.shields.io/badge/Web-quickcall.dev-000000?logo=googlechrome&logoColor=white" alt="Web"></a>
24
+ <a href="https://discord.gg/DtnMxuE35v"><img src="https://img.shields.io/badge/Discord-Join%20Us-5865F2?logo=discord&logoColor=white" alt="Discord"></a>
25
+ </p>
26
+
27
+ <p align="center">
28
+ <a href="#claude-code">Claude Code</a> |
29
+ <a href="#cursor">Cursor</a> |
30
+ <a href="#commands">Commands</a> |
31
+ <a href="#development">Development</a>
32
+ </p>
33
+
34
+ ---
35
+
36
+ ## Current integrations
37
+
38
+ - Git - commits, diffs, code changes
39
+
40
+ ## Coming soon
41
+
42
+ - GitHub PRs & Issues
43
+
44
+ ## Install
45
+
46
+ ### Claude Code
47
+
48
+ Run these commands in [Claude Code](https://claude.ai/code):
49
+
50
+ ```
51
+ /plugin marketplace add quickcall-dev/quickcall-integrations
52
+ /plugin install quickcall@quickcall-integrations
53
+ ```
54
+
55
+ <details>
56
+ <summary>MCP only (without plugin)</summary>
57
+
58
+ ```bash
59
+ claude mcp add quickcall -- uvx quickcall-integrations
60
+ ```
61
+ </details>
62
+
63
+ <details>
64
+ <summary>Update to latest version</summary>
65
+
66
+ ```
67
+ /plugin marketplace update quickcall-integrations
68
+ /plugin uninstall quickcall
69
+ /plugin install quickcall@quickcall-integrations
70
+ ```
71
+
72
+ After updating, restart Claude Code or open a new terminal.
73
+ </details>
74
+
75
+ ### Cursor
76
+
77
+ Add to your Cursor MCP config (`~/.cursor/mcp.json` for global, or `.cursor/mcp.json` for project):
78
+
79
+ ```json
80
+ {
81
+ "mcpServers": {
82
+ "quickcall": {
83
+ "command": "uvx",
84
+ "args": ["quickcall-integrations"]
85
+ }
86
+ }
87
+ }
88
+ ```
89
+
90
+ Then restart Cursor.
91
+
92
+ > Also works with [Antigravity](https://antigravity.dev) and any other IDE that supports MCP servers.
93
+
94
+ ## Commands
95
+
96
+ ### Claude Code
97
+
98
+ - `/quickcall:updates` - Get git updates (default: 1 day)
99
+ - `/quickcall:updates 7d` - Get updates for last 7 days
100
+ - `/quickcall:updates 30d` - Get updates for last 30 days
101
+
102
+ ### Cursor
103
+
104
+ Ask the AI naturally - it will use the `get_updates` tool:
105
+ - "What did I work on today?"
106
+ - "Show me recent commits"
107
+ - "What changed in the last week?"
108
+
109
+
110
+ ## Development
111
+
112
+ ```bash
113
+ git clone https://github.com/quickcall-dev/quickcall-integrations
114
+ cd quickcall-integrations
115
+ uv pip install -e .
116
+ quickcall-integrations
117
+ ```
118
+ ## Deployment
119
+
120
+ It only triggers on:
121
+
122
+ - Tags starting with v* (e.g., v0.1.0)
123
+ - Manual trigger (workflow_dispatch)
124
+
125
+ To publish to PyPI:
126
+
127
+ ```bash
128
+ git tag v0.1.0
129
+ git push origin v0.1.0
130
+ ```
131
+
132
+ Or trigger manually from GitHub Actions page.
133
+
134
+ ---
135
+
136
+ <p align="center">
137
+ Built with ❤️ by <a href="https://quickcall.dev">QuickCall</a>
138
+ </p>
@@ -0,0 +1,18 @@
1
+ mcp_server/__init__.py,sha256=wAVZ0eHQoGovs-66UH9-kRkcv37bprVEUeinyUFS_KI,98
2
+ mcp_server/server.py,sha256=9Ojv5DoQrCeyC6lDD3keh9BuLyNKB6mb6FUslP6z0O8,2839
3
+ mcp_server/api_clients/__init__.py,sha256=kOG5_sxIVpAx_tvf1nq_P0QCkqojAVidRE-wenLS-Wc,207
4
+ mcp_server/api_clients/github_client.py,sha256=Wj326ImYI11eFyItP5HQ4TD7aQ4nC6WAR12ZbneBiAQ,13569
5
+ mcp_server/api_clients/slack_client.py,sha256=Tby3vkPo-yN38Egb6Cj7MQk6Ul3DV4BOp5nVWScR4cw,10424
6
+ mcp_server/auth/__init__.py,sha256=YQpDPH5itIaBuEm0AtwNCHxTX4L5dLutTximVamsItw,552
7
+ mcp_server/auth/credentials.py,sha256=OCPs_4DcQ1zHEBgkcPDNCHVFFO36Xe6_QBx_5Jn2xgk,9379
8
+ mcp_server/auth/device_flow.py,sha256=NXNWHzd-CA4dlhEVCgUhwfpe9TpMKpLSJuyFCh70xKs,8371
9
+ mcp_server/tools/__init__.py,sha256=vIR2ujAaTXm2DgpTsVNz3brI4G34p-Jeg44Qe0uvWc0,405
10
+ mcp_server/tools/auth_tools.py,sha256=wuhEucxeTT08DWT1TCxoYrEa6Jy2MIpOlXBxtCeYEXQ,14586
11
+ mcp_server/tools/git_tools.py,sha256=5cZfngkP1wHNYUvGtLFcMjS7bhrFzxAC_TPz0h3CUB0,7691
12
+ mcp_server/tools/github_tools.py,sha256=GomR88SByAbdi4VHk1vaUNp29hwWEIY6cX1t9QoMDOU,10972
13
+ mcp_server/tools/slack_tools.py,sha256=uXCxnzLfdi5LaM3ayVS5JT7F3MAnI6C0vB7jW0tZfjY,6303
14
+ mcp_server/tools/utility_tools.py,sha256=1WiOpJivu6Ug9OLajm77lzsmFfBPgWHs8e1hNCEX_Aw,3359
15
+ quickcall_integrations-0.1.4.dist-info/METADATA,sha256=MGQRUdJJyCB5SbPPPp3VyF8KXI5ubYOQoJvetKBDphg,3032
16
+ quickcall_integrations-0.1.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
17
+ quickcall_integrations-0.1.4.dist-info/entry_points.txt,sha256=kkcunmJUzncYvQ1rOR35V2LPm2HcFTKzdI2l3n7NwiM,66
18
+ quickcall_integrations-0.1.4.dist-info/RECORD,,