maton-agent-toolkit 0.1.0__tar.gz
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.
- maton_agent_toolkit-0.1.0/LICENSE +23 -0
- maton_agent_toolkit-0.1.0/PKG-INFO +135 -0
- maton_agent_toolkit-0.1.0/README.md +76 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/__init__.py +7 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/configuration.py +14 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/crewai/__init__.py +5 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/crewai/toolkit.py +134 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/langchain/__init__.py +5 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/langchain/toolkit.py +134 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/openai/__init__.py +5 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/openai/toolkit.py +125 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/shared/__init__.py +21 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/shared/async_initializer.py +71 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/shared/constants.py +6 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/shared/mcp_client.py +231 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/shared/schema_utils.py +127 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/shared/toolkit_core.py +163 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/strands/__init__.py +5 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit/strands/toolkit.py +173 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit.egg-info/PKG-INFO +135 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit.egg-info/SOURCES.txt +28 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit.egg-info/dependency_links.txt +1 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit.egg-info/requires.txt +27 -0
- maton_agent_toolkit-0.1.0/maton_agent_toolkit.egg-info/top_level.txt +1 -0
- maton_agent_toolkit-0.1.0/pyproject.toml +68 -0
- maton_agent_toolkit-0.1.0/setup.cfg +4 -0
- maton_agent_toolkit-0.1.0/tests/test_async_initializer.py +121 -0
- maton_agent_toolkit-0.1.0/tests/test_configuration.py +34 -0
- maton_agent_toolkit-0.1.0/tests/test_mcp_client.py +107 -0
- maton_agent_toolkit-0.1.0/tests/test_schema_utils.py +482 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Maton
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2025 Stripe
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: maton-agent-toolkit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Maton Agent Toolkit
|
|
5
|
+
Author-email: Maton <support@maton.ai>
|
|
6
|
+
License: The MIT License (MIT)
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Maton
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2025 Stripe
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
|
|
30
|
+
Project-URL: Bug Tracker, https://github.com/maton-ai/maton-agent-toolkit/issues
|
|
31
|
+
Project-URL: Source Code, https://github.com/maton-ai/maton-agent-toolkit
|
|
32
|
+
Project-URL: Documentation, https://maton.ai
|
|
33
|
+
Keywords: maton,api,automation,mcp,agents
|
|
34
|
+
Requires-Python: >=3.11
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
License-File: LICENSE
|
|
37
|
+
Requires-Dist: pydantic>=2.0.0
|
|
38
|
+
Requires-Dist: mcp>=1.0.0
|
|
39
|
+
Provides-Extra: openai
|
|
40
|
+
Requires-Dist: openai>=1.0.0; extra == "openai"
|
|
41
|
+
Requires-Dist: agents>=0.0.84; extra == "openai"
|
|
42
|
+
Provides-Extra: langchain
|
|
43
|
+
Requires-Dist: langchain>=0.1.0; extra == "langchain"
|
|
44
|
+
Provides-Extra: crewai
|
|
45
|
+
Requires-Dist: crewai>=0.1.0; extra == "crewai"
|
|
46
|
+
Provides-Extra: strands
|
|
47
|
+
Requires-Dist: strands-agents>=1.0.0; extra == "strands"
|
|
48
|
+
Provides-Extra: all
|
|
49
|
+
Requires-Dist: maton-agent-toolkit[openai]; extra == "all"
|
|
50
|
+
Requires-Dist: maton-agent-toolkit[langchain]; extra == "all"
|
|
51
|
+
Requires-Dist: maton-agent-toolkit[crewai]; extra == "all"
|
|
52
|
+
Requires-Dist: maton-agent-toolkit[strands]; extra == "all"
|
|
53
|
+
Provides-Extra: dev
|
|
54
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
55
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
56
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
57
|
+
Requires-Dist: pyright>=1.1.0; extra == "dev"
|
|
58
|
+
Dynamic: license-file
|
|
59
|
+
|
|
60
|
+
# Maton Agent Toolkit - Python
|
|
61
|
+
|
|
62
|
+
The Maton Agent Toolkit connects popular agent frameworks — OpenAI's Agents SDK, LangChain, CrewAI, and Strands — to the [Maton MCP server](https://mcp.maton.ai) through function calling. Instead of bundling a fixed set of actions, the toolkit connects to the remote Maton MCP server, discovers the available tools, and exposes them in each framework's native tool format. This lets your agent connect and automate 150+ apps (Google Workspace, Microsoft 365, GitHub, Notion, Slack, HubSpot, and more).
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
You don't need this source code unless you want to modify the package. If you just want to use the package, just run:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
uv pip install maton-agent-toolkit
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Requirements
|
|
73
|
+
|
|
74
|
+
- Python 3.11+
|
|
75
|
+
|
|
76
|
+
## Usage
|
|
77
|
+
|
|
78
|
+
The library needs to be configured with your Maton API key. You can create one at [maton.ai](https://maton.ai), or set the `MATON_API_KEY` environment variable. The toolkit connects to `https://mcp.maton.ai` with your key in the `Authorization: Bearer` header.
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from maton_agent_toolkit.openai.toolkit import create_maton_agent_toolkit
|
|
82
|
+
|
|
83
|
+
async def main():
|
|
84
|
+
toolkit = await create_maton_agent_toolkit(api_key="YOUR_MATON_API_KEY")
|
|
85
|
+
tools = toolkit.get_tools()
|
|
86
|
+
# ... use tools ...
|
|
87
|
+
await toolkit.close() # Clean up when done
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The toolkit works with OpenAI's Agents SDK, LangChain, CrewAI, and Strands and can be passed as a list of tools. For example:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from agents import Agent
|
|
94
|
+
|
|
95
|
+
async def main():
|
|
96
|
+
toolkit = await create_maton_agent_toolkit(api_key="YOUR_MATON_API_KEY")
|
|
97
|
+
|
|
98
|
+
maton_agent = Agent(
|
|
99
|
+
name="Maton Agent",
|
|
100
|
+
instructions="You are an expert at automating apps with Maton",
|
|
101
|
+
tools=toolkit.get_tools()
|
|
102
|
+
)
|
|
103
|
+
# ... use agent ...
|
|
104
|
+
await toolkit.close()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Import from the framework-specific module you need:
|
|
108
|
+
|
|
109
|
+
- `maton_agent_toolkit.openai.toolkit`
|
|
110
|
+
- `maton_agent_toolkit.langchain.toolkit`
|
|
111
|
+
- `maton_agent_toolkit.crewai.toolkit`
|
|
112
|
+
- `maton_agent_toolkit.strands.toolkit`
|
|
113
|
+
|
|
114
|
+
### Context
|
|
115
|
+
|
|
116
|
+
You can provide a default `connection` that all requests route through (sent as the `Maton-Connection` header). If omitted, Maton uses the newest active connection for the target app.
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
toolkit = await create_maton_agent_toolkit(
|
|
120
|
+
api_key="YOUR_MATON_API_KEY",
|
|
121
|
+
configuration={
|
|
122
|
+
"context": {
|
|
123
|
+
"connection": "conn_123"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Development
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
uv venv --python 3.11
|
|
133
|
+
source .venv/bin/activate
|
|
134
|
+
uv pip install -r requirements.txt
|
|
135
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Maton Agent Toolkit - Python
|
|
2
|
+
|
|
3
|
+
The Maton Agent Toolkit connects popular agent frameworks — OpenAI's Agents SDK, LangChain, CrewAI, and Strands — to the [Maton MCP server](https://mcp.maton.ai) through function calling. Instead of bundling a fixed set of actions, the toolkit connects to the remote Maton MCP server, discovers the available tools, and exposes them in each framework's native tool format. This lets your agent connect and automate 150+ apps (Google Workspace, Microsoft 365, GitHub, Notion, Slack, HubSpot, and more).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
You don't need this source code unless you want to modify the package. If you just want to use the package, just run:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
uv pip install maton-agent-toolkit
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Requirements
|
|
14
|
+
|
|
15
|
+
- Python 3.11+
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
The library needs to be configured with your Maton API key. You can create one at [maton.ai](https://maton.ai), or set the `MATON_API_KEY` environment variable. The toolkit connects to `https://mcp.maton.ai` with your key in the `Authorization: Bearer` header.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from maton_agent_toolkit.openai.toolkit import create_maton_agent_toolkit
|
|
23
|
+
|
|
24
|
+
async def main():
|
|
25
|
+
toolkit = await create_maton_agent_toolkit(api_key="YOUR_MATON_API_KEY")
|
|
26
|
+
tools = toolkit.get_tools()
|
|
27
|
+
# ... use tools ...
|
|
28
|
+
await toolkit.close() # Clean up when done
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The toolkit works with OpenAI's Agents SDK, LangChain, CrewAI, and Strands and can be passed as a list of tools. For example:
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from agents import Agent
|
|
35
|
+
|
|
36
|
+
async def main():
|
|
37
|
+
toolkit = await create_maton_agent_toolkit(api_key="YOUR_MATON_API_KEY")
|
|
38
|
+
|
|
39
|
+
maton_agent = Agent(
|
|
40
|
+
name="Maton Agent",
|
|
41
|
+
instructions="You are an expert at automating apps with Maton",
|
|
42
|
+
tools=toolkit.get_tools()
|
|
43
|
+
)
|
|
44
|
+
# ... use agent ...
|
|
45
|
+
await toolkit.close()
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Import from the framework-specific module you need:
|
|
49
|
+
|
|
50
|
+
- `maton_agent_toolkit.openai.toolkit`
|
|
51
|
+
- `maton_agent_toolkit.langchain.toolkit`
|
|
52
|
+
- `maton_agent_toolkit.crewai.toolkit`
|
|
53
|
+
- `maton_agent_toolkit.strands.toolkit`
|
|
54
|
+
|
|
55
|
+
### Context
|
|
56
|
+
|
|
57
|
+
You can provide a default `connection` that all requests route through (sent as the `Maton-Connection` header). If omitted, Maton uses the newest active connection for the target app.
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
toolkit = await create_maton_agent_toolkit(
|
|
61
|
+
api_key="YOUR_MATON_API_KEY",
|
|
62
|
+
configuration={
|
|
63
|
+
"context": {
|
|
64
|
+
"connection": "conn_123"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Development
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
uv venv --python 3.11
|
|
74
|
+
source .venv/bin/activate
|
|
75
|
+
uv pip install -r requirements.txt
|
|
76
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Configuration types for Maton Agent Toolkit."""
|
|
2
|
+
|
|
3
|
+
from typing_extensions import TypedDict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Context(TypedDict, total=False):
|
|
7
|
+
"""Context for MCP connection."""
|
|
8
|
+
connection: str | None
|
|
9
|
+
mode: str | None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Configuration(TypedDict, total=False):
|
|
13
|
+
"""Configuration for Maton Agent Toolkit."""
|
|
14
|
+
context: Context | None
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""Maton Agent Toolkit for CrewAI."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from typing import List, Any, Type, Callable, Awaitable
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
from crewai.tools import BaseTool
|
|
8
|
+
|
|
9
|
+
from ..shared.toolkit_core import ToolkitCore
|
|
10
|
+
from ..shared.mcp_client import McpTool
|
|
11
|
+
from ..shared.schema_utils import json_schema_to_pydantic_model
|
|
12
|
+
from ..configuration import Configuration
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MatonTool(BaseTool):
|
|
16
|
+
"""Tool for interacting with Maton via MCP."""
|
|
17
|
+
|
|
18
|
+
run_tool: Callable[..., Awaitable[str]]
|
|
19
|
+
method: str
|
|
20
|
+
name: str = ""
|
|
21
|
+
description: str = ""
|
|
22
|
+
args_schema: Type[BaseModel] | None = None
|
|
23
|
+
|
|
24
|
+
def _run(self, **kwargs: Any) -> str:
|
|
25
|
+
"""Synchronous execution - wraps async call."""
|
|
26
|
+
loop = asyncio.get_event_loop()
|
|
27
|
+
if loop.is_running():
|
|
28
|
+
# If we're already in an async context, create a new loop
|
|
29
|
+
import concurrent.futures
|
|
30
|
+
with concurrent.futures.ThreadPoolExecutor() as pool:
|
|
31
|
+
future = pool.submit(
|
|
32
|
+
asyncio.run,
|
|
33
|
+
self.run_tool(self.method, kwargs)
|
|
34
|
+
)
|
|
35
|
+
return future.result()
|
|
36
|
+
else:
|
|
37
|
+
return loop.run_until_complete(
|
|
38
|
+
self.run_tool(self.method, kwargs)
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
async def _arun(self, **kwargs: Any) -> str:
|
|
42
|
+
"""Async execution via MCP."""
|
|
43
|
+
return await self.run_tool(self.method, kwargs)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class MatonAgentToolkit(ToolkitCore[List[MatonTool]]):
|
|
47
|
+
"""
|
|
48
|
+
Maton Agent Toolkit for CrewAI.
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
toolkit = await create_maton_agent_toolkit(
|
|
52
|
+
api_key='YOUR_MATON_API_KEY',
|
|
53
|
+
)
|
|
54
|
+
tools = toolkit.get_tools()
|
|
55
|
+
agent = Agent(role="...", tools=tools)
|
|
56
|
+
await toolkit.close()
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
def __init__(
|
|
60
|
+
self,
|
|
61
|
+
api_key: str | None = None,
|
|
62
|
+
configuration: Configuration | None = None
|
|
63
|
+
):
|
|
64
|
+
super().__init__(api_key, configuration)
|
|
65
|
+
|
|
66
|
+
def _empty_tools(self) -> List[MatonTool]:
|
|
67
|
+
"""Return empty list of tools."""
|
|
68
|
+
return []
|
|
69
|
+
|
|
70
|
+
def _convert_tools(
|
|
71
|
+
self,
|
|
72
|
+
mcp_tools: List[McpTool]
|
|
73
|
+
) -> List[MatonTool]:
|
|
74
|
+
"""Convert MCP tools to CrewAI MatonTool instances."""
|
|
75
|
+
tools = []
|
|
76
|
+
for mcp_tool in mcp_tools:
|
|
77
|
+
# Convert JSON Schema to Pydantic model
|
|
78
|
+
args_schema = json_schema_to_pydantic_model(
|
|
79
|
+
mcp_tool.get("inputSchema"),
|
|
80
|
+
model_name=f"{mcp_tool['name']}_args"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
tools.append(MatonTool(
|
|
84
|
+
run_tool=self.run_tool,
|
|
85
|
+
method=mcp_tool["name"],
|
|
86
|
+
name=mcp_tool["name"],
|
|
87
|
+
description=mcp_tool.get("description", mcp_tool["name"]),
|
|
88
|
+
args_schema=args_schema,
|
|
89
|
+
))
|
|
90
|
+
return tools
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def tools(self) -> List[MatonTool]:
|
|
94
|
+
"""
|
|
95
|
+
The tools available in the toolkit.
|
|
96
|
+
|
|
97
|
+
.. deprecated::
|
|
98
|
+
Access tools via get_tools() after calling initialize().
|
|
99
|
+
"""
|
|
100
|
+
return self._get_tools_with_warning()
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
async def create_maton_agent_toolkit(
|
|
104
|
+
api_key: str | None = None,
|
|
105
|
+
configuration: Configuration | None = None
|
|
106
|
+
) -> MatonAgentToolkit:
|
|
107
|
+
"""
|
|
108
|
+
Factory function to create and initialize a MatonAgentToolkit.
|
|
109
|
+
|
|
110
|
+
This is the recommended way to create a toolkit as it handles
|
|
111
|
+
async initialization automatically.
|
|
112
|
+
|
|
113
|
+
Example:
|
|
114
|
+
toolkit = await create_maton_agent_toolkit(
|
|
115
|
+
api_key='YOUR_MATON_API_KEY',
|
|
116
|
+
)
|
|
117
|
+
tools = toolkit.get_tools()
|
|
118
|
+
|
|
119
|
+
# Use with CrewAI agent
|
|
120
|
+
agent = Agent(role="Maton Agent", tools=tools)
|
|
121
|
+
|
|
122
|
+
# Clean up when done
|
|
123
|
+
await toolkit.close()
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
api_key: Maton API key. Create one at https://maton.ai
|
|
127
|
+
configuration: Optional configuration for context
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Initialized MatonAgentToolkit ready to use
|
|
131
|
+
"""
|
|
132
|
+
toolkit = MatonAgentToolkit(api_key, configuration)
|
|
133
|
+
await toolkit.initialize()
|
|
134
|
+
return toolkit
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""Maton Agent Toolkit for LangChain."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from typing import List, Any, Type, Callable, Awaitable
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
from langchain_core.tools import BaseTool
|
|
8
|
+
|
|
9
|
+
from ..shared.toolkit_core import ToolkitCore
|
|
10
|
+
from ..shared.mcp_client import McpTool
|
|
11
|
+
from ..shared.schema_utils import json_schema_to_pydantic_model
|
|
12
|
+
from ..configuration import Configuration
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MatonTool(BaseTool):
|
|
16
|
+
"""Tool for interacting with Maton via MCP."""
|
|
17
|
+
|
|
18
|
+
run_tool: Callable[..., Awaitable[str]]
|
|
19
|
+
method: str
|
|
20
|
+
name: str = ""
|
|
21
|
+
description: str = ""
|
|
22
|
+
args_schema: Type[BaseModel] | None = None
|
|
23
|
+
|
|
24
|
+
def _run(self, **kwargs: Any) -> str:
|
|
25
|
+
"""Synchronous execution - wraps async call."""
|
|
26
|
+
loop = asyncio.get_event_loop()
|
|
27
|
+
if loop.is_running():
|
|
28
|
+
# If we're already in an async context, create a new loop
|
|
29
|
+
import concurrent.futures
|
|
30
|
+
with concurrent.futures.ThreadPoolExecutor() as pool:
|
|
31
|
+
future = pool.submit(
|
|
32
|
+
asyncio.run,
|
|
33
|
+
self.run_tool(self.method, kwargs)
|
|
34
|
+
)
|
|
35
|
+
return future.result()
|
|
36
|
+
else:
|
|
37
|
+
return loop.run_until_complete(
|
|
38
|
+
self.run_tool(self.method, kwargs)
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
async def _arun(self, **kwargs: Any) -> str:
|
|
42
|
+
"""Async execution via MCP."""
|
|
43
|
+
return await self.run_tool(self.method, kwargs)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class MatonAgentToolkit(ToolkitCore[List[MatonTool]]):
|
|
47
|
+
"""
|
|
48
|
+
Maton Agent Toolkit for LangChain.
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
toolkit = await create_maton_agent_toolkit(
|
|
52
|
+
api_key='YOUR_MATON_API_KEY',
|
|
53
|
+
)
|
|
54
|
+
tools = toolkit.get_tools()
|
|
55
|
+
agent = create_react_agent(llm, tools, prompt)
|
|
56
|
+
await toolkit.close()
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
def __init__(
|
|
60
|
+
self,
|
|
61
|
+
api_key: str | None = None,
|
|
62
|
+
configuration: Configuration | None = None
|
|
63
|
+
):
|
|
64
|
+
super().__init__(api_key, configuration)
|
|
65
|
+
|
|
66
|
+
def _empty_tools(self) -> List[MatonTool]:
|
|
67
|
+
"""Return empty list of tools."""
|
|
68
|
+
return []
|
|
69
|
+
|
|
70
|
+
def _convert_tools(
|
|
71
|
+
self,
|
|
72
|
+
mcp_tools: List[McpTool]
|
|
73
|
+
) -> List[MatonTool]:
|
|
74
|
+
"""Convert MCP tools to LangChain MatonTool instances."""
|
|
75
|
+
tools = []
|
|
76
|
+
for mcp_tool in mcp_tools:
|
|
77
|
+
# Convert JSON Schema to Pydantic model
|
|
78
|
+
args_schema = json_schema_to_pydantic_model(
|
|
79
|
+
mcp_tool.get("inputSchema"),
|
|
80
|
+
model_name=f"{mcp_tool['name']}_args"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
tools.append(MatonTool(
|
|
84
|
+
run_tool=self.run_tool,
|
|
85
|
+
method=mcp_tool["name"],
|
|
86
|
+
name=mcp_tool["name"],
|
|
87
|
+
description=mcp_tool.get("description", mcp_tool["name"]),
|
|
88
|
+
args_schema=args_schema,
|
|
89
|
+
))
|
|
90
|
+
return tools
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def tools(self) -> List[MatonTool]:
|
|
94
|
+
"""
|
|
95
|
+
The tools available in the toolkit.
|
|
96
|
+
|
|
97
|
+
.. deprecated::
|
|
98
|
+
Access tools via get_tools() after calling initialize().
|
|
99
|
+
"""
|
|
100
|
+
return self._get_tools_with_warning()
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
async def create_maton_agent_toolkit(
|
|
104
|
+
api_key: str | None = None,
|
|
105
|
+
configuration: Configuration | None = None
|
|
106
|
+
) -> MatonAgentToolkit:
|
|
107
|
+
"""
|
|
108
|
+
Factory function to create and initialize a MatonAgentToolkit.
|
|
109
|
+
|
|
110
|
+
This is the recommended way to create a toolkit as it handles
|
|
111
|
+
async initialization automatically.
|
|
112
|
+
|
|
113
|
+
Example:
|
|
114
|
+
toolkit = await create_maton_agent_toolkit(
|
|
115
|
+
api_key='YOUR_MATON_API_KEY',
|
|
116
|
+
)
|
|
117
|
+
tools = toolkit.get_tools()
|
|
118
|
+
|
|
119
|
+
# Use with LangChain agent
|
|
120
|
+
agent = create_react_agent(llm, tools, prompt)
|
|
121
|
+
|
|
122
|
+
# Clean up when done
|
|
123
|
+
await toolkit.close()
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
api_key: Maton API key. Create one at https://maton.ai
|
|
127
|
+
configuration: Optional configuration for context
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Initialized MatonAgentToolkit ready to use
|
|
131
|
+
"""
|
|
132
|
+
toolkit = MatonAgentToolkit(api_key, configuration)
|
|
133
|
+
await toolkit.initialize()
|
|
134
|
+
return toolkit
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""Maton Agent Toolkit for OpenAI Agents SDK."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import List, Any
|
|
5
|
+
|
|
6
|
+
from agents import FunctionTool
|
|
7
|
+
from agents.run_context import RunContextWrapper
|
|
8
|
+
|
|
9
|
+
from ..shared.toolkit_core import ToolkitCore
|
|
10
|
+
from ..shared.mcp_client import McpTool
|
|
11
|
+
from ..configuration import Configuration
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MatonAgentToolkit(ToolkitCore[List[FunctionTool]]):
|
|
15
|
+
"""
|
|
16
|
+
Maton Agent Toolkit for OpenAI Agents SDK.
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
toolkit = await create_maton_agent_toolkit(
|
|
20
|
+
api_key='YOUR_MATON_API_KEY',
|
|
21
|
+
)
|
|
22
|
+
tools = toolkit.get_tools()
|
|
23
|
+
agent = Agent(name="Maton Agent", tools=tools)
|
|
24
|
+
await toolkit.close()
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
api_key: str | None = None,
|
|
30
|
+
configuration: Configuration | None = None
|
|
31
|
+
):
|
|
32
|
+
super().__init__(api_key, configuration)
|
|
33
|
+
|
|
34
|
+
def _empty_tools(self) -> List[FunctionTool]:
|
|
35
|
+
"""Return empty list of tools."""
|
|
36
|
+
return []
|
|
37
|
+
|
|
38
|
+
def _convert_tools(
|
|
39
|
+
self,
|
|
40
|
+
mcp_tools: List[McpTool]
|
|
41
|
+
) -> List[FunctionTool]:
|
|
42
|
+
"""Convert MCP tools to OpenAI FunctionTool instances."""
|
|
43
|
+
tools = []
|
|
44
|
+
for mcp_tool in mcp_tools:
|
|
45
|
+
tools.append(self._create_function_tool(mcp_tool))
|
|
46
|
+
return tools
|
|
47
|
+
|
|
48
|
+
def _create_function_tool(self, mcp_tool: McpTool) -> FunctionTool:
|
|
49
|
+
"""Create a FunctionTool from an MCP tool definition."""
|
|
50
|
+
toolkit = self
|
|
51
|
+
tool_name = mcp_tool["name"]
|
|
52
|
+
|
|
53
|
+
async def on_invoke_tool(
|
|
54
|
+
ctx: RunContextWrapper[Any],
|
|
55
|
+
input_str: str
|
|
56
|
+
) -> str:
|
|
57
|
+
args = json.loads(input_str)
|
|
58
|
+
return await toolkit.run_tool(tool_name, args)
|
|
59
|
+
|
|
60
|
+
# Prepare parameters schema
|
|
61
|
+
parameters = dict(mcp_tool.get("inputSchema", {}))
|
|
62
|
+
parameters["additionalProperties"] = False
|
|
63
|
+
parameters["type"] = "object"
|
|
64
|
+
|
|
65
|
+
# Clean up schema - remove fields not needed in OpenAI function schema
|
|
66
|
+
for key in ["description", "title"]:
|
|
67
|
+
parameters.pop(key, None)
|
|
68
|
+
|
|
69
|
+
if "properties" in parameters:
|
|
70
|
+
for prop in parameters["properties"].values():
|
|
71
|
+
for key in ["title", "default"]:
|
|
72
|
+
if isinstance(prop, dict):
|
|
73
|
+
prop.pop(key, None)
|
|
74
|
+
|
|
75
|
+
return FunctionTool(
|
|
76
|
+
name=tool_name,
|
|
77
|
+
description=mcp_tool.get("description", tool_name),
|
|
78
|
+
params_json_schema=parameters,
|
|
79
|
+
on_invoke_tool=on_invoke_tool,
|
|
80
|
+
strict_json_schema=False
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def tools(self) -> List[FunctionTool]:
|
|
85
|
+
"""
|
|
86
|
+
The tools available in the toolkit.
|
|
87
|
+
|
|
88
|
+
.. deprecated::
|
|
89
|
+
Access tools via get_tools() after calling initialize().
|
|
90
|
+
"""
|
|
91
|
+
return self._get_tools_with_warning()
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
async def create_maton_agent_toolkit(
|
|
95
|
+
api_key: str | None = None,
|
|
96
|
+
configuration: Configuration | None = None
|
|
97
|
+
) -> MatonAgentToolkit:
|
|
98
|
+
"""
|
|
99
|
+
Factory function to create and initialize a MatonAgentToolkit.
|
|
100
|
+
|
|
101
|
+
This is the recommended way to create a toolkit as it handles
|
|
102
|
+
async initialization automatically.
|
|
103
|
+
|
|
104
|
+
Example:
|
|
105
|
+
toolkit = await create_maton_agent_toolkit(
|
|
106
|
+
api_key='YOUR_MATON_API_KEY',
|
|
107
|
+
)
|
|
108
|
+
tools = toolkit.get_tools()
|
|
109
|
+
|
|
110
|
+
# Use with agent
|
|
111
|
+
agent = Agent(name="Maton Agent", tools=tools)
|
|
112
|
+
|
|
113
|
+
# Clean up when done
|
|
114
|
+
await toolkit.close()
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
api_key: Maton API key. Create one at https://maton.ai
|
|
118
|
+
configuration: Optional configuration for context
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
Initialized MatonAgentToolkit ready to use
|
|
122
|
+
"""
|
|
123
|
+
toolkit = MatonAgentToolkit(api_key, configuration)
|
|
124
|
+
await toolkit.initialize()
|
|
125
|
+
return toolkit
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Shared infrastructure for Maton Agent Toolkit MCP integration."""
|
|
2
|
+
|
|
3
|
+
from .constants import VERSION, MCP_SERVER_URL, TOOLKIT_HEADER, MCP_HEADER
|
|
4
|
+
from .async_initializer import AsyncInitializer
|
|
5
|
+
from .mcp_client import MatonMcpClient, McpTool, McpToolInputSchema
|
|
6
|
+
from .schema_utils import json_schema_to_pydantic_model, json_schema_to_pydantic_fields
|
|
7
|
+
from .toolkit_core import ToolkitCore
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"VERSION",
|
|
11
|
+
"MCP_SERVER_URL",
|
|
12
|
+
"TOOLKIT_HEADER",
|
|
13
|
+
"MCP_HEADER",
|
|
14
|
+
"AsyncInitializer",
|
|
15
|
+
"MatonMcpClient",
|
|
16
|
+
"McpTool",
|
|
17
|
+
"McpToolInputSchema",
|
|
18
|
+
"json_schema_to_pydantic_model",
|
|
19
|
+
"json_schema_to_pydantic_fields",
|
|
20
|
+
"ToolkitCore",
|
|
21
|
+
]
|