universal-mcp-applications 0.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.
- universal_mcp/applications/ahrefs/README.md +51 -0
- universal_mcp/applications/ahrefs/__init__.py +1 -0
- universal_mcp/applications/ahrefs/app.py +2291 -0
- universal_mcp/applications/airtable/README.md +22 -0
- universal_mcp/applications/airtable/__init__.py +1 -0
- universal_mcp/applications/airtable/app.py +479 -0
- universal_mcp/applications/apollo/README.md +44 -0
- universal_mcp/applications/apollo/__init__.py +1 -0
- universal_mcp/applications/apollo/app.py +1847 -0
- universal_mcp/applications/asana/README.md +199 -0
- universal_mcp/applications/asana/__init__.py +1 -0
- universal_mcp/applications/asana/app.py +9509 -0
- universal_mcp/applications/aws-s3/README.md +0 -0
- universal_mcp/applications/aws-s3/__init__.py +1 -0
- universal_mcp/applications/aws-s3/app.py +552 -0
- universal_mcp/applications/bill/README.md +0 -0
- universal_mcp/applications/bill/__init__.py +1 -0
- universal_mcp/applications/bill/app.py +8705 -0
- universal_mcp/applications/box/README.md +307 -0
- universal_mcp/applications/box/__init__.py +1 -0
- universal_mcp/applications/box/app.py +15987 -0
- universal_mcp/applications/braze/README.md +106 -0
- universal_mcp/applications/braze/__init__.py +1 -0
- universal_mcp/applications/braze/app.py +4754 -0
- universal_mcp/applications/cal-com-v2/README.md +150 -0
- universal_mcp/applications/cal-com-v2/__init__.py +1 -0
- universal_mcp/applications/cal-com-v2/app.py +5541 -0
- universal_mcp/applications/calendly/README.md +53 -0
- universal_mcp/applications/calendly/__init__.py +1 -0
- universal_mcp/applications/calendly/app.py +1436 -0
- universal_mcp/applications/canva/README.md +43 -0
- universal_mcp/applications/canva/__init__.py +1 -0
- universal_mcp/applications/canva/app.py +941 -0
- universal_mcp/applications/clickup/README.md +135 -0
- universal_mcp/applications/clickup/__init__.py +1 -0
- universal_mcp/applications/clickup/app.py +5009 -0
- universal_mcp/applications/coda/README.md +108 -0
- universal_mcp/applications/coda/__init__.py +1 -0
- universal_mcp/applications/coda/app.py +3671 -0
- universal_mcp/applications/confluence/README.md +198 -0
- universal_mcp/applications/confluence/__init__.py +1 -0
- universal_mcp/applications/confluence/app.py +6273 -0
- universal_mcp/applications/contentful/README.md +17 -0
- universal_mcp/applications/contentful/__init__.py +1 -0
- universal_mcp/applications/contentful/app.py +364 -0
- universal_mcp/applications/crustdata/README.md +25 -0
- universal_mcp/applications/crustdata/__init__.py +1 -0
- universal_mcp/applications/crustdata/app.py +586 -0
- universal_mcp/applications/dialpad/README.md +202 -0
- universal_mcp/applications/dialpad/__init__.py +1 -0
- universal_mcp/applications/dialpad/app.py +5949 -0
- universal_mcp/applications/digitalocean/README.md +463 -0
- universal_mcp/applications/digitalocean/__init__.py +1 -0
- universal_mcp/applications/digitalocean/app.py +20835 -0
- universal_mcp/applications/domain-checker/README.md +13 -0
- universal_mcp/applications/domain-checker/__init__.py +1 -0
- universal_mcp/applications/domain-checker/app.py +265 -0
- universal_mcp/applications/e2b/README.md +12 -0
- universal_mcp/applications/e2b/__init__.py +1 -0
- universal_mcp/applications/e2b/app.py +187 -0
- universal_mcp/applications/elevenlabs/README.md +88 -0
- universal_mcp/applications/elevenlabs/__init__.py +1 -0
- universal_mcp/applications/elevenlabs/app.py +3235 -0
- universal_mcp/applications/exa/README.md +15 -0
- universal_mcp/applications/exa/__init__.py +1 -0
- universal_mcp/applications/exa/app.py +221 -0
- universal_mcp/applications/falai/README.md +17 -0
- universal_mcp/applications/falai/__init__.py +1 -0
- universal_mcp/applications/falai/app.py +331 -0
- universal_mcp/applications/figma/README.md +49 -0
- universal_mcp/applications/figma/__init__.py +1 -0
- universal_mcp/applications/figma/app.py +1090 -0
- universal_mcp/applications/firecrawl/README.md +20 -0
- universal_mcp/applications/firecrawl/__init__.py +1 -0
- universal_mcp/applications/firecrawl/app.py +514 -0
- universal_mcp/applications/fireflies/README.md +25 -0
- universal_mcp/applications/fireflies/__init__.py +1 -0
- universal_mcp/applications/fireflies/app.py +506 -0
- universal_mcp/applications/fpl/README.md +23 -0
- universal_mcp/applications/fpl/__init__.py +1 -0
- universal_mcp/applications/fpl/app.py +1327 -0
- universal_mcp/applications/fpl/utils/api.py +142 -0
- universal_mcp/applications/fpl/utils/fixtures.py +629 -0
- universal_mcp/applications/fpl/utils/helper.py +982 -0
- universal_mcp/applications/fpl/utils/league_utils.py +546 -0
- universal_mcp/applications/fpl/utils/position_utils.py +68 -0
- universal_mcp/applications/ghost-content/README.md +25 -0
- universal_mcp/applications/ghost-content/__init__.py +1 -0
- universal_mcp/applications/ghost-content/app.py +654 -0
- universal_mcp/applications/github/README.md +1049 -0
- universal_mcp/applications/github/__init__.py +1 -0
- universal_mcp/applications/github/app.py +50600 -0
- universal_mcp/applications/gong/README.md +63 -0
- universal_mcp/applications/gong/__init__.py +1 -0
- universal_mcp/applications/gong/app.py +2297 -0
- universal_mcp/applications/google-ads/README.md +0 -0
- universal_mcp/applications/google-ads/__init__.py +1 -0
- universal_mcp/applications/google-ads/app.py +23 -0
- universal_mcp/applications/google-calendar/README.md +21 -0
- universal_mcp/applications/google-calendar/__init__.py +1 -0
- universal_mcp/applications/google-calendar/app.py +574 -0
- universal_mcp/applications/google-docs/README.md +25 -0
- universal_mcp/applications/google-docs/__init__.py +1 -0
- universal_mcp/applications/google-docs/app.py +760 -0
- universal_mcp/applications/google-drive/README.md +68 -0
- universal_mcp/applications/google-drive/__init__.py +1 -0
- universal_mcp/applications/google-drive/app.py +4936 -0
- universal_mcp/applications/google-gemini/README.md +25 -0
- universal_mcp/applications/google-gemini/__init__.py +1 -0
- universal_mcp/applications/google-gemini/app.py +663 -0
- universal_mcp/applications/google-mail/README.md +31 -0
- universal_mcp/applications/google-mail/__init__.py +1 -0
- universal_mcp/applications/google-mail/app.py +1354 -0
- universal_mcp/applications/google-searchconsole/README.md +21 -0
- universal_mcp/applications/google-searchconsole/__init__.py +1 -0
- universal_mcp/applications/google-searchconsole/app.py +320 -0
- universal_mcp/applications/google-sheet/README.md +36 -0
- universal_mcp/applications/google-sheet/__init__.py +1 -0
- universal_mcp/applications/google-sheet/app.py +1941 -0
- universal_mcp/applications/hashnode/README.md +20 -0
- universal_mcp/applications/hashnode/__init__.py +1 -0
- universal_mcp/applications/hashnode/app.py +455 -0
- universal_mcp/applications/heygen/README.md +44 -0
- universal_mcp/applications/heygen/__init__.py +1 -0
- universal_mcp/applications/heygen/app.py +961 -0
- universal_mcp/applications/http-tools/README.md +16 -0
- universal_mcp/applications/http-tools/__init__.py +1 -0
- universal_mcp/applications/http-tools/app.py +153 -0
- universal_mcp/applications/hubspot/README.md +239 -0
- universal_mcp/applications/hubspot/__init__.py +1 -0
- universal_mcp/applications/hubspot/app.py +416 -0
- universal_mcp/applications/jira/README.md +600 -0
- universal_mcp/applications/jira/__init__.py +1 -0
- universal_mcp/applications/jira/app.py +28804 -0
- universal_mcp/applications/klaviyo/README.md +313 -0
- universal_mcp/applications/klaviyo/__init__.py +1 -0
- universal_mcp/applications/klaviyo/app.py +11236 -0
- universal_mcp/applications/linkedin/README.md +15 -0
- universal_mcp/applications/linkedin/__init__.py +1 -0
- universal_mcp/applications/linkedin/app.py +243 -0
- universal_mcp/applications/mailchimp/README.md +281 -0
- universal_mcp/applications/mailchimp/__init__.py +1 -0
- universal_mcp/applications/mailchimp/app.py +10937 -0
- universal_mcp/applications/markitdown/README.md +12 -0
- universal_mcp/applications/markitdown/__init__.py +1 -0
- universal_mcp/applications/markitdown/app.py +63 -0
- universal_mcp/applications/miro/README.md +151 -0
- universal_mcp/applications/miro/__init__.py +1 -0
- universal_mcp/applications/miro/app.py +5429 -0
- universal_mcp/applications/ms-teams/README.md +42 -0
- universal_mcp/applications/ms-teams/__init__.py +1 -0
- universal_mcp/applications/ms-teams/app.py +1823 -0
- universal_mcp/applications/neon/README.md +74 -0
- universal_mcp/applications/neon/__init__.py +1 -0
- universal_mcp/applications/neon/app.py +2018 -0
- universal_mcp/applications/notion/README.md +30 -0
- universal_mcp/applications/notion/__init__.py +1 -0
- universal_mcp/applications/notion/app.py +527 -0
- universal_mcp/applications/openai/README.md +22 -0
- universal_mcp/applications/openai/__init__.py +1 -0
- universal_mcp/applications/openai/app.py +759 -0
- universal_mcp/applications/outlook/README.md +20 -0
- universal_mcp/applications/outlook/__init__.py +1 -0
- universal_mcp/applications/outlook/app.py +444 -0
- universal_mcp/applications/perplexity/README.md +12 -0
- universal_mcp/applications/perplexity/__init__.py +1 -0
- universal_mcp/applications/perplexity/app.py +65 -0
- universal_mcp/applications/pipedrive/README.md +284 -0
- universal_mcp/applications/pipedrive/__init__.py +1 -0
- universal_mcp/applications/pipedrive/app.py +12924 -0
- universal_mcp/applications/posthog/README.md +132 -0
- universal_mcp/applications/posthog/__init__.py +1 -0
- universal_mcp/applications/posthog/app.py +7125 -0
- universal_mcp/applications/reddit/README.md +135 -0
- universal_mcp/applications/reddit/__init__.py +1 -0
- universal_mcp/applications/reddit/app.py +4652 -0
- universal_mcp/applications/replicate/README.md +18 -0
- universal_mcp/applications/replicate/__init__.py +1 -0
- universal_mcp/applications/replicate/app.py +495 -0
- universal_mcp/applications/resend/README.md +40 -0
- universal_mcp/applications/resend/__init__.py +1 -0
- universal_mcp/applications/resend/app.py +881 -0
- universal_mcp/applications/retell/README.md +21 -0
- universal_mcp/applications/retell/__init__.py +1 -0
- universal_mcp/applications/retell/app.py +333 -0
- universal_mcp/applications/rocketlane/README.md +70 -0
- universal_mcp/applications/rocketlane/__init__.py +1 -0
- universal_mcp/applications/rocketlane/app.py +4346 -0
- universal_mcp/applications/semanticscholar/README.md +25 -0
- universal_mcp/applications/semanticscholar/__init__.py +1 -0
- universal_mcp/applications/semanticscholar/app.py +482 -0
- universal_mcp/applications/semrush/README.md +44 -0
- universal_mcp/applications/semrush/__init__.py +1 -0
- universal_mcp/applications/semrush/app.py +2081 -0
- universal_mcp/applications/sendgrid/README.md +362 -0
- universal_mcp/applications/sendgrid/__init__.py +1 -0
- universal_mcp/applications/sendgrid/app.py +9752 -0
- universal_mcp/applications/sentry/README.md +186 -0
- universal_mcp/applications/sentry/__init__.py +1 -0
- universal_mcp/applications/sentry/app.py +7471 -0
- universal_mcp/applications/serpapi/README.md +14 -0
- universal_mcp/applications/serpapi/__init__.py +1 -0
- universal_mcp/applications/serpapi/app.py +293 -0
- universal_mcp/applications/sharepoint/README.md +0 -0
- universal_mcp/applications/sharepoint/__init__.py +1 -0
- universal_mcp/applications/sharepoint/app.py +215 -0
- universal_mcp/applications/shopify/README.md +321 -0
- universal_mcp/applications/shopify/__init__.py +1 -0
- universal_mcp/applications/shopify/app.py +15392 -0
- universal_mcp/applications/shortcut/README.md +128 -0
- universal_mcp/applications/shortcut/__init__.py +1 -0
- universal_mcp/applications/shortcut/app.py +4478 -0
- universal_mcp/applications/slack/README.md +0 -0
- universal_mcp/applications/slack/__init__.py +1 -0
- universal_mcp/applications/slack/app.py +570 -0
- universal_mcp/applications/spotify/README.md +91 -0
- universal_mcp/applications/spotify/__init__.py +1 -0
- universal_mcp/applications/spotify/app.py +2526 -0
- universal_mcp/applications/supabase/README.md +87 -0
- universal_mcp/applications/supabase/__init__.py +1 -0
- universal_mcp/applications/supabase/app.py +2970 -0
- universal_mcp/applications/tavily/README.md +12 -0
- universal_mcp/applications/tavily/__init__.py +1 -0
- universal_mcp/applications/tavily/app.py +51 -0
- universal_mcp/applications/trello/README.md +266 -0
- universal_mcp/applications/trello/__init__.py +1 -0
- universal_mcp/applications/trello/app.py +10875 -0
- universal_mcp/applications/twillo/README.md +0 -0
- universal_mcp/applications/twillo/__init__.py +1 -0
- universal_mcp/applications/twillo/app.py +269 -0
- universal_mcp/applications/twitter/README.md +100 -0
- universal_mcp/applications/twitter/__init__.py +1 -0
- universal_mcp/applications/twitter/api_segments/__init__.py +0 -0
- universal_mcp/applications/twitter/api_segments/api_segment_base.py +51 -0
- universal_mcp/applications/twitter/api_segments/compliance_api.py +122 -0
- universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +255 -0
- universal_mcp/applications/twitter/api_segments/dm_events_api.py +140 -0
- universal_mcp/applications/twitter/api_segments/likes_api.py +159 -0
- universal_mcp/applications/twitter/api_segments/lists_api.py +395 -0
- universal_mcp/applications/twitter/api_segments/openapi_json_api.py +34 -0
- universal_mcp/applications/twitter/api_segments/spaces_api.py +309 -0
- universal_mcp/applications/twitter/api_segments/trends_api.py +40 -0
- universal_mcp/applications/twitter/api_segments/tweets_api.py +1403 -0
- universal_mcp/applications/twitter/api_segments/usage_api.py +40 -0
- universal_mcp/applications/twitter/api_segments/users_api.py +1498 -0
- universal_mcp/applications/twitter/app.py +46 -0
- universal_mcp/applications/unipile/README.md +28 -0
- universal_mcp/applications/unipile/__init__.py +1 -0
- universal_mcp/applications/unipile/app.py +829 -0
- universal_mcp/applications/whatsapp/README.md +23 -0
- universal_mcp/applications/whatsapp/__init__.py +1 -0
- universal_mcp/applications/whatsapp/app.py +595 -0
- universal_mcp/applications/whatsapp-business/README.md +34 -0
- universal_mcp/applications/whatsapp-business/__init__.py +1 -0
- universal_mcp/applications/whatsapp-business/app.py +1065 -0
- universal_mcp/applications/wrike/README.md +46 -0
- universal_mcp/applications/wrike/__init__.py +1 -0
- universal_mcp/applications/wrike/app.py +1583 -0
- universal_mcp/applications/youtube/README.md +57 -0
- universal_mcp/applications/youtube/__init__.py +1 -0
- universal_mcp/applications/youtube/app.py +1696 -0
- universal_mcp/applications/zenquotes/README.md +12 -0
- universal_mcp/applications/zenquotes/__init__.py +1 -0
- universal_mcp/applications/zenquotes/app.py +31 -0
- universal_mcp_applications-0.1.1.dist-info/METADATA +172 -0
- universal_mcp_applications-0.1.1.dist-info/RECORD +268 -0
- universal_mcp_applications-0.1.1.dist-info/WHEEL +4 -0
- universal_mcp_applications-0.1.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
from collections.abc import Callable # For type hinting
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from gql import gql
|
|
5
|
+
from universal_mcp.applications import (
|
|
6
|
+
GraphQLApplication,
|
|
7
|
+
) # Assuming this is in a reachable path
|
|
8
|
+
from universal_mcp.integrations import Integration
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FirefliesApp(GraphQLApplication):
|
|
12
|
+
"""
|
|
13
|
+
Application for interacting with the Fireflies.ai GraphQL API.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, integration: Integration | None = None, **kwargs: Any) -> None:
|
|
17
|
+
super().__init__(
|
|
18
|
+
name="fireflies", base_url="https://api.fireflies.ai/graphql", **kwargs
|
|
19
|
+
)
|
|
20
|
+
self.integration = integration
|
|
21
|
+
|
|
22
|
+
def get_team_analytics(
|
|
23
|
+
self, start_time: str | None = None, end_time: str | None = None
|
|
24
|
+
) -> dict[str, Any]:
|
|
25
|
+
"""
|
|
26
|
+
Fetches team analytics data within a specified time range.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
start_time: Optional start time for analytics (ISO 8601 format, e.g., "2024-01-01T00:00:00Z").
|
|
30
|
+
end_time: Optional end time for analytics (ISO 8601 format, e.g., "2024-01-31T23:59:59Z").
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
A dictionary containing team analytics data.
|
|
34
|
+
Example: {"team": {"conversation": {"average_filler_words": 0.5}}}
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
Exception: If the API request fails.
|
|
38
|
+
|
|
39
|
+
Tags:
|
|
40
|
+
analytics, team, fireflies, query
|
|
41
|
+
"""
|
|
42
|
+
query_gql = gql("""
|
|
43
|
+
query Analytics($startTime: String, $endTime: String) {
|
|
44
|
+
analytics(start_time: $startTime, end_time: $endTime) {
|
|
45
|
+
team {
|
|
46
|
+
conversation {
|
|
47
|
+
average_filler_words
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
""")
|
|
53
|
+
variables: dict[str, Any] = {}
|
|
54
|
+
if start_time:
|
|
55
|
+
variables["startTime"] = start_time
|
|
56
|
+
if end_time:
|
|
57
|
+
variables["endTime"] = end_time
|
|
58
|
+
|
|
59
|
+
result = self.query(query_gql, variables=variables if variables else None)
|
|
60
|
+
return result.get("analytics", {})
|
|
61
|
+
|
|
62
|
+
def get_ai_apps_outputs(self, transcript_id: str) -> list[dict[str, Any]]:
|
|
63
|
+
"""
|
|
64
|
+
Fetches AI Apps outputs for a given transcript.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
transcript_id: The ID of the transcript.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
A list of dictionaries, each representing an AI app output.
|
|
71
|
+
Example: [{"transcript_id": "...", "user_id": "...", ...}]
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
Exception: If the API request fails.
|
|
75
|
+
|
|
76
|
+
Tags:
|
|
77
|
+
ai, apps, transcript, fireflies, query
|
|
78
|
+
"""
|
|
79
|
+
query_gql = gql("""
|
|
80
|
+
query GetAIAppsOutputs($transcriptId: String!) {
|
|
81
|
+
apps(transcript_id: $transcriptId) {
|
|
82
|
+
outputs {
|
|
83
|
+
transcript_id
|
|
84
|
+
user_id
|
|
85
|
+
app_id
|
|
86
|
+
created_at
|
|
87
|
+
title
|
|
88
|
+
prompt
|
|
89
|
+
response
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
""")
|
|
94
|
+
variables = {"transcriptId": transcript_id}
|
|
95
|
+
result = self.query(query_gql, variables=variables)
|
|
96
|
+
return result.get("apps", {})
|
|
97
|
+
|
|
98
|
+
def get_user_details(self, user_id: str) -> dict[str, Any]:
|
|
99
|
+
"""
|
|
100
|
+
Fetches details for a specific user.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
user_id: The ID of the user.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
A dictionary containing user details (e.g., name, integrations).
|
|
107
|
+
Example: {"name": "John Doe", "integrations": [...]}
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
Exception: If the API request fails.
|
|
111
|
+
|
|
112
|
+
Tags:
|
|
113
|
+
user, details, fireflies, query, important
|
|
114
|
+
"""
|
|
115
|
+
query_gql = gql("""
|
|
116
|
+
query User($userId: String!) {
|
|
117
|
+
user(id: $userId) {
|
|
118
|
+
name
|
|
119
|
+
integrations
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
""")
|
|
123
|
+
variables = {"userId": user_id}
|
|
124
|
+
result = self.query(query_gql, variables=variables)
|
|
125
|
+
return result.get("user", {})
|
|
126
|
+
|
|
127
|
+
def list_users(self) -> list[dict[str, Any]]:
|
|
128
|
+
"""
|
|
129
|
+
Fetches a list of users in the workspace.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
A list of dictionaries, each representing a user with their name and integrations.
|
|
133
|
+
Example: [{"name": "Justin Fly", "integrations": ["zoom", "slack"]}, ...]
|
|
134
|
+
|
|
135
|
+
Raises:
|
|
136
|
+
Exception: If the API request fails.
|
|
137
|
+
|
|
138
|
+
Tags:
|
|
139
|
+
user, list, users, fireflies, query
|
|
140
|
+
"""
|
|
141
|
+
query_str = """
|
|
142
|
+
query ListAllUsers {
|
|
143
|
+
users {
|
|
144
|
+
name
|
|
145
|
+
integrations
|
|
146
|
+
# You might want to add other available user fields here if needed, e.g.:
|
|
147
|
+
# id
|
|
148
|
+
# email
|
|
149
|
+
# role
|
|
150
|
+
# is_admin
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
"""
|
|
154
|
+
result = self.query(query_str)
|
|
155
|
+
return result.get("users", [])
|
|
156
|
+
|
|
157
|
+
def get_transcript_details(self, transcript_id: str) -> dict[str, Any]:
|
|
158
|
+
"""
|
|
159
|
+
Fetches details for a specific transcript.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
transcript_id: The ID of the transcript.
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
A dictionary containing transcript details (e.g., title, id).
|
|
166
|
+
Example: {"title": "Meeting Notes", "id": "..."}
|
|
167
|
+
|
|
168
|
+
Raises:
|
|
169
|
+
Exception: If the API request fails.
|
|
170
|
+
|
|
171
|
+
Tags:
|
|
172
|
+
transcript, details, fireflies, query, important
|
|
173
|
+
"""
|
|
174
|
+
query_gql = gql("""
|
|
175
|
+
query Transcript($transcriptId: String!) {
|
|
176
|
+
transcript(id: $transcriptId) {
|
|
177
|
+
title
|
|
178
|
+
id
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
""")
|
|
182
|
+
variables = {"transcriptId": transcript_id}
|
|
183
|
+
result = self.query(query_gql, variables=variables)
|
|
184
|
+
return result.get("transcript", {})
|
|
185
|
+
|
|
186
|
+
def list_transcripts(self, user_id: str | None = None) -> list[dict[str, Any]]:
|
|
187
|
+
"""
|
|
188
|
+
Fetches a list of transcripts, optionally filtered by user ID.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
user_id: Optional ID of the user to filter transcripts for.
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
A list of dictionaries, each representing a transcript (e.g., title, id).
|
|
195
|
+
Example: [{"title": "Meeting 1", "id": "..."}, {"title": "Meeting 2", "id": "..."}]
|
|
196
|
+
|
|
197
|
+
Raises:
|
|
198
|
+
Exception: If the API request fails.
|
|
199
|
+
|
|
200
|
+
Tags:
|
|
201
|
+
transcript, list, fireflies, query
|
|
202
|
+
"""
|
|
203
|
+
query_gql = gql("""
|
|
204
|
+
query Transcripts($userId: String) {
|
|
205
|
+
transcripts(user_id: $userId) {
|
|
206
|
+
title
|
|
207
|
+
id
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
""")
|
|
211
|
+
variables: dict[str, Any] = {}
|
|
212
|
+
if user_id:
|
|
213
|
+
variables["userId"] = user_id
|
|
214
|
+
result = self.query(query_gql, variables=variables if variables else None)
|
|
215
|
+
return result.get("transcripts", [])
|
|
216
|
+
|
|
217
|
+
def get_bite_details(self, bite_id: str) -> dict[str, Any]:
|
|
218
|
+
"""
|
|
219
|
+
Fetches details for a specific bite (soundbite/clip).
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
bite_id: The ID of the bite.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
A dictionary containing bite details (e.g., user_id, name, status, summary).
|
|
226
|
+
Example: {"user_id": "...", "name": "Key Moment", "status": "processed", "summary": "..."}
|
|
227
|
+
|
|
228
|
+
Raises:
|
|
229
|
+
Exception: If the API request fails.
|
|
230
|
+
|
|
231
|
+
Tags:
|
|
232
|
+
bite, details, fireflies, query
|
|
233
|
+
"""
|
|
234
|
+
query_gql = gql("""
|
|
235
|
+
query Bite($biteId: ID!) {
|
|
236
|
+
bite(id: $biteId) {
|
|
237
|
+
user_id
|
|
238
|
+
name
|
|
239
|
+
status
|
|
240
|
+
summary
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
""")
|
|
244
|
+
variables = {"biteId": bite_id}
|
|
245
|
+
result = self.query(query_gql, variables=variables)
|
|
246
|
+
return result.get("bite", {})
|
|
247
|
+
|
|
248
|
+
def list_bites(self, mine: bool | None = None) -> list[dict[str, Any]]:
|
|
249
|
+
"""
|
|
250
|
+
Fetches a list of bites, optionally filtered to the current user's bites.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
mine: Optional boolean to filter for the authenticated user's bites (default true if not specified by API).
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
A list of dictionaries, each representing a bite (e.g., user_id, name, end_time).
|
|
257
|
+
Example: [{"user_id": "...", "name": "Clip 1", "end_time": "..."}]
|
|
258
|
+
|
|
259
|
+
Raises:
|
|
260
|
+
Exception: If the API request fails.
|
|
261
|
+
|
|
262
|
+
Tags:
|
|
263
|
+
bite, list, fireflies, query
|
|
264
|
+
"""
|
|
265
|
+
query_gql = gql("""
|
|
266
|
+
query Bites($mine: Boolean) {
|
|
267
|
+
bites(mine: $mine) {
|
|
268
|
+
user_id
|
|
269
|
+
name
|
|
270
|
+
end_time
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
""")
|
|
274
|
+
variables: dict[str, Any] = {}
|
|
275
|
+
if (
|
|
276
|
+
mine is not None
|
|
277
|
+
): # API might default this, ensure we only send if explicitly set
|
|
278
|
+
variables["mine"] = mine
|
|
279
|
+
result = self.query(query_gql, variables=variables if variables else None)
|
|
280
|
+
return result.get("bites", [])
|
|
281
|
+
|
|
282
|
+
def add_to_live_meeting(self, meeting_link: str) -> dict[str, Any]:
|
|
283
|
+
"""
|
|
284
|
+
Adds Fireflies.ai to a live meeting.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
meeting_link: The URL of the live meeting (e.g., Google Meet link).
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
A dictionary indicating the success of the operation.
|
|
291
|
+
Example: {"success": true}
|
|
292
|
+
|
|
293
|
+
Raises:
|
|
294
|
+
Exception: If the API request fails.
|
|
295
|
+
|
|
296
|
+
Tags:
|
|
297
|
+
meeting, live, fireflies, mutation, important
|
|
298
|
+
"""
|
|
299
|
+
mutation_gql = gql("""
|
|
300
|
+
mutation AddToLiveMeeting($meetingLink: String!) {
|
|
301
|
+
addToLiveMeeting(meeting_link: $meetingLink) {
|
|
302
|
+
success
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
""")
|
|
306
|
+
variables = {"meetingLink": meeting_link}
|
|
307
|
+
result = self.mutate(mutation_gql, variables=variables)
|
|
308
|
+
return result.get("addToLiveMeeting", {})
|
|
309
|
+
|
|
310
|
+
def create_bite(
|
|
311
|
+
self, transcript_id: str, start_time: float, end_time: float
|
|
312
|
+
) -> dict[str, Any]:
|
|
313
|
+
"""
|
|
314
|
+
Creates a bite (soundbite/clip) from a transcript.
|
|
315
|
+
|
|
316
|
+
Args:
|
|
317
|
+
transcript_id: The ID of the transcript.
|
|
318
|
+
start_time: The start time of the bite in seconds (or relevant float unit).
|
|
319
|
+
end_time: The end time of the bite in seconds (or relevant float unit).
|
|
320
|
+
|
|
321
|
+
Returns:
|
|
322
|
+
A dictionary containing details of the created bite (e.g., summary, status, id).
|
|
323
|
+
Example: {"summary": "...", "status": "processing", "id": "..."}
|
|
324
|
+
|
|
325
|
+
Raises:
|
|
326
|
+
Exception: If the API request fails.
|
|
327
|
+
|
|
328
|
+
Tags:
|
|
329
|
+
bite, create, transcript, fireflies, mutation
|
|
330
|
+
"""
|
|
331
|
+
mutation_gql = gql("""
|
|
332
|
+
mutation CreateBite($transcriptId: ID!, $startTime: Float!, $endTime: Float!) {
|
|
333
|
+
createBite(transcript_id: $transcriptId, start_time: $startTime, end_time: $endTime) {
|
|
334
|
+
summary
|
|
335
|
+
status
|
|
336
|
+
id
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
""")
|
|
340
|
+
variables = {
|
|
341
|
+
"transcriptId": transcript_id,
|
|
342
|
+
"startTime": start_time,
|
|
343
|
+
"endTime": end_time,
|
|
344
|
+
}
|
|
345
|
+
result = self.mutate(mutation_gql, variables=variables)
|
|
346
|
+
return result.get("createBite", {})
|
|
347
|
+
|
|
348
|
+
def delete_transcript(self, transcript_id: str) -> dict[str, Any]:
|
|
349
|
+
"""
|
|
350
|
+
Deletes a transcript.
|
|
351
|
+
|
|
352
|
+
Args:
|
|
353
|
+
transcript_id: The ID of the transcript to delete.
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
A dictionary containing details of the deleted transcript.
|
|
357
|
+
Example: {"title": "Old Meeting", "date": "...", "duration": ..., "organizer_email": "..."}
|
|
358
|
+
|
|
359
|
+
Raises:
|
|
360
|
+
Exception: If the API request fails.
|
|
361
|
+
|
|
362
|
+
Tags:
|
|
363
|
+
transcript, delete, fireflies, mutation, destructive
|
|
364
|
+
"""
|
|
365
|
+
mutation_gql = gql("""
|
|
366
|
+
mutation DeleteTranscript($transcriptId: String!) {
|
|
367
|
+
deleteTranscript(id: $transcriptId) {
|
|
368
|
+
title
|
|
369
|
+
date
|
|
370
|
+
duration
|
|
371
|
+
organizer_email
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
""")
|
|
375
|
+
variables = {"transcriptId": transcript_id}
|
|
376
|
+
result = self.mutate(mutation_gql, variables=variables)
|
|
377
|
+
return result.get("deleteTranscript", {})
|
|
378
|
+
|
|
379
|
+
def set_user_role(self, user_id: str, role: str) -> dict[str, Any]:
|
|
380
|
+
"""
|
|
381
|
+
Sets the role for a user.
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
user_id: The ID of the user.
|
|
385
|
+
role: The role to assign (e.g., "admin", "member").
|
|
386
|
+
|
|
387
|
+
Returns:
|
|
388
|
+
A dictionary containing the updated user details (e.g., name, is_admin).
|
|
389
|
+
Example: {"name": "Jane Doe", "is_admin": true}
|
|
390
|
+
|
|
391
|
+
Raises:
|
|
392
|
+
Exception: If the API request fails.
|
|
393
|
+
|
|
394
|
+
Tags:
|
|
395
|
+
user, role, admin, fireflies, mutation
|
|
396
|
+
"""
|
|
397
|
+
mutation_gql = gql("""
|
|
398
|
+
mutation SetUserRole($user_id: String!, $role: Role!) {
|
|
399
|
+
setUserRole(user_id: $user_id, role: $role) {
|
|
400
|
+
name
|
|
401
|
+
is_admin
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
""")
|
|
405
|
+
variables = {"user_id": user_id, "role": role}
|
|
406
|
+
result = self.mutate(mutation_gql, variables=variables)
|
|
407
|
+
return result.get("setUserRole", {})
|
|
408
|
+
|
|
409
|
+
def upload_audio(
|
|
410
|
+
self,
|
|
411
|
+
url: str,
|
|
412
|
+
title: str | None = None,
|
|
413
|
+
attendees: list[dict[str, str]] | None = None,
|
|
414
|
+
) -> dict[str, Any]:
|
|
415
|
+
"""
|
|
416
|
+
Uploads an audio file for transcription.
|
|
417
|
+
|
|
418
|
+
Args:
|
|
419
|
+
url: The URL of the audio file.
|
|
420
|
+
title: Optional title for the uploaded audio.
|
|
421
|
+
attendees: Optional list of attendees. Each attendee is a dict
|
|
422
|
+
with "displayName", "email", "phoneNumber".
|
|
423
|
+
|
|
424
|
+
Returns:
|
|
425
|
+
A dictionary indicating the success and details of the upload.
|
|
426
|
+
Example: {"success": true, "title": "Uploaded Audio", "message": "..."}
|
|
427
|
+
|
|
428
|
+
Raises:
|
|
429
|
+
Exception: If the API request fails.
|
|
430
|
+
|
|
431
|
+
Tags:
|
|
432
|
+
audio, upload, transcript, fireflies, mutation
|
|
433
|
+
"""
|
|
434
|
+
mutation_gql = gql("""
|
|
435
|
+
mutation UploadAudio($input: AudioUploadInput!) {
|
|
436
|
+
uploadAudio(input: $input) {
|
|
437
|
+
success
|
|
438
|
+
title
|
|
439
|
+
message
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
""")
|
|
443
|
+
input_data: dict[str, Any] = {"url": url}
|
|
444
|
+
if title:
|
|
445
|
+
input_data["title"] = title
|
|
446
|
+
if attendees:
|
|
447
|
+
input_data["attendees"] = attendees
|
|
448
|
+
|
|
449
|
+
variables = {"input": input_data}
|
|
450
|
+
result = self.mutate(mutation_gql, variables=variables)
|
|
451
|
+
return result.get("uploadAudio", {})
|
|
452
|
+
|
|
453
|
+
def update_meeting_title(
|
|
454
|
+
self, transcript_id: str, new_title: str
|
|
455
|
+
) -> dict[str, Any]:
|
|
456
|
+
"""
|
|
457
|
+
Updates the title of a meeting (transcript).
|
|
458
|
+
|
|
459
|
+
Args:
|
|
460
|
+
transcript_id: The ID of the transcript to update.
|
|
461
|
+
new_title: The new title for the meeting.
|
|
462
|
+
|
|
463
|
+
Returns:
|
|
464
|
+
A dictionary containing the updated title.
|
|
465
|
+
Example: {"title": "New Meeting Title"}
|
|
466
|
+
|
|
467
|
+
Raises:
|
|
468
|
+
Exception: If the API request fails.
|
|
469
|
+
|
|
470
|
+
Tags:
|
|
471
|
+
transcript, meeting, title, update, fireflies, mutation
|
|
472
|
+
"""
|
|
473
|
+
mutation_gql = gql("""
|
|
474
|
+
mutation UpdateMeetingTitle($input: UpdateMeetingTitleInput!) {
|
|
475
|
+
updateMeetingTitle(input: $input) {
|
|
476
|
+
title
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
""")
|
|
480
|
+
variables = {"input": {"id": transcript_id, "title": new_title}}
|
|
481
|
+
result = self.mutate(mutation_gql, variables=variables)
|
|
482
|
+
return result.get("updateMeetingTitle", {})
|
|
483
|
+
|
|
484
|
+
def list_tools(self) -> list[Callable[..., Any]]:
|
|
485
|
+
"""
|
|
486
|
+
Lists all available tools (public methods) for the FirefliesApp.
|
|
487
|
+
|
|
488
|
+
Returns:
|
|
489
|
+
A list of callable tool methods.
|
|
490
|
+
"""
|
|
491
|
+
return [
|
|
492
|
+
self.get_team_analytics,
|
|
493
|
+
self.get_ai_apps_outputs,
|
|
494
|
+
self.get_user_details,
|
|
495
|
+
self.list_users,
|
|
496
|
+
self.get_transcript_details,
|
|
497
|
+
self.list_transcripts,
|
|
498
|
+
self.get_bite_details,
|
|
499
|
+
self.list_bites,
|
|
500
|
+
self.add_to_live_meeting,
|
|
501
|
+
self.create_bite,
|
|
502
|
+
self.delete_transcript,
|
|
503
|
+
self.set_user_role,
|
|
504
|
+
self.upload_audio,
|
|
505
|
+
self.update_meeting_title,
|
|
506
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# FplApp MCP Server
|
|
2
|
+
|
|
3
|
+
An MCP Server for the FplApp API.
|
|
4
|
+
|
|
5
|
+
## 🛠️ Tool List
|
|
6
|
+
|
|
7
|
+
This is automatically generated from OpenAPI schema for the FplApp API.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
| Tool | Description |
|
|
11
|
+
|------|-------------|
|
|
12
|
+
| `get_player_information` | Get detailed information and statistics for a specific player |
|
|
13
|
+
| `search_fpl_players` | Search for FPL players by name with optional filtering |
|
|
14
|
+
| `get_gameweek_status` | Get precise information about current, previous, and next gameweeks. |
|
|
15
|
+
| `analyze_players` | Filter and analyze FPL players based on multiple criteria |
|
|
16
|
+
| `compare_players` | Compare multiple players across various metrics |
|
|
17
|
+
| `analyze_player_fixtures` | Analyze upcoming fixtures for a player and provide a difficulty rating |
|
|
18
|
+
| `analyze_fixtures` | Analyze upcoming fixtures for players, teams, or positions |
|
|
19
|
+
| `get_blank_gameweeks` | Get information about upcoming blank gameweeks where teams don't have fixtures |
|
|
20
|
+
| `get_double_gameweeks` | Get information about upcoming double gameweeks where teams have multiple fixtures |
|
|
21
|
+
| `get_league_standings` | Get standings for a specified FPL league |
|
|
22
|
+
| `get_league_analytics` | Get rich analytics for a Fantasy Premier League mini-league |
|
|
23
|
+
| `team_info` | Get information about a team |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .app import FplApp
|