universal-mcp 0.1.11rc3__py3-none-any.whl → 0.1.13rc1__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/__init__.py +51 -7
- universal_mcp/applications/curstdata/README.md +50 -0
- universal_mcp/applications/curstdata/__init__.py +0 -0
- universal_mcp/applications/curstdata/app.py +551 -0
- universal_mcp/applications/falai/app.py +8 -8
- universal_mcp/applications/neon/README.md +99 -0
- universal_mcp/applications/neon/__init__.py +0 -0
- universal_mcp/applications/neon/app.py +1924 -0
- universal_mcp/applications/shortcut/README.md +153 -0
- universal_mcp/applications/shortcut/__init__.py +0 -0
- universal_mcp/applications/shortcut/app.py +3880 -0
- universal_mcp/cli.py +109 -17
- universal_mcp/integrations/__init__.py +1 -1
- universal_mcp/integrations/integration.py +79 -0
- universal_mcp/servers/README.md +79 -0
- universal_mcp/servers/server.py +17 -29
- universal_mcp/stores/README.md +74 -0
- universal_mcp/stores/store.py +0 -2
- universal_mcp/templates/README.md.j2 +93 -0
- universal_mcp/templates/api_client.py.j2 +27 -0
- universal_mcp/tools/README.md +86 -0
- universal_mcp/tools/tools.py +1 -1
- universal_mcp/utils/agentr.py +90 -0
- universal_mcp/utils/api_generator.py +166 -208
- universal_mcp/utils/openapi.py +221 -321
- universal_mcp/utils/singleton.py +23 -0
- {universal_mcp-0.1.11rc3.dist-info → universal_mcp-0.1.13rc1.dist-info}/METADATA +16 -41
- {universal_mcp-0.1.11rc3.dist-info → universal_mcp-0.1.13rc1.dist-info}/RECORD +30 -17
- universal_mcp/applications/hashnode/app.py +0 -81
- universal_mcp/applications/hashnode/prompt.md +0 -23
- universal_mcp/integrations/agentr.py +0 -112
- {universal_mcp-0.1.11rc3.dist-info → universal_mcp-0.1.13rc1.dist-info}/WHEEL +0 -0
- {universal_mcp-0.1.11rc3.dist-info → universal_mcp-0.1.13rc1.dist-info}/entry_points.txt +0 -0
@@ -1,13 +1,14 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: universal-mcp
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.13rc1
|
4
4
|
Summary: Universal MCP acts as a middle ware for your API applications. It can store your credentials, authorize, enable disable apps on the fly and much more.
|
5
5
|
Author-email: Manoj Bajaj <manojbajaj95@gmail.com>
|
6
|
+
License: MIT
|
6
7
|
Requires-Python: >=3.11
|
8
|
+
Requires-Dist: cookiecutter>=2.6.0
|
7
9
|
Requires-Dist: gql[all]>=3.5.2
|
10
|
+
Requires-Dist: jinja2>=3.1.3
|
8
11
|
Requires-Dist: keyring>=25.6.0
|
9
|
-
Requires-Dist: langchain-cerebras>=0.5.0
|
10
|
-
Requires-Dist: langchain-google-genai>=2.1.3
|
11
12
|
Requires-Dist: litellm>=1.30.7
|
12
13
|
Requires-Dist: loguru>=0.7.3
|
13
14
|
Requires-Dist: mcp>=1.6.0
|
@@ -18,17 +19,11 @@ Requires-Dist: pyyaml>=6.0.2
|
|
18
19
|
Requires-Dist: rich>=14.0.0
|
19
20
|
Requires-Dist: typer>=0.15.2
|
20
21
|
Provides-Extra: all
|
21
|
-
Requires-Dist: e2b-code-interpreter>=1.2.0; extra == 'all'
|
22
|
-
Requires-Dist: fal-client>=0.5.9; extra == 'all'
|
23
|
-
Requires-Dist: fastapi[standard]>=0.115.12; extra == 'all'
|
24
|
-
Requires-Dist: firecrawl-py>=1.15.0; extra == 'all'
|
25
|
-
Requires-Dist: google-search-results>=2.4.2; extra == 'all'
|
26
22
|
Requires-Dist: langchain-mcp-adapters>=0.0.3; extra == 'all'
|
27
23
|
Requires-Dist: langchain-openai>=0.3.12; extra == 'all'
|
28
24
|
Requires-Dist: langgraph-checkpoint-sqlite>=2.0.6; extra == 'all'
|
29
25
|
Requires-Dist: langgraph>=0.3.24; extra == 'all'
|
30
26
|
Requires-Dist: litellm>=1.30.7; extra == 'all'
|
31
|
-
Requires-Dist: markitdown[all]>=0.1.1; extra == 'all'
|
32
27
|
Requires-Dist: pyright>=1.1.398; extra == 'all'
|
33
28
|
Requires-Dist: pytest-asyncio>=0.26.0; extra == 'all'
|
34
29
|
Requires-Dist: pytest>=8.3.5; extra == 'all'
|
@@ -42,16 +37,7 @@ Requires-Dist: pyright>=1.1.398; extra == 'dev'
|
|
42
37
|
Requires-Dist: pytest-asyncio>=0.26.0; extra == 'dev'
|
43
38
|
Requires-Dist: pytest>=8.3.5; extra == 'dev'
|
44
39
|
Requires-Dist: ruff>=0.11.4; extra == 'dev'
|
45
|
-
Provides-Extra: e2b
|
46
|
-
Requires-Dist: e2b-code-interpreter>=1.2.0; extra == 'e2b'
|
47
|
-
Provides-Extra: fal-ai
|
48
|
-
Requires-Dist: fal-client>=0.5.9; extra == 'fal-ai'
|
49
|
-
Provides-Extra: firecrawl
|
50
|
-
Requires-Dist: firecrawl-py>=1.15.0; extra == 'firecrawl'
|
51
|
-
Provides-Extra: markitdown
|
52
|
-
Requires-Dist: markitdown[all]>=0.1.1; extra == 'markitdown'
|
53
40
|
Provides-Extra: playground
|
54
|
-
Requires-Dist: fastapi[standard]>=0.115.12; extra == 'playground'
|
55
41
|
Requires-Dist: langchain-mcp-adapters>=0.0.3; extra == 'playground'
|
56
42
|
Requires-Dist: langchain-openai>=0.3.12; extra == 'playground'
|
57
43
|
Requires-Dist: langgraph-checkpoint-sqlite>=2.0.6; extra == 'playground'
|
@@ -59,8 +45,6 @@ Requires-Dist: langgraph>=0.3.24; extra == 'playground'
|
|
59
45
|
Requires-Dist: python-dotenv>=1.0.1; extra == 'playground'
|
60
46
|
Requires-Dist: streamlit>=1.44.1; extra == 'playground'
|
61
47
|
Requires-Dist: watchdog>=6.0.0; extra == 'playground'
|
62
|
-
Provides-Extra: serpapi
|
63
|
-
Requires-Dist: google-search-results>=2.4.2; extra == 'serpapi'
|
64
48
|
Description-Content-Type: text/markdown
|
65
49
|
|
66
50
|
# Universal MCP
|
@@ -73,6 +57,8 @@ Universal MCP acts as a middleware layer for your API applications, enabling sea
|
|
73
57
|
- **Managed Authentication**: Built-in support for API keys and OAuth-based authentication flows
|
74
58
|
- **Extensible Architecture**: Easily build and add new app integrations with minimal boilerplate
|
75
59
|
- **Credential Management**: Flexible storage options for API credentials with memory and environment-based implementations
|
60
|
+
- **Tool Management**: Comprehensive tool registration, validation, and execution capabilities
|
61
|
+
- **Multiple Server Types**: Support for local, AgentR, and single-application server configurations
|
76
62
|
|
77
63
|
## 🔧 Installation
|
78
64
|
|
@@ -170,27 +156,7 @@ python src/playground
|
|
170
156
|
Refer to `src/playground/README.md` for more detailed setup and usage instructions.
|
171
157
|
|
172
158
|
## 🧩 Available Applications
|
173
|
-
|
174
|
-
Universal MCP comes with several pre-built applications:
|
175
|
-
|
176
|
-
| Application Slug | Description | Authentication Type |
|
177
|
-
| :--------------- | :--------------------------------------- | :---------------------------------------- |
|
178
|
-
| `e2b` | Execute Python code in secure sandboxes | API Key (via Integration) |
|
179
|
-
| `firecrawl` | Scrape/crawl web pages, search | API Key (via Integration) |
|
180
|
-
| `github` | Interact with GitHub repos, issues, PRs | OAuth (AgentR) |
|
181
|
-
| `google-calendar`| Manage Google Calendar events | OAuth (AgentR) |
|
182
|
-
| `google-docs` | Create and manage Google Docs documents | OAuth (AgentR) |
|
183
|
-
| `google-drive` | Manage Google Drive files and folders | OAuth (AgentR) |
|
184
|
-
| `google-mail` | Read and send Gmail emails | OAuth (AgentR) |
|
185
|
-
| `google-sheet` | Manage Google Sheets spreadsheets | OAuth (AgentR) |
|
186
|
-
| `markitdown` | Convert web pages/files to Markdown | None |
|
187
|
-
| `notion` | Interact with Notion pages/databases | OAuth (AgentR) |
|
188
|
-
| `perplexity` | Interact with Perplexity AI models | API Key (via Integration) |
|
189
|
-
| `reddit` | Interact with Reddit posts/comments | OAuth (AgentR) |
|
190
|
-
| `resend` | Send emails via Resend API | API Key (via Integration) |
|
191
|
-
| `serpapi` | Perform web searches via SerpApi | API Key (via Integration) |
|
192
|
-
| `tavily` | Advanced web search & research API | API Key (via Integration) |
|
193
|
-
| `zenquotes` | Get inspirational quotes | None |
|
159
|
+
Visit [https://agentr.dev](https://agentr.dev) to check all available applications
|
194
160
|
|
195
161
|
*Authentication Type notes:*
|
196
162
|
* *OAuth (AgentR)*: Typically requires configuring the integration with `type: "agentr"` in your `ServerConfig`. Requires the `AGENTR_API_KEY`.
|
@@ -275,6 +241,15 @@ universal_mcp --version
|
|
275
241
|
- `litellm` (optional, for `docgen` command)
|
276
242
|
- ... and others specific to certain applications.
|
277
243
|
|
244
|
+
## 📚 Documentation
|
245
|
+
|
246
|
+
For more detailed information about specific components:
|
247
|
+
|
248
|
+
- [Tools Documentation](src/universal_mcp/tools/README.md) - Learn about tool management and conversion
|
249
|
+
- [Servers Documentation](src/universal_mcp/servers/README.md) - Understand different server implementations
|
250
|
+
- [Stores Documentation](src/universal_mcp/stores/README.md) - Explore credential storage options
|
251
|
+
- [Integrations Documentation](src/universal_mcp/integrations/README.md) - Learn about authentication methods
|
252
|
+
|
278
253
|
## 📝 License
|
279
254
|
|
280
255
|
This project is licensed under the MIT License.
|
@@ -1,11 +1,11 @@
|
|
1
1
|
universal_mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
universal_mcp/analytics.py,sha256=aGCg0Okpcy06W70qCA9I8_ySOiCgAtzJAIWAdhBsOeA,2212
|
3
|
-
universal_mcp/cli.py,sha256=
|
3
|
+
universal_mcp/cli.py,sha256=kJwUvIG3RJQ62wiZaf8qgO_N7Gnrye7kH5BBOCDXeaQ,8212
|
4
4
|
universal_mcp/config.py,sha256=sJaPI4q51CDPPG0z32rMJiE7a64eaa9nxbjJgYnaFA4,838
|
5
5
|
universal_mcp/exceptions.py,sha256=WApedvzArNujD0gZfUofYBxjQo97ZDJLqDibtLWZoRk,373
|
6
6
|
universal_mcp/logger.py,sha256=D947u1roUf6WqlcEsPpvmWDqGc8L41qF3MO1suK5O1Q,308
|
7
7
|
universal_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
universal_mcp/applications/__init__.py,sha256=
|
8
|
+
universal_mcp/applications/__init__.py,sha256=7rghGqPTKDqpzjYo7JshagaAEyU8CcLaQ07TjwM4TTU,2808
|
9
9
|
universal_mcp/applications/application.py,sha256=0eC9D4HHRwIGpuFusaCxTZ0u64U68VbBpRSxjxGB5y8,8152
|
10
10
|
universal_mcp/applications/ahrefs/README.md,sha256=bQQ5AmPFxM52gL-tllIFWC_64f7KYkBiD1tYfdTwDu4,5370
|
11
11
|
universal_mcp/applications/ahrefs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -22,6 +22,9 @@ universal_mcp/applications/clickup/app.py,sha256=byJFbwbzt0Pg7CQ2Eyqnrdqi_iFfF2a
|
|
22
22
|
universal_mcp/applications/coda/README.md,sha256=4i6o_R-qtTuxfS1A7VoIb8_85FHAj-WVb8YG5fNvwL4,11411
|
23
23
|
universal_mcp/applications/coda/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
24
|
universal_mcp/applications/coda/app.py,sha256=47ZmtYF5A2Cn0rh3Dpc3VtkIHR1Xu2PCYe1JDH8kJbY,155862
|
25
|
+
universal_mcp/applications/curstdata/README.md,sha256=imieeO25UDSJjxxrgfNGCBxrtxl2jOAXD5ITHqNUhHc,2388
|
26
|
+
universal_mcp/applications/curstdata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
|
+
universal_mcp/applications/curstdata/app.py,sha256=p8vEBfhnptHB1CrKMBM1Jfa5gXfeouXMN--UdK4DcFk,24949
|
25
28
|
universal_mcp/applications/e2b/README.md,sha256=S4lTp-vEZ8VTCKPXqjUXu5nYlUMAF8lw8CQyBGPgxjs,700
|
26
29
|
universal_mcp/applications/e2b/app.py,sha256=4cMuGHm_QY4uh0JMh3HYzhaqtnfnXajRKFhoAGmRnBE,2252
|
27
30
|
universal_mcp/applications/elevenlabs/README.md,sha256=KSNBY0efc3XK_6kTM1YZQo8uVv34qhJ3IGGChIAhEQU,8196
|
@@ -29,7 +32,7 @@ universal_mcp/applications/elevenlabs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
29
32
|
universal_mcp/applications/elevenlabs/app.py,sha256=A43xAyQNIbdH8Y1MHw_fmnjmH9MR14TTzeFjg4h8Pek,66722
|
30
33
|
universal_mcp/applications/falai/README.md,sha256=fc31zlKe09FsOw6W5KY7VipxvKhon4KQoWjTdoMlPfc,1449
|
31
34
|
universal_mcp/applications/falai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
|
-
universal_mcp/applications/falai/app.py,sha256=
|
35
|
+
universal_mcp/applications/falai/app.py,sha256=XLHmuRkOCHhVsF3h0TKql4SmQ4h5LbkWKudcvs6Ydhc,12244
|
33
36
|
universal_mcp/applications/figma/README.md,sha256=qA9UMf5PsPhfJrnteGVQOudhLuevwZ4-D_1xM6gAjgQ,4393
|
34
37
|
universal_mcp/applications/figma/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
38
|
universal_mcp/applications/figma/app.py,sha256=sr-ednZinHdIcXmDWuWAA_Ri21iBbAYPRZ0-uLeiEkM,50392
|
@@ -49,8 +52,6 @@ universal_mcp/applications/google_mail/README.md,sha256=LL6TjjmwEqyuRVvIfCh-I_Pl
|
|
49
52
|
universal_mcp/applications/google_mail/app.py,sha256=1XI1hve2FXOqkzgJNYu2ki5J1yGKfeMx3cO_Qyflp_o,27286
|
50
53
|
universal_mcp/applications/google_sheet/README.md,sha256=yW1b_qlb_pbIJzCxZc58581kKzC5vyP8Mj4iwXgidtQ,1108
|
51
54
|
universal_mcp/applications/google_sheet/app.py,sha256=O6g8P697ve93CsljLK9ejWbIyzGbZ-_ThK_A_3cTpIk,6310
|
52
|
-
universal_mcp/applications/hashnode/app.py,sha256=v0OR00kkMqyL-NcclCuriCdGErE7PRvHoWScfvAeEXQ,2538
|
53
|
-
universal_mcp/applications/hashnode/prompt.md,sha256=K-LPmn2wchYEX2ytANDS4-fsKrhPphKPV62oYZ_n-M4,1742
|
54
55
|
universal_mcp/applications/heygen/README.md,sha256=8YW_JYxPMXIFqNlhp-IYtRN8CrPAR0Uh1q3FFzlPni0,4304
|
55
56
|
universal_mcp/applications/heygen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
56
57
|
universal_mcp/applications/heygen/app.py,sha256=2H0RI_zs-L2uT8TiCzCFtuLmuH6O2mDtmVIvNUu4qNA,35256
|
@@ -58,6 +59,9 @@ universal_mcp/applications/mailchimp/README.md,sha256=9p7rVwf0aX2lClVeMliUz8rFWt
|
|
58
59
|
universal_mcp/applications/mailchimp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
60
|
universal_mcp/applications/mailchimp/app.py,sha256=_ceKe-ZM6KTgi17WABs9I45dum1cTj0ZlnccJ9BQwuE,466711
|
60
61
|
universal_mcp/applications/markitdown/app.py,sha256=FeJONdT-Jwe5mJBelOfgpM1A3T-hIDfFGf1PCR5x1gA,1832
|
62
|
+
universal_mcp/applications/neon/README.md,sha256=RfWOgFIynMD1nX31cD31yuv0h0Y7mze093xMM5GlcWo,7436
|
63
|
+
universal_mcp/applications/neon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
|
+
universal_mcp/applications/neon/app.py,sha256=pGP4uNysbvP1MQ2wNFwwH-K-3vebO4PSxdVx1iOnUk4,84636
|
61
65
|
universal_mcp/applications/notion/README.md,sha256=45NmPOmSQv99qBvWdwmnV5vbaYc9_8vq8I-FA7veVAA,2600
|
62
66
|
universal_mcp/applications/notion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
63
67
|
universal_mcp/applications/notion/app.py,sha256=nc-p531L-L6gMFqOOkYu5Irn9SReWAYRmJ8ZOIv5LrQ,20834
|
@@ -78,6 +82,9 @@ universal_mcp/applications/rocketlane/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
78
82
|
universal_mcp/applications/rocketlane/app.py,sha256=EvHFiIi_hAuU_UqLCxkdXE3Cb9uNHZmunsUaNjiyfwU,6795
|
79
83
|
universal_mcp/applications/serpapi/README.md,sha256=hX4VeT2iL_67ZsMhKd60DAujQCh9K3IdHroHIq808RY,691
|
80
84
|
universal_mcp/applications/serpapi/app.py,sha256=krx9STkJI0vLarXo34emySv3fs9o9lmQ2qfjWbzxtg4,2918
|
85
|
+
universal_mcp/applications/shortcut/README.md,sha256=nQ3yAsdBRTwYFo5ihTU-mxZ3B_ByAKjT09AwBt079fc,10965
|
86
|
+
universal_mcp/applications/shortcut/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
87
|
+
universal_mcp/applications/shortcut/app.py,sha256=fiLNADllcYvlAtoQVS8rFeTrZOvWTypJZvfou3XPYRw,170245
|
81
88
|
universal_mcp/applications/spotify/README.md,sha256=iT8nx2_1jcpNqf6Xn3E0-oxmimg1Z1CYFAJg9qNR_4g,9626
|
82
89
|
universal_mcp/applications/spotify/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
83
90
|
universal_mcp/applications/spotify/app.py,sha256=x8QxvW9gjKtxjM58ECta1MN-_0lwPUGpnmW443a2OM0,105444
|
@@ -95,25 +102,31 @@ universal_mcp/applications/youtube/app.py,sha256=EQgeLNJS8Spm8xB82hSIBANJ4HR2-kt
|
|
95
102
|
universal_mcp/applications/zenquotes/README.md,sha256=wA3hjqjrkrczQaffpwyolSKq6gXmkLgeHx6_EQrYEOY,709
|
96
103
|
universal_mcp/applications/zenquotes/app.py,sha256=xp_nlW4LFi0Mw1GRWIde4k8eexXUJx1wNqNExJ0oeKA,1085
|
97
104
|
universal_mcp/integrations/README.md,sha256=lTAPXO2nivcBe1q7JT6PRa6v9Ns_ZersQMIdw-nmwEA,996
|
98
|
-
universal_mcp/integrations/__init__.py,sha256=
|
99
|
-
universal_mcp/integrations/
|
100
|
-
universal_mcp/
|
105
|
+
universal_mcp/integrations/__init__.py,sha256=fx0dn79M1YhCwxtDy5QKrqtez2fbowhfJtQeWCLm1wU,922
|
106
|
+
universal_mcp/integrations/integration.py,sha256=genBiaWuzCs-XCf3UD1j8PQYyGU3GiVO4uupSdJRHnA,12601
|
107
|
+
universal_mcp/servers/README.md,sha256=ytFlgp8-LO0oogMrHkMOp8SvFTwgsKgv7XhBVZGNTbM,2284
|
101
108
|
universal_mcp/servers/__init__.py,sha256=dDtvvMzbWskABlobTZHztrWMb3hbzgidza3BmEmIAD8,474
|
102
|
-
universal_mcp/servers/server.py,sha256=
|
109
|
+
universal_mcp/servers/server.py,sha256=j_WreQSSed-e_QFFffsuQxhr7XDexiR5Cls50qkdX-g,9439
|
110
|
+
universal_mcp/stores/README.md,sha256=jrPh_ow4ESH4BDGaSafilhOVaN8oQ9IFlFW-j5Z5hLA,2465
|
103
111
|
universal_mcp/stores/__init__.py,sha256=quvuwhZnpiSLuojf0NfmBx2xpaCulv3fbKtKaSCEmuM,603
|
104
|
-
universal_mcp/stores/store.py,sha256=
|
112
|
+
universal_mcp/stores/store.py,sha256=eaS2S2V0pg-9qj5gUup0de7RY1lW8GglA-isJdeg6l8,6898
|
113
|
+
universal_mcp/templates/README.md.j2,sha256=gNry-IrGUdumhgWyHFVxOKgXf_MR4RFK6SI6jF3Tuns,2564
|
114
|
+
universal_mcp/templates/api_client.py.j2,sha256=972Im7LNUAq3yZTfwDcgivnb-b8u6_JLKWXwoIwXXXQ,908
|
115
|
+
universal_mcp/tools/README.md,sha256=RuxliOFqV1ZEyeBdj3m8UKfkxAsfrxXh-b6V4ZGAk8I,2468
|
105
116
|
universal_mcp/tools/__init__.py,sha256=hVL-elJLwD_K87Gpw_s2_o43sQRPyRNOnxlzt0_Pfn8,72
|
106
117
|
universal_mcp/tools/adapters.py,sha256=2HvpyFiI0zg9dp0XshnG7t6KrVqFHM7hgtmgY1bsHN0,927
|
107
118
|
universal_mcp/tools/func_metadata.py,sha256=f_5LdDNsOu1DpXvDUeZYiJswVmwGZz6IMPtpJJ5B2-Y,7975
|
108
|
-
universal_mcp/tools/tools.py,sha256=
|
119
|
+
universal_mcp/tools/tools.py,sha256=Q1MoYSjKCBnQNv-lFWwbXzrYrVaVp-69bzLLOE5GyrE,12919
|
109
120
|
universal_mcp/utils/__init__.py,sha256=8wi4PGWu-SrFjNJ8U7fr2iFJ1ktqlDmSKj1xYd7KSDc,41
|
110
|
-
universal_mcp/utils/
|
121
|
+
universal_mcp/utils/agentr.py,sha256=RkKDbOu5M2q-_3jSQcTqI1vQdTCsidJri5QufzyUD20,3410
|
122
|
+
universal_mcp/utils/api_generator.py,sha256=bs7BTuEKWz9FNb49BofsLP29BHL3B0PRCtBaKLXoR0A,7949
|
111
123
|
universal_mcp/utils/docgen.py,sha256=yGBcBIr7dz3mNMGrCb_-JFsDf-ShmCKWWiPpuEj2SIU,21878
|
112
124
|
universal_mcp/utils/docstring_parser.py,sha256=j7aE-LLnBOPTJI0qXayf0NlYappzxICv5E_hUPNmAlc,11459
|
113
125
|
universal_mcp/utils/dump_app_tools.py,sha256=9bQePJ4ZKzGtcIYrBgLxbKDOZmL7ajIAHhXljT_AlyA,2041
|
114
126
|
universal_mcp/utils/installation.py,sha256=KPBojDlt2YfFY2DfJ9pUr5evFJ9QQGp99KQUsRkz9GQ,10235
|
115
|
-
universal_mcp/utils/openapi.py,sha256=
|
116
|
-
universal_mcp
|
117
|
-
universal_mcp-0.1.
|
118
|
-
universal_mcp-0.1.
|
119
|
-
universal_mcp-0.1.
|
127
|
+
universal_mcp/utils/openapi.py,sha256=Mojlihskv0xO0RGGhvjjFjVMBJEoRIcE1a2h_Tt9Ir0,15998
|
128
|
+
universal_mcp/utils/singleton.py,sha256=kolHnbS9yd5C7z-tzaUAD16GgI-thqJXysNi3sZM4No,733
|
129
|
+
universal_mcp-0.1.13rc1.dist-info/METADATA,sha256=Rusy1XR9UMTyUGsTQ0JF645RT1Zq2ysGQfFPEwssObY,10392
|
130
|
+
universal_mcp-0.1.13rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
131
|
+
universal_mcp-0.1.13rc1.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
|
132
|
+
universal_mcp-0.1.13rc1.dist-info/RECORD,,
|
@@ -1,81 +0,0 @@
|
|
1
|
-
from gql import gql
|
2
|
-
|
3
|
-
from universal_mcp.applications import GraphQLApplication
|
4
|
-
from universal_mcp.integrations import Integration
|
5
|
-
|
6
|
-
|
7
|
-
class HashnodeApp(GraphQLApplication):
|
8
|
-
def __init__(self, integration: Integration | None = None, **kwargs) -> None:
|
9
|
-
super().__init__(name="hashnode", base_url="https://gql.hashnode.com", **kwargs)
|
10
|
-
self.integration = integration
|
11
|
-
|
12
|
-
def publish_post(
|
13
|
-
self,
|
14
|
-
publication_id: str,
|
15
|
-
title: str,
|
16
|
-
content: str,
|
17
|
-
tags: list[str] = None,
|
18
|
-
slug: str = None,
|
19
|
-
subtitle: str = None,
|
20
|
-
cover_image: str = None,
|
21
|
-
) -> str:
|
22
|
-
"""
|
23
|
-
Publishes a post to Hashnode using the GraphQL API.
|
24
|
-
|
25
|
-
Args:
|
26
|
-
publication_id: The ID of the publication to publish the post to
|
27
|
-
title: The title of the post
|
28
|
-
content: The markdown content of the post
|
29
|
-
tags: Optional list of tag names to add to the post. Example: ["blog", "release-notes", "python", "ai"]
|
30
|
-
slug: Optional custom URL slug for the post. Example: "my-post"
|
31
|
-
subtitle: Optional subtitle for the post. Example: "A subtitle for my post"
|
32
|
-
cover_image: Optional cover image for the post. Example: "https://example.com/cover-image.jpg"
|
33
|
-
Returns:
|
34
|
-
The URL of the published post
|
35
|
-
|
36
|
-
Raises:
|
37
|
-
GraphQLError: If the API request fails
|
38
|
-
|
39
|
-
Tags:
|
40
|
-
publish, post, hashnode, api, important
|
41
|
-
"""
|
42
|
-
publish_post_mutation = gql("""
|
43
|
-
mutation PublishPost($input: PublishPostInput!) {
|
44
|
-
publishPost(input: $input) {
|
45
|
-
post {
|
46
|
-
url
|
47
|
-
}
|
48
|
-
}
|
49
|
-
}
|
50
|
-
""")
|
51
|
-
|
52
|
-
variables = {
|
53
|
-
"input": {
|
54
|
-
"publicationId": publication_id,
|
55
|
-
"title": title,
|
56
|
-
"contentMarkdown": content,
|
57
|
-
}
|
58
|
-
}
|
59
|
-
|
60
|
-
if tags:
|
61
|
-
variables["input"]["tags"] = [
|
62
|
-
{"name": tag, "slug": tag.replace(" ", "-").lower()} for tag in tags
|
63
|
-
]
|
64
|
-
|
65
|
-
if slug:
|
66
|
-
variables["input"]["slug"] = slug
|
67
|
-
|
68
|
-
if subtitle:
|
69
|
-
variables["input"]["subtitle"] = subtitle
|
70
|
-
|
71
|
-
if cover_image:
|
72
|
-
variables["input"]["bannerImageOptions"] = {
|
73
|
-
"url": cover_image,
|
74
|
-
"potrait": False,
|
75
|
-
}
|
76
|
-
|
77
|
-
result = self.mutate(publish_post_mutation, variables)
|
78
|
-
return result["publishPost"]["post"]["url"]
|
79
|
-
|
80
|
-
def list_tools(self):
|
81
|
-
return [self.publish_post]
|
@@ -1,23 +0,0 @@
|
|
1
|
-
Generate a blog post for given topic for agentr in a formal tone. Use perplexity to research for the topic and put up to date content. Once done publish the post to hashnode blog with publication id: 68077ed7fe54cfc2a84b253b
|
2
|
-
|
3
|
-
Specifically, provide:
|
4
|
-
- Slug (a concise, URL-friendly version of the title, ideally lowercase and using hyphens between words)
|
5
|
-
- Title: Craft a catchy, SEO-friendly title (e.g., "5 JavaScript Tips to Boost Your Code’s Performance")
|
6
|
-
- Subtitle
|
7
|
-
- Content (the full blog post, aiming for [desired length or detail level, e.g., 500 words, a comprehensive overview, etc.], written in the specified tone and following best practices for readability such as clear headings, subheadings, and concise paragraphs)
|
8
|
-
- Tags (a comma-separated list of relevant keywords or phrases, around [number, e.g., 3-5] tags, that categorize the blog post). Always include "blog"
|
9
|
-
|
10
|
-
## Writing Guidelines:
|
11
|
-
- Divide the content into clear sections with descriptive subheadings (use ## for main sections, ### for subsections)
|
12
|
-
- Use short paragraphs (2-4 sentences) for readability
|
13
|
-
- Include practical examples, code snippets (in ``` code blocks), or visuals where applicable
|
14
|
-
- Add 1-2 external links to credible sources for credibility.
|
15
|
-
- Conclusion: Summarize key points and include a call-to-action (e.g., “Try these tips and share your results!”).
|
16
|
-
|
17
|
-
Tone: Keep it conversational, professional, and approachable. Length: Aim for 800-1,500 words.
|
18
|
-
|
19
|
-
Markdown Formatting: Use proper Markdown syntax Embed images with Alt text and code with language . Create inline links wherever possible
|
20
|
-
|
21
|
-
Cover Image: Use fal ai tool to generate a cover image for the blog. Use landscape format
|
22
|
-
|
23
|
-
The topic is: "Grok3 vs Gemini2.5 vs GPT4.1 vs Sonnect 3.7"
|
@@ -1,112 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
|
3
|
-
import httpx
|
4
|
-
from loguru import logger
|
5
|
-
|
6
|
-
from universal_mcp.exceptions import NotAuthorizedError
|
7
|
-
from universal_mcp.integrations.integration import Integration
|
8
|
-
|
9
|
-
|
10
|
-
class AgentRIntegration(Integration):
|
11
|
-
"""Integration class for AgentR API authentication and authorization.
|
12
|
-
|
13
|
-
This class handles API key authentication and OAuth authorization flow for AgentR services.
|
14
|
-
|
15
|
-
Args:
|
16
|
-
name (str): Name of the integration
|
17
|
-
api_key (str, optional): AgentR API key. If not provided, will look for AGENTR_API_KEY env var
|
18
|
-
**kwargs: Additional keyword arguments passed to parent Integration class
|
19
|
-
|
20
|
-
Raises:
|
21
|
-
ValueError: If no API key is provided or found in environment variables
|
22
|
-
"""
|
23
|
-
|
24
|
-
def __init__(self, name: str, api_key: str = None, **kwargs):
|
25
|
-
super().__init__(name, **kwargs)
|
26
|
-
self.api_key = api_key or os.getenv("AGENTR_API_KEY")
|
27
|
-
if not self.api_key:
|
28
|
-
logger.error(
|
29
|
-
"API key for AgentR is missing. Please visit https://agentr.dev to create an API key, then set it as AGENTR_API_KEY environment variable."
|
30
|
-
)
|
31
|
-
raise ValueError("AgentR API key required - get one at https://agentr.dev")
|
32
|
-
self.base_url = os.getenv("AGENTR_BASE_URL", "https://api.agentr.dev").rstrip(
|
33
|
-
"/"
|
34
|
-
)
|
35
|
-
self._credentials = None
|
36
|
-
|
37
|
-
def set_credentials(self, credentials: dict | None = None):
|
38
|
-
"""Set credentials for the integration.
|
39
|
-
|
40
|
-
This method is not implemented for AgentR integration. Instead it redirects to the authorize flow.
|
41
|
-
|
42
|
-
Args:
|
43
|
-
credentials (dict | None, optional): Credentials dict (not used). Defaults to None.
|
44
|
-
|
45
|
-
Returns:
|
46
|
-
str: Authorization URL from authorize() method
|
47
|
-
"""
|
48
|
-
return self.authorize()
|
49
|
-
|
50
|
-
@property
|
51
|
-
def credentials(self):
|
52
|
-
"""Get credentials for the integration from the AgentR API.
|
53
|
-
|
54
|
-
Makes API request to retrieve stored credentials for this integration.
|
55
|
-
|
56
|
-
Returns:
|
57
|
-
dict: Credentials data from API response
|
58
|
-
|
59
|
-
Raises:
|
60
|
-
NotAuthorizedError: If credentials are not found (404 response)
|
61
|
-
HTTPError: For other API errors
|
62
|
-
"""
|
63
|
-
if self._credentials is not None:
|
64
|
-
return self._credentials
|
65
|
-
response = httpx.get(
|
66
|
-
f"{self.base_url}/api/{self.name}/credentials/",
|
67
|
-
headers={"accept": "application/json", "X-API-KEY": self.api_key},
|
68
|
-
)
|
69
|
-
if response.status_code == 404:
|
70
|
-
logger.warning(
|
71
|
-
f"No credentials found for {self.name}. Requesting authorization..."
|
72
|
-
)
|
73
|
-
action = self.authorize()
|
74
|
-
raise NotAuthorizedError(action)
|
75
|
-
response.raise_for_status()
|
76
|
-
data = response.json()
|
77
|
-
self._credentials = data
|
78
|
-
return self._credentials
|
79
|
-
|
80
|
-
def get_credentials(self):
|
81
|
-
"""Get credentials for the integration from the AgentR API.
|
82
|
-
|
83
|
-
Makes API request to retrieve stored credentials for this integration.
|
84
|
-
|
85
|
-
Returns:
|
86
|
-
dict: Credentials data from API response
|
87
|
-
|
88
|
-
Raises:
|
89
|
-
NotAuthorizedError: If credentials are not found (404 response)
|
90
|
-
HTTPError: For other API errors
|
91
|
-
"""
|
92
|
-
return self.credentials
|
93
|
-
|
94
|
-
def authorize(self):
|
95
|
-
"""Get authorization URL for the integration.
|
96
|
-
|
97
|
-
Makes API request to get OAuth authorization URL.
|
98
|
-
|
99
|
-
Returns:
|
100
|
-
str: Message containing authorization URL
|
101
|
-
|
102
|
-
Raises:
|
103
|
-
HTTPError: If API request fails
|
104
|
-
"""
|
105
|
-
response = httpx.get(
|
106
|
-
f"{self.base_url}/api/{self.name}/authorize/",
|
107
|
-
headers={"X-API-KEY": self.api_key},
|
108
|
-
)
|
109
|
-
response.raise_for_status()
|
110
|
-
url = response.json()
|
111
|
-
|
112
|
-
return f"Please ask the user to visit the following url to authorize the application: {url}. Render the url in proper markdown format with a clickable link."
|
File without changes
|
File without changes
|