Metadata-Version: 2.4
Name: eo-toolbelt
Version: 0.1.0
Summary: Python SDK for EO Toolbelt built-in tools, MCP tools, and provider-native tool schemas
Author: EO Toolbelt Maintainers
License-Expression: MIT
Project-URL: Homepage, https://github.com/easyops-io/eo-toolbelt
Project-URL: Documentation, https://github.com/easyops-io/eo-toolbelt#readme
Project-URL: Repository, https://github.com/easyops-io/eo-toolbelt
Project-URL: Issues, https://github.com/easyops-io/eo-toolbelt/issues
Keywords: mcp,tools,llm,sdk,tool-use
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp>=1.8.0
Requires-Dist: jsonschema>=4.20.0
Requires-Dist: tiktoken>=0.8.0
Requires-Dist: tzdata>=2025.2
Provides-Extra: dev
Requires-Dist: setuptools>=69; extra == "dev"
Requires-Dist: wheel>=0.43; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Dynamic: license-file

# EO Toolbelt SDK

Korean documentation: [README.ko.md](README.ko.md)

EO Toolbelt SDK helps Python applications expose utility tools, custom Python functions, and MCP server tools to model providers.

It gives you three small building blocks:

- list available tool specs
- execute a selected tool by name
- build provider-native tool option payloads for OpenAI, Anthropic, Gemini, and Bedrock Converse

The SDK does not call a language model for you. Your application keeps the model message loop and passes tool results back using the provider's normal API format.

## Install

```bash
pip install eo-toolbelt
```

Import package:

```python
from mcp_tools_sdk import Tools
```

## Quick Start

```python
import asyncio

from mcp_tools_sdk import Tools


async def main() -> None:
    tools = Tools()

    result = await tools.call_tool(
        "safe_calculate",
        {"expression": "(12 + 8) * 3"},
    )
    print(result)


asyncio.run(main())
```

## Build Model Tool Options

```python
from openai import AsyncOpenAI
from mcp_tools_sdk import Tools

client = AsyncOpenAI()
tools = Tools()

tool_options = await tools.model_tool_options(
    provider="openai",
    tool_names=["safe_calculate", "get_current_datetime"],
)

response = await client.responses.create(
    model="gpt-5",
    input="What is 12 * 8, and what time is it in Seoul?",
    **tool_options,
)
```

If the model returns a tool call, parse the provider response, call `tools.call_tool(...)`, then send the tool result back to the model.

## Tools Constructor

```python
tools = Tools(
    config_path="mcp_servers.json",
    timeout_seconds=30,
    custom_tools=[my_custom_tool],
)
```

| Option | Type | Description |
| --- | --- | --- |
| `config_path` | `str | Path | None` | MCP server config path. When omitted, built-in and custom tools are available without MCP discovery. |
| `timeout_seconds` | `float | None` | Timeout for MCP operations. |
| `custom_tools` | iterable | Python callables or `CustomTool` objects registered on this instance. |
| `backend` | internal backend | Alternate runtime backend for tests and advanced embedding. |

## Main Methods

### `list_tools(...)`

Returns canonical tool specs.

```python
catalog = await tools.list_tools(
    include_internal=True,
    include_mcp=True,
    include_custom=True,
    mcp_server_names=["fetch"],
    selected_tool_names=["safe_calculate"],
)
```

### `call_tool(tool_name, arguments=None)`

Executes one built-in, custom, or MCP tool.

```python
result = await tools.call_tool(
    "safe_calculate",
    {"expression": "7 * 6"},
)
```

MCP tools use this name format:

```text
mcp__{server_name}__{tool_name}
```

### `model_tool_options(provider, ...)`

Converts tool specs into provider-native request fields.

```python
tool_options = await tools.model_tool_options(
    provider="bedrock",
    tool_names=["safe_calculate"],
    tool_choice={"auto": {}},
)
```

| Provider value | Returned fields |
| --- | --- |
| `openai`, `gpt`, `openai_responses` | OpenAI Responses API `tools` and optional `tool_choice`. |
| `openai_chat_completions` | OpenAI Chat Completions `tools` and optional `tool_choice`. |
| `anthropic`, `claude` | Anthropic Messages `tools` and optional `tool_choice`. |
| `gemini` | Gemini `tools` with `function_declarations` and optional `tool_config`. |
| `bedrock`, `bedrock_converse` | Bedrock Converse `toolConfig`. |

### `select_tools(query, ...)`

Selects a compact tool list from a catalog. Pass an LLM callback for model-judged selection, or omit `llm` for the deterministic keyword fallback.

```python
tool_names = await tools.select_tools(
    query="Calculate actual vs budget variance by department.",
    max_tools=4,
    llm=select_with_llm,
)
```

## Custom Tools

```python
from typing import Literal

from mcp_tools_sdk import Tools, custom_tool


def apply_discount(amount: float, rate: float = 0.1) -> dict:
    """Apply a discount rate."""
    return {"amount": amount, "rate": rate, "total": amount * (1 - rate)}


@custom_tool(name="classify_priority")
def classify_priority(level: Literal["low", "high"]) -> str:
    """Classify a priority level."""
    return level.upper()


tools = Tools(custom_tools=[apply_discount, classify_priority])
```

## MCP Config

Pass an MCP config file when your application wants to expose MCP server tools:

```python
tools = Tools(config_path="mcp_servers.json")
```

An example config is available at [examples/mcp_servers.example.json](examples/mcp_servers.example.json).

Environment variable placeholders use this form:

```text
${ENV_NAME}
${ENV_NAME:-default}
```

Credential values can also be attached to a `Tools` instance:

```python
tools.configure_integration(
    "github",
    {"access_token": "github_pat_..."},
)
```

## License

MIT
