camel-ai 0.2.38__py3-none-any.whl → 0.2.39__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.

Potentially problematic release.


This version of camel-ai might be problematic. Click here for more details.

Files changed (85) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +4 -0
  3. camel/agents/repo_agent.py +2 -2
  4. camel/benchmarks/apibank.py +1 -1
  5. camel/benchmarks/apibench.py +1 -1
  6. camel/configs/__init__.py +3 -0
  7. camel/configs/modelscope_config.py +59 -0
  8. camel/datagen/self_improving_cot.py +1 -1
  9. camel/datasets/__init__.py +2 -0
  10. camel/datasets/base_generator.py +22 -9
  11. camel/datasets/few_shot_generator.py +2 -3
  12. camel/datasets/self_instruct_generator.py +415 -0
  13. camel/embeddings/openai_compatible_embedding.py +13 -5
  14. camel/environments/models.py +1 -1
  15. camel/environments/single_step.py +155 -89
  16. camel/interpreters/docker_interpreter.py +1 -1
  17. camel/interpreters/internal_python_interpreter.py +1 -1
  18. camel/loaders/unstructured_io.py +2 -1
  19. camel/memories/blocks/chat_history_block.py +1 -1
  20. camel/memories/context_creators/score_based.py +2 -2
  21. camel/models/__init__.py +2 -0
  22. camel/models/model_factory.py +119 -0
  23. camel/models/modelscope_model.py +208 -0
  24. camel/models/openai_audio_models.py +2 -2
  25. camel/models/openai_model.py +49 -2
  26. camel/models/togetherai_model.py +2 -2
  27. camel/models/vllm_model.py +1 -1
  28. camel/models/zhipuai_model.py +2 -2
  29. camel/retrievers/vector_retriever.py +1 -1
  30. camel/storages/graph_storages/neo4j_graph.py +1 -1
  31. camel/storages/vectordb_storages/base.py +2 -2
  32. camel/storages/vectordb_storages/milvus.py +2 -2
  33. camel/storages/vectordb_storages/qdrant.py +2 -2
  34. camel/tasks/task.py +2 -2
  35. camel/toolkits/__init__.py +4 -1
  36. camel/toolkits/arxiv_toolkit.py +2 -1
  37. camel/toolkits/ask_news_toolkit.py +11 -3
  38. camel/toolkits/audio_analysis_toolkit.py +2 -0
  39. camel/toolkits/base.py +3 -0
  40. camel/toolkits/code_execution.py +3 -1
  41. camel/toolkits/dappier_toolkit.py +2 -1
  42. camel/toolkits/data_commons_toolkit.py +2 -0
  43. camel/toolkits/excel_toolkit.py +2 -0
  44. camel/toolkits/file_write_toolkit.py +2 -0
  45. camel/toolkits/github_toolkit.py +6 -4
  46. camel/toolkits/google_scholar_toolkit.py +2 -0
  47. camel/toolkits/human_toolkit.py +17 -1
  48. camel/toolkits/image_analysis_toolkit.py +2 -0
  49. camel/toolkits/linkedin_toolkit.py +2 -1
  50. camel/toolkits/math_toolkit.py +2 -0
  51. camel/toolkits/mcp_toolkit.py +42 -52
  52. camel/toolkits/meshy_toolkit.py +20 -2
  53. camel/toolkits/networkx_toolkit.py +2 -0
  54. camel/toolkits/notion_toolkit.py +7 -0
  55. camel/toolkits/openbb_toolkit.py +2 -1
  56. camel/toolkits/pubmed_toolkit.py +2 -0
  57. camel/toolkits/reddit_toolkit.py +2 -1
  58. camel/toolkits/retrieval_toolkit.py +2 -1
  59. camel/toolkits/search_toolkit.py +2 -1
  60. camel/toolkits/semantic_scholar_toolkit.py +2 -0
  61. camel/toolkits/slack_toolkit.py +2 -0
  62. camel/toolkits/stripe_toolkit.py +2 -1
  63. camel/toolkits/sympy_toolkit.py +2 -0
  64. camel/toolkits/terminal_toolkit.py +2 -0
  65. camel/toolkits/twitter_toolkit.py +2 -1
  66. camel/toolkits/video_analysis_toolkit.py +2 -1
  67. camel/toolkits/video_download_toolkit.py +2 -1
  68. camel/toolkits/weather_toolkit.py +2 -0
  69. camel/toolkits/whatsapp_toolkit.py +2 -1
  70. camel/toolkits/zapier_toolkit.py +2 -1
  71. camel/types/enums.py +65 -0
  72. camel/types/unified_model_type.py +5 -0
  73. camel/utils/__init__.py +2 -0
  74. camel/utils/chunker/code_chunker.py +9 -9
  75. camel/utils/commons.py +50 -30
  76. camel/utils/constants.py +2 -2
  77. camel/utils/mcp.py +79 -0
  78. camel/verifiers/__init__.py +2 -0
  79. camel/verifiers/base.py +15 -15
  80. camel/verifiers/math_verifier.py +182 -0
  81. camel/verifiers/python_verifier.py +18 -26
  82. {camel_ai-0.2.38.dist-info → camel_ai-0.2.39.dist-info}/METADATA +3 -1
  83. {camel_ai-0.2.38.dist-info → camel_ai-0.2.39.dist-info}/RECORD +85 -80
  84. {camel_ai-0.2.38.dist-info → camel_ai-0.2.39.dist-info}/WHEEL +0 -0
  85. {camel_ai-0.2.38.dist-info → camel_ai-0.2.39.dist-info}/licenses/LICENSE +0 -0
@@ -18,11 +18,12 @@ from typing import Dict, List, Literal, Optional, Union
18
18
 
19
19
  from camel.toolkits import FunctionTool
20
20
  from camel.toolkits.base import BaseToolkit
21
- from camel.utils import dependencies_required
21
+ from camel.utils import MCPServer, dependencies_required
22
22
 
23
23
  logger = logging.getLogger(__name__)
24
24
 
25
25
 
26
+ @MCPServer()
26
27
  class GithubToolkit(BaseToolkit):
27
28
  r"""A class representing a toolkit for interacting with GitHub
28
29
  repositories.
@@ -53,12 +54,13 @@ class GithubToolkit(BaseToolkit):
53
54
  `get_github_access_token` method.
54
55
  """
55
56
  super().__init__(timeout=timeout)
56
- from github import Auth, Github
57
+ from github.Auth import Token
58
+ from github.MainClass import Github
57
59
 
58
60
  if access_token is None:
59
61
  access_token = self.get_github_access_token()
60
62
 
61
- self.github = Github(auth=Auth.Token(access_token))
63
+ self.github = Github(auth=Token(access_token))
62
64
  self.repo = self.github.get_repo(repo_name)
63
65
 
64
66
  def get_github_access_token(self) -> str:
@@ -110,7 +112,7 @@ class GithubToolkit(BaseToolkit):
110
112
  successfully or not.
111
113
  """
112
114
  sb = self.repo.get_branch(self.repo.default_branch)
113
- from github import GithubException
115
+ from github.GithubException import GithubException
114
116
 
115
117
  try:
116
118
  self.repo.create_git_ref(
@@ -16,8 +16,10 @@ from typing import Any, Dict, List, Optional
16
16
 
17
17
  from camel.toolkits import FunctionTool
18
18
  from camel.toolkits.base import BaseToolkit
19
+ from camel.utils import MCPServer
19
20
 
20
21
 
22
+ @MCPServer()
21
23
  class GoogleScholarToolkit(BaseToolkit):
22
24
  r"""A toolkit for retrieving information about authors and their
23
25
  publications from Google Scholar.
@@ -39,6 +39,19 @@ class HumanToolkit(BaseToolkit):
39
39
  logger.info(f"User reply: {reply}")
40
40
  return reply
41
41
 
42
+ def send_message_to_user(self, message: str) -> None:
43
+ r"""Send a message to the user, without waiting for
44
+ a response. This will send to stdout in a noticeable way.
45
+
46
+ This is guaranteed to reach the user regardless of
47
+ actual user interface.
48
+
49
+ Args:
50
+ message (str): The message to send to the user.
51
+ """
52
+ print(f"\nAgent Message:\n{message}")
53
+ logger.info(f"\nAgent Message:\n{message}")
54
+
42
55
  def get_tools(self) -> List[FunctionTool]:
43
56
  r"""Returns a list of FunctionTool objects representing the
44
57
  functions in the toolkit.
@@ -47,4 +60,7 @@ class HumanToolkit(BaseToolkit):
47
60
  List[FunctionTool]: A list of FunctionTool objects
48
61
  representing the functions in the toolkit.
49
62
  """
50
- return [FunctionTool(self.ask_human_via_console)]
63
+ return [
64
+ FunctionTool(self.ask_human_via_console),
65
+ FunctionTool(self.send_message_to_user),
66
+ ]
@@ -25,10 +25,12 @@ from camel.models import BaseModelBackend, ModelFactory
25
25
  from camel.toolkits import FunctionTool
26
26
  from camel.toolkits.base import BaseToolkit
27
27
  from camel.types import ModelPlatformType, ModelType
28
+ from camel.utils import MCPServer
28
29
 
29
30
  logger = get_logger(__name__)
30
31
 
31
32
 
33
+ @MCPServer()
32
34
  class ImageAnalysisToolkit(BaseToolkit):
33
35
  r"""A toolkit for comprehensive image analysis and understanding.
34
36
  The toolkit uses vision-capable language models to perform these tasks.
@@ -21,11 +21,12 @@ import requests
21
21
 
22
22
  from camel.toolkits import FunctionTool
23
23
  from camel.toolkits.base import BaseToolkit
24
- from camel.utils import handle_http_error
24
+ from camel.utils import MCPServer, handle_http_error
25
25
 
26
26
  LINKEDIN_POST_LIMIT = 1300
27
27
 
28
28
 
29
+ @MCPServer()
29
30
  class LinkedInToolkit(BaseToolkit):
30
31
  r"""A class representing a toolkit for LinkedIn operations.
31
32
 
@@ -16,8 +16,10 @@ from typing import List
16
16
 
17
17
  from camel.toolkits.base import BaseToolkit
18
18
  from camel.toolkits.function_tool import FunctionTool
19
+ from camel.utils import MCPServer
19
20
 
20
21
 
22
+ @MCPServer()
21
23
  class MathToolkit(BaseToolkit):
22
24
  r"""A class representing a toolkit for mathematical operations.
23
25
 
@@ -14,6 +14,7 @@
14
14
  import inspect
15
15
  import json
16
16
  import os
17
+ import shlex
17
18
  from contextlib import AsyncExitStack, asynccontextmanager
18
19
  from typing import (
19
20
  TYPE_CHECKING,
@@ -25,11 +26,12 @@ from typing import (
25
26
  Optional,
26
27
  Set,
27
28
  Union,
29
+ cast,
28
30
  )
29
31
  from urllib.parse import urlparse
30
32
 
31
33
  if TYPE_CHECKING:
32
- from mcp import ListToolsResult, Tool
34
+ from mcp import ClientSession, ListToolsResult, Tool
33
35
 
34
36
  from camel.logger import get_logger
35
37
  from camel.toolkits import BaseToolkit, FunctionTool
@@ -37,7 +39,7 @@ from camel.toolkits import BaseToolkit, FunctionTool
37
39
  logger = get_logger(__name__)
38
40
 
39
41
 
40
- class _MCPServer(BaseToolkit):
42
+ class MCPClient(BaseToolkit):
41
43
  r"""Internal class that provides an abstraction layer to interact with
42
44
  external tools using the Model Context Protocol (MCP). It supports two
43
45
  modes of connection:
@@ -69,7 +71,6 @@ class _MCPServer(BaseToolkit):
69
71
  headers: Optional[Dict[str, str]] = None,
70
72
  ):
71
73
  from mcp import Tool
72
- from mcp.client.session import ClientSession
73
74
 
74
75
  super().__init__(timeout=timeout)
75
76
 
@@ -87,7 +88,7 @@ class _MCPServer(BaseToolkit):
87
88
  r"""Explicitly connect to the MCP server.
88
89
 
89
90
  Returns:
90
- _MCPServer: The connected server instance
91
+ MCPClient: The client used to connect to the server.
91
92
  """
92
93
  from mcp.client.session import ClientSession
93
94
  from mcp.client.sse import sse_client
@@ -110,11 +111,20 @@ class _MCPServer(BaseToolkit):
110
111
  )
111
112
  else:
112
113
  command = self.command_or_url
114
+ arguments = self.args
115
+ if not self.args:
116
+ argv = shlex.split(command)
117
+ if not argv:
118
+ raise ValueError("Command is empty")
119
+
120
+ command = argv[0]
121
+ arguments = argv[1:]
122
+
113
123
  if os.name == "nt" and command.lower() == "npx":
114
124
  command = "npx.cmd"
115
125
 
116
126
  server_parameters = StdioServerParameters(
117
- command=command, args=self.args, env=self.env
127
+ command=command, args=arguments, env=self.env
118
128
  )
119
129
  (
120
130
  read_stream,
@@ -135,6 +145,7 @@ class _MCPServer(BaseToolkit):
135
145
  # Ensure resources are cleaned up on connection failure
136
146
  await self.disconnect()
137
147
  logger.error(f"Failed to connect to MCP server: {e}")
148
+ raise e
138
149
 
139
150
  async def disconnect(self):
140
151
  r"""Explicitly disconnect from the MCP server."""
@@ -149,7 +160,7 @@ class _MCPServer(BaseToolkit):
149
160
  on the provided `command_or_url`.
150
161
 
151
162
  Yields:
152
- _MCPServer: Instance with active connection ready for tool
163
+ MCPClient: Instance with active connection ready for tool
153
164
  interaction.
154
165
  """
155
166
  try:
@@ -170,7 +181,8 @@ class _MCPServer(BaseToolkit):
170
181
  try:
171
182
  return await self._session.list_tools()
172
183
  except Exception as e:
173
- return f"Failed to list MCP tools: {e!s}"
184
+ logger.exception("Failed to list MCP tools")
185
+ raise e
174
186
 
175
187
  def generate_function_from_mcp_tool(self, mcp_tool: "Tool") -> Callable:
176
188
  r"""Dynamically generates a Python callable function corresponding to
@@ -235,7 +247,7 @@ class _MCPServer(BaseToolkit):
235
247
  logger.error(
236
248
  "MCP Client is not connected. Call `connection()` first."
237
249
  )
238
- return (
250
+ raise RuntimeError(
239
251
  "MCP Client is not connected. Call `connection()` first."
240
252
  )
241
253
 
@@ -245,7 +257,7 @@ class _MCPServer(BaseToolkit):
245
257
  )
246
258
  except Exception as e:
247
259
  logger.error(f"Failed to call MCP tool '{func_name}': {e!s}")
248
- return f"Failed to call MCP tool '{func_name}': {e!s}"
260
+ raise e
249
261
 
250
262
  if not result.content or len(result.content) == 0:
251
263
  return "No data available for this request."
@@ -272,7 +284,7 @@ class _MCPServer(BaseToolkit):
272
284
  logger.error(
273
285
  f"Error processing content from MCP tool response: {e!s}"
274
286
  )
275
- return "Error processing content from MCP tool response"
287
+ raise e
276
288
 
277
289
  dynamic_function.__name__ = func_name
278
290
  dynamic_function.__doc__ = func_desc
@@ -331,6 +343,10 @@ class _MCPServer(BaseToolkit):
331
343
  for mcp_tool in self._mcp_tools
332
344
  ]
333
345
 
346
+ @property
347
+ def session(self) -> Optional["ClientSession"]:
348
+ return self._session
349
+
334
350
 
335
351
  class MCPToolkit(BaseToolkit):
336
352
  r"""MCPToolkit provides a unified interface for managing multiple
@@ -341,7 +357,7 @@ class MCPToolkit(BaseToolkit):
341
357
  MCP services.
342
358
 
343
359
  Args:
344
- servers (Optional[List[_MCPServer]]): List of _MCPServer
360
+ servers (Optional[List[MCPClient]]): List of MCPClient
345
361
  instances to manage.
346
362
  config_path (Optional[str]): Path to a JSON configuration file
347
363
  defining MCP servers.
@@ -359,7 +375,7 @@ class MCPToolkit(BaseToolkit):
359
375
  .. code-block:: json
360
376
 
361
377
  {
362
- "mcpWebServers": {
378
+ "mcpServers": {
363
379
  "protected-server": {
364
380
  "url": "https://example.com/mcp",
365
381
  "timeout": 30,
@@ -372,12 +388,12 @@ class MCPToolkit(BaseToolkit):
372
388
  }
373
389
 
374
390
  Attributes:
375
- servers (List[_MCPServer]): List of _MCPServer instances being managed.
391
+ servers (List[MCPClient]): List of MCPClient instances being managed.
376
392
  """
377
393
 
378
394
  def __init__(
379
395
  self,
380
- servers: Optional[List[_MCPServer]] = None,
396
+ servers: Optional[List[MCPClient]] = None,
381
397
  config_path: Optional[str] = None,
382
398
  ):
383
399
  super().__init__()
@@ -388,7 +404,7 @@ class MCPToolkit(BaseToolkit):
388
404
  "Servers from both sources will be combined."
389
405
  )
390
406
 
391
- self.servers = servers or []
407
+ self.servers: List[MCPClient] = servers or []
392
408
 
393
409
  if config_path:
394
410
  self.servers.extend(self._load_servers_from_config(config_path))
@@ -396,14 +412,14 @@ class MCPToolkit(BaseToolkit):
396
412
  self._exit_stack = AsyncExitStack()
397
413
  self._connected = False
398
414
 
399
- def _load_servers_from_config(self, config_path: str) -> List[_MCPServer]:
415
+ def _load_servers_from_config(self, config_path: str) -> List[MCPClient]:
400
416
  r"""Loads MCP server configurations from a JSON file.
401
417
 
402
418
  Args:
403
419
  config_path (str): Path to the JSON configuration file.
404
420
 
405
421
  Returns:
406
- List[_MCPServer]: List of configured _MCPServer instances.
422
+ List[MCPClient]: List of configured MCPClient instances.
407
423
  """
408
424
  try:
409
425
  with open(config_path, "r", encoding="utf-8") as f:
@@ -413,14 +429,13 @@ class MCPToolkit(BaseToolkit):
413
429
  logger.warning(
414
430
  f"Invalid JSON in config file '{config_path}': {e!s}"
415
431
  )
416
- return []
417
- except FileNotFoundError:
432
+ raise e
433
+ except FileNotFoundError as e:
418
434
  logger.warning(f"Config file not found: '{config_path}'")
419
- return []
435
+ raise e
420
436
 
421
437
  all_servers = []
422
438
 
423
- # Process local MCP servers
424
439
  mcp_servers = data.get("mcpServers", {})
425
440
  if not isinstance(mcp_servers, dict):
426
441
  logger.warning("'mcpServers' is not a dictionary, skipping...")
@@ -433,47 +448,21 @@ class MCPToolkit(BaseToolkit):
433
448
  )
434
449
  continue
435
450
 
436
- if "command" not in cfg:
451
+ if "command" not in cfg and "url" not in cfg:
437
452
  logger.warning(
438
- f"Missing required 'command' field for server '{name}'"
453
+ f"Missing required 'command' or 'url' field for server "
454
+ f"'{name}'"
439
455
  )
440
456
  continue
441
457
 
442
- server = _MCPServer(
443
- command_or_url=cfg["command"],
458
+ server = MCPClient(
459
+ command_or_url=cast(str, cfg.get("command") or cfg.get("url")),
444
460
  args=cfg.get("args", []),
445
461
  env={**os.environ, **cfg.get("env", {})},
446
462
  timeout=cfg.get("timeout", None),
447
463
  )
448
464
  all_servers.append(server)
449
465
 
450
- # Process remote MCP web servers
451
- mcp_web_servers = data.get("mcpWebServers", {})
452
- if not isinstance(mcp_web_servers, dict):
453
- logger.warning("'mcpWebServers' is not a dictionary, skipping...")
454
- mcp_web_servers = {}
455
-
456
- for name, cfg in mcp_web_servers.items():
457
- if not isinstance(cfg, dict):
458
- logger.warning(
459
- f"Configuration for web server '{name}' must"
460
- "be a dictionary"
461
- )
462
- continue
463
-
464
- if "url" not in cfg:
465
- logger.warning(
466
- f"Missing required 'url' field for web server '{name}'"
467
- )
468
- continue
469
-
470
- server = _MCPServer(
471
- command_or_url=cfg["url"],
472
- timeout=cfg.get("timeout", None),
473
- headers=cfg.get("headers", {}),
474
- )
475
- all_servers.append(server)
476
-
477
466
  return all_servers
478
467
 
479
468
  async def connect(self):
@@ -497,6 +486,7 @@ class MCPToolkit(BaseToolkit):
497
486
  # Ensure resources are cleaned up on connection failure
498
487
  await self.disconnect()
499
488
  logger.error(f"Failed to connect to one or more MCP servers: {e}")
489
+ raise e
500
490
 
501
491
  async def disconnect(self):
502
492
  r"""Explicitly disconnect from all MCP servers."""
@@ -13,14 +13,16 @@
13
13
  # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
14
14
 
15
15
  import os
16
- from typing import Any, Dict, Optional
16
+ from typing import Any, Dict, List, Optional
17
17
 
18
18
  import requests
19
19
 
20
+ from camel.toolkits import FunctionTool
20
21
  from camel.toolkits.base import BaseToolkit
21
- from camel.utils import api_keys_required
22
+ from camel.utils import MCPServer, api_keys_required
22
23
 
23
24
 
25
+ @MCPServer()
24
26
  class MeshyToolkit(BaseToolkit):
25
27
  r"""A class representing a toolkit for 3D model generation using Meshy.
26
28
 
@@ -188,3 +190,19 @@ class MeshyToolkit(BaseToolkit):
188
190
 
189
191
  # Wait for refinement completion and return final result
190
192
  return self.wait_for_task_completion(refine_task_id)
193
+
194
+ def get_tools(self) -> List[FunctionTool]:
195
+ r"""Returns a list of FunctionTool objects representing the
196
+ functions in the toolkit.
197
+
198
+ Returns:
199
+ List[FunctionTool]: A list of FunctionTool objects
200
+ representing the functions in the toolkit.
201
+ """
202
+ return [
203
+ FunctionTool(self.generate_3d_preview),
204
+ FunctionTool(self.refine_3d_model),
205
+ FunctionTool(self.get_task_status),
206
+ FunctionTool(self.wait_for_task_completion),
207
+ FunctionTool(self.generate_3d_model_complete),
208
+ ]
@@ -18,10 +18,12 @@ from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union
18
18
  from camel.logger import get_logger
19
19
  from camel.toolkits import FunctionTool
20
20
  from camel.toolkits.base import BaseToolkit
21
+ from camel.utils import MCPServer
21
22
 
22
23
  logger = get_logger(__name__)
23
24
 
24
25
 
26
+ @MCPServer()
25
27
  class NetworkXToolkit(BaseToolkit):
26
28
  _nx = None # Class variable to store the networkx module
27
29
 
@@ -16,6 +16,7 @@ from typing import List, Optional, cast
16
16
 
17
17
  from camel.toolkits import FunctionTool
18
18
  from camel.toolkits.base import BaseToolkit
19
+ from camel.utils import MCPServer, api_keys_required
19
20
 
20
21
 
21
22
  def get_plain_text_from_rich_text(rich_text: List[dict]) -> str:
@@ -66,6 +67,7 @@ def get_media_source_text(block: dict) -> str:
66
67
  return source
67
68
 
68
69
 
70
+ @MCPServer()
69
71
  class NotionToolkit(BaseToolkit):
70
72
  r"""A toolkit for retrieving information from the user's notion pages.
71
73
 
@@ -76,6 +78,11 @@ class NotionToolkit(BaseToolkit):
76
78
  the notion APIs.
77
79
  """
78
80
 
81
+ @api_keys_required(
82
+ [
83
+ ("notion_token", 'NOTION_TOKEN'),
84
+ ]
85
+ )
79
86
  def __init__(
80
87
  self,
81
88
  notion_token: Optional[str] = None,
@@ -17,9 +17,10 @@ from typing import List, Literal, Optional
17
17
 
18
18
  from camel.toolkits.base import BaseToolkit
19
19
  from camel.toolkits.function_tool import FunctionTool
20
- from camel.utils import api_keys_required, dependencies_required
20
+ from camel.utils import MCPServer, api_keys_required, dependencies_required
21
21
 
22
22
 
23
+ @MCPServer()
23
24
  class OpenBBToolkit(BaseToolkit):
24
25
  r"""A toolkit for accessing financial data and analysis through OpenBB
25
26
  Platform.
@@ -18,10 +18,12 @@ import requests
18
18
 
19
19
  from camel.logger import get_logger
20
20
  from camel.toolkits import BaseToolkit, FunctionTool
21
+ from camel.utils import MCPServer
21
22
 
22
23
  logger = get_logger(__name__)
23
24
 
24
25
 
26
+ @MCPServer()
25
27
  class PubMedToolkit(BaseToolkit):
26
28
  r"""A toolkit for interacting with PubMed's E-utilities API to access
27
29
  MEDLINE data.
@@ -18,9 +18,10 @@ from typing import Any, Dict, List, Optional, Union
18
18
 
19
19
  from camel.toolkits import FunctionTool
20
20
  from camel.toolkits.base import BaseToolkit
21
- from camel.utils import retry_on_error
21
+ from camel.utils import MCPServer, retry_on_error
22
22
 
23
23
 
24
+ @MCPServer()
24
25
  class RedditToolkit(BaseToolkit):
25
26
  r"""A class representing a toolkit for Reddit operations.
26
27
 
@@ -17,9 +17,10 @@ from camel.retrievers import AutoRetriever
17
17
  from camel.toolkits import FunctionTool
18
18
  from camel.toolkits.base import BaseToolkit
19
19
  from camel.types import StorageType
20
- from camel.utils import Constants
20
+ from camel.utils import Constants, MCPServer
21
21
 
22
22
 
23
+ @MCPServer()
23
24
  class RetrievalToolkit(BaseToolkit):
24
25
  r"""A class representing a toolkit for information retrieval.
25
26
 
@@ -19,9 +19,10 @@ import requests
19
19
 
20
20
  from camel.toolkits.base import BaseToolkit
21
21
  from camel.toolkits.function_tool import FunctionTool
22
- from camel.utils import api_keys_required, dependencies_required
22
+ from camel.utils import MCPServer, api_keys_required, dependencies_required
23
23
 
24
24
 
25
+ @MCPServer()
25
26
  class SearchToolkit(BaseToolkit):
26
27
  r"""A class representing a toolkit for web search.
27
28
 
@@ -19,8 +19,10 @@ import requests
19
19
 
20
20
  from camel.toolkits import FunctionTool
21
21
  from camel.toolkits.base import BaseToolkit
22
+ from camel.utils import MCPServer
22
23
 
23
24
 
25
+ @MCPServer()
24
26
  class SemanticScholarToolkit(BaseToolkit):
25
27
  r"""A toolkit for interacting with the Semantic Scholar
26
28
  API to fetch paper and author data.
@@ -20,6 +20,7 @@ import os
20
20
  from typing import TYPE_CHECKING, List, Optional
21
21
 
22
22
  from camel.toolkits.base import BaseToolkit
23
+ from camel.utils import MCPServer
23
24
 
24
25
  if TYPE_CHECKING:
25
26
  from ssl import SSLContext
@@ -31,6 +32,7 @@ from camel.toolkits import FunctionTool
31
32
  logger = logging.getLogger(__name__)
32
33
 
33
34
 
35
+ @MCPServer()
34
36
  class SlackToolkit(BaseToolkit):
35
37
  r"""A class representing a toolkit for Slack operations.
36
38
 
@@ -19,9 +19,10 @@ from typing import List, Optional
19
19
 
20
20
  from camel.toolkits import FunctionTool
21
21
  from camel.toolkits.base import BaseToolkit
22
- from camel.utils import api_keys_required
22
+ from camel.utils import MCPServer, api_keys_required
23
23
 
24
24
 
25
+ @MCPServer()
25
26
  class StripeToolkit(BaseToolkit):
26
27
  r"""A class representing a toolkit for Stripe operations.
27
28
 
@@ -18,10 +18,12 @@ from typing import List, Optional
18
18
  from camel.logger import get_logger
19
19
  from camel.toolkits import FunctionTool
20
20
  from camel.toolkits.base import BaseToolkit
21
+ from camel.utils import MCPServer
21
22
 
22
23
  logger = get_logger(__name__)
23
24
 
24
25
 
26
+ @MCPServer()
25
27
  class SymPyToolkit(BaseToolkit):
26
28
  r"""A toolkit for performing symbolic computations using SymPy.
27
29
  This includes methods for Algebraic manipulation calculus
@@ -19,10 +19,12 @@ from typing import Any, Dict, List, Optional
19
19
  from camel.logger import get_logger
20
20
  from camel.toolkits.base import BaseToolkit
21
21
  from camel.toolkits.function_tool import FunctionTool
22
+ from camel.utils import MCPServer
22
23
 
23
24
  logger = get_logger(__name__)
24
25
 
25
26
 
27
+ @MCPServer()
26
28
  class TerminalToolkit(BaseToolkit):
27
29
  r"""A toolkit for terminal operations across multiple operating systems.
28
30
 
@@ -23,7 +23,7 @@ from requests_oauthlib import OAuth1
23
23
  from camel.logger import get_logger
24
24
  from camel.toolkits import FunctionTool
25
25
  from camel.toolkits.base import BaseToolkit
26
- from camel.utils import api_keys_required
26
+ from camel.utils import MCPServer, api_keys_required
27
27
 
28
28
  TWEET_TEXT_LIMIT = 280
29
29
 
@@ -418,6 +418,7 @@ def _handle_http_error(response: requests.Response) -> str:
418
418
  return "Unexpected Exception"
419
419
 
420
420
 
421
+ @MCPServer()
421
422
  class TwitterToolkit(BaseToolkit):
422
423
  r"""A class representing a toolkit for Twitter operations.
423
424
 
@@ -24,7 +24,7 @@ from camel.messages import BaseMessage
24
24
  from camel.models import BaseModelBackend, OpenAIAudioModels
25
25
  from camel.toolkits.base import BaseToolkit
26
26
  from camel.toolkits.function_tool import FunctionTool
27
- from camel.utils import dependencies_required
27
+ from camel.utils import MCPServer, dependencies_required
28
28
 
29
29
  from .video_download_toolkit import (
30
30
  VideoDownloaderToolkit,
@@ -77,6 +77,7 @@ similar-looking species or objects
77
77
  """
78
78
 
79
79
 
80
+ @MCPServer()
80
81
  class VideoAnalysisToolkit(BaseToolkit):
81
82
  r"""A class for analysing videos with vision-language model.
82
83
 
@@ -23,7 +23,7 @@ from PIL import Image
23
23
  from camel.logger import get_logger
24
24
  from camel.toolkits.base import BaseToolkit
25
25
  from camel.toolkits.function_tool import FunctionTool
26
- from camel.utils import dependencies_required
26
+ from camel.utils import MCPServer, dependencies_required
27
27
 
28
28
  logger = get_logger(__name__)
29
29
 
@@ -54,6 +54,7 @@ def _capture_screenshot(video_file: str, timestamp: float) -> Image.Image:
54
54
  return Image.open(io.BytesIO(out))
55
55
 
56
56
 
57
+ @MCPServer()
57
58
  class VideoDownloaderToolkit(BaseToolkit):
58
59
  r"""A class for downloading videos and optionally splitting them into
59
60
  chunks.
@@ -16,8 +16,10 @@ from typing import List, Literal
16
16
 
17
17
  from camel.toolkits.base import BaseToolkit
18
18
  from camel.toolkits.function_tool import FunctionTool
19
+ from camel.utils import MCPServer
19
20
 
20
21
 
22
+ @MCPServer()
21
23
  class WeatherToolkit(BaseToolkit):
22
24
  r"""A class representing a toolkit for interacting with weather data.
23
25