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.
Files changed (33) hide show
  1. universal_mcp/applications/__init__.py +51 -7
  2. universal_mcp/applications/curstdata/README.md +50 -0
  3. universal_mcp/applications/curstdata/__init__.py +0 -0
  4. universal_mcp/applications/curstdata/app.py +551 -0
  5. universal_mcp/applications/falai/app.py +8 -8
  6. universal_mcp/applications/neon/README.md +99 -0
  7. universal_mcp/applications/neon/__init__.py +0 -0
  8. universal_mcp/applications/neon/app.py +1924 -0
  9. universal_mcp/applications/shortcut/README.md +153 -0
  10. universal_mcp/applications/shortcut/__init__.py +0 -0
  11. universal_mcp/applications/shortcut/app.py +3880 -0
  12. universal_mcp/cli.py +109 -17
  13. universal_mcp/integrations/__init__.py +1 -1
  14. universal_mcp/integrations/integration.py +79 -0
  15. universal_mcp/servers/README.md +79 -0
  16. universal_mcp/servers/server.py +17 -29
  17. universal_mcp/stores/README.md +74 -0
  18. universal_mcp/stores/store.py +0 -2
  19. universal_mcp/templates/README.md.j2 +93 -0
  20. universal_mcp/templates/api_client.py.j2 +27 -0
  21. universal_mcp/tools/README.md +86 -0
  22. universal_mcp/tools/tools.py +1 -1
  23. universal_mcp/utils/agentr.py +90 -0
  24. universal_mcp/utils/api_generator.py +166 -208
  25. universal_mcp/utils/openapi.py +221 -321
  26. universal_mcp/utils/singleton.py +23 -0
  27. {universal_mcp-0.1.11rc3.dist-info → universal_mcp-0.1.13rc1.dist-info}/METADATA +16 -41
  28. {universal_mcp-0.1.11rc3.dist-info → universal_mcp-0.1.13rc1.dist-info}/RECORD +30 -17
  29. universal_mcp/applications/hashnode/app.py +0 -81
  30. universal_mcp/applications/hashnode/prompt.md +0 -23
  31. universal_mcp/integrations/agentr.py +0 -112
  32. {universal_mcp-0.1.11rc3.dist-info → universal_mcp-0.1.13rc1.dist-info}/WHEEL +0 -0
  33. {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.11rc3
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=DG-Qxc5vQIdbhAIQuU7bKKJuRGzwyOigjfCKSWBRhBI,5258
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=7s5c2j3Cbgdmqp7J1QKdehUQmlzSE0NLfkDE1U8Dl1A,825
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=S6gaXLWBgTm_EBqH8aBUKih5iM2EL6gbRSAJ5Xmcfzg,12323
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=YY8Uw0XGNUpAQ1j-qgCOrwHTcuSew4W92cEtYXMxry4,963
99
- universal_mcp/integrations/agentr.py,sha256=Bap4PA2-K4BkBhscgAVsBdvXNN19dkuCLO82sQFRvUM,3952
100
- universal_mcp/integrations/integration.py,sha256=imzxq1jZJAjq9odF6ttCUS2-yQW7qqG8NNUj1LudT9U,9986
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=bm1gprc_6TPB8iShI6H7Kzp8CWsW5A51vb8DHW8AiUA,9916
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=lYaFd-9YKC404BPeqzNw_Xm3ziQjksZyvQtaW1yd9FM,6900
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=PbvTi8A1hT7F8UXiiP291aP_oZmIPBfhfcgqR8XeSqo,12978
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/api_generator.py,sha256=-wRBpLVfJQXy1R-8FpDNs6b8_eeekVDuPc_uwjSGgiY,8883
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=AgmcyntPyovic2mRqr-a7P4kEc7hU-yk9gRVIsO4078,20673
116
- universal_mcp-0.1.11rc3.dist-info/METADATA,sha256=xqOqfP8KNm3BeQrvIuPzHUqx4KOSSTkm637FTcgmxEc,12435
117
- universal_mcp-0.1.11rc3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
118
- universal_mcp-0.1.11rc3.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
119
- universal_mcp-0.1.11rc3.dist-info/RECORD,,
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."