Skip to content

Commit d50d5fb

Browse files
authored
refactor!: remove deprecated OAS-based getTools, migrate to fetchTools only (#42)
Remove all deprecated OpenAPI Specification (OAS) based tool generation and migrate exclusively to the MCP-based fetch_tools() API. BREAKING CHANGES: - get_tools() method removed from StackOneToolSet - get_tool() method removed from StackOneToolSet - OpenAPI spec parser and loader removed - Bundled OAS JSON files removed (~1.5MB) - Python 3.10+ now required for fetch_tools() Deleted: - stackone_ai/oas/ directory (8 JSON spec files) - stackone_ai/specs/ directory (parser.py, loader.py) - tests/test_parser.py and related snapshots - examples/available_tools.py, custom_base_url.py, error_handling.py Modified: - StackOneToolSet: now only exposes fetch_tools() - stackone_ai/constants.py: removed OAS_DIR constant - stackone_ai/server.py: updated to use fetch_tools() - All examples updated to use fetch_tools() - Tests updated for new API - README.md: updated documentation with migration guide Migration path: Before: toolset.get_tools("hris_*", account_id="acc-123") After: toolset.fetch_tools(actions=["hris_*"], account_ids=["acc-123"]) This aligns the Python SDK with the Node SDK architecture (PR #148), removing maintenance burden of bundled OAS specs and enabling dynamic tool discovery via MCP.
1 parent 10510d4 commit d50d5fb

37 files changed

+120
-120778
lines changed

README.md

Lines changed: 38 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ StackOne AI provides a unified interface for accessing various SaaS tools throug
1010
- Unified interface for multiple SaaS tools
1111
- AI-friendly tool descriptions and parameters
1212
- **Tool Calling**: Direct method calling with `tool.call()` for intuitive usage
13+
- **MCP-backed Dynamic Discovery**: Fetch tools at runtime via `fetch_tools()` with provider, action, and account filtering
1314
- **Advanced Tool Filtering**:
1415
- Glob pattern filtering with patterns like `"hris_*"` and exclusions `"!hris_delete_*"`
15-
- Provider and action filtering with `fetch_tools()`
16+
- Provider and action filtering
1617
- Multi-account support
17-
- Dynamic discovery via `fetch_tools()` so you can pull the latest tools at runtime (accounts, providers, or globbed actions)
1818
- **Meta Tools** (Beta): Dynamic tool discovery and execution based on natural language queries
1919
- Integration with popular AI frameworks:
2020
- OpenAI Functions
@@ -24,54 +24,39 @@ StackOne AI provides a unified interface for accessing various SaaS tools throug
2424

2525
## Requirements
2626

27-
- Python 3.9+ (core SDK functionality)
28-
- Python 3.10+ (for dynamic discovery and CrewAI examples)
27+
- Python 3.10+ (MCP extra required for `fetch_tools()`)
2928

3029
## Installation
3130

32-
### Basic Installation
33-
3431
```bash
35-
pip install stackone-ai
32+
pip install 'stackone-ai[mcp]'
3633

3734
# Or with uv
38-
uv add stackone-ai
35+
uv add 'stackone-ai[mcp]'
3936
```
4037

4138
### Optional Features
4239

4340
```bash
44-
# Install with dynamic discovery support (requires Python 3.10+)
45-
uv add 'stackone-ai[mcp]'
46-
# or
47-
pip install 'stackone-ai[mcp]'
48-
49-
# Install with CrewAI examples (requires Python 3.10+)
50-
uv add 'stackone-ai[examples]'
41+
# Install with CrewAI examples
42+
pip install 'stackone-ai[mcp,examples]'
5143
# or
52-
pip install 'stackone-ai[examples]'
53-
54-
# Install everything
5544
uv add 'stackone-ai[mcp,examples]'
56-
# or
57-
pip install 'stackone-ai[mcp,examples]'
5845
```
5946

6047
## Quick Start
6148

6249
```python
6350
from stackone_ai import StackOneToolSet
6451

65-
# Initialize with API key
52+
# Initialise with API key
6653
toolset = StackOneToolSet() # Uses STACKONE_API_KEY env var
6754
# Or explicitly: toolset = StackOneToolSet(api_key="your-api-key")
6855

6956
# Get HRIS-related tools with glob patterns
70-
tools = toolset.get_tools("hris_*", account_id="your-account-id")
71-
# Exclude certain tools with negative patterns
72-
tools = toolset.get_tools(["hris_*", "!hris_delete_*"])
57+
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=["your-account-id"])
7358

74-
# Use a specific tool with the new call method
59+
# Use a specific tool with the call method
7560
employee_tool = tools.get_tool("hris_get_employee")
7661
# Call with keyword arguments
7762
employee = employee_tool.call(id="employee-id")
@@ -83,30 +68,9 @@ employee = employee_tool.execute({"id": "employee-id"})
8368

8469
StackOne AI SDK provides powerful filtering capabilities to help you select the exact tools you need.
8570

86-
### Filtering with `get_tools()`
71+
### Filtering with `fetch_tools()`
8772

88-
Use glob patterns to filter tools by name:
89-
90-
```python
91-
from stackone_ai import StackOneToolSet
92-
93-
toolset = StackOneToolSet()
94-
95-
# Get all HRIS tools
96-
tools = toolset.get_tools("hris_*", account_id="your-account-id")
97-
98-
# Get multiple categories
99-
tools = toolset.get_tools(["hris_*", "ats_*"])
100-
101-
# Exclude specific tools with negative patterns
102-
tools = toolset.get_tools(["hris_*", "!hris_delete_*"])
103-
```
104-
105-
### Advanced Filtering with `fetch_tools()`
106-
107-
The `fetch_tools()` method provides advanced filtering by providers, actions, and account IDs:
108-
109-
> Install the optional extra (`pip install 'stackone-ai[mcp]'`) on Python 3.10+ to enable dynamic discovery.
73+
The `fetch_tools()` method provides filtering by providers, actions, and account IDs:
11074

11175
```python
11276
from stackone_ai import StackOneToolSet
@@ -199,9 +163,9 @@ StackOne tools work seamlessly with LangChain, enabling powerful AI agent workfl
199163
from langchain_openai import ChatOpenAI
200164
from stackone_ai import StackOneToolSet
201165

202-
# Initialize StackOne tools
166+
# Initialise StackOne tools
203167
toolset = StackOneToolSet()
204-
tools = toolset.get_tools("hris_*", account_id="your-account-id")
168+
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=["your-account-id"])
205169

206170
# Convert to LangChain format
207171
langchain_tools = tools.to_langchain()
@@ -248,7 +212,7 @@ from stackone_ai.integrations.langgraph import to_tool_node, bind_model_with_too
248212

249213
# Prepare tools
250214
toolset = StackOneToolSet()
251-
tools = toolset.get_tools("hris_*", account_id="your-account-id")
215+
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=["your-account-id"])
252216
langchain_tools = tools.to_langchain()
253217

254218
class State(TypedDict):
@@ -280,21 +244,21 @@ _ = app.invoke({"messages": [("user", "Get employee with id emp123") ]})
280244

281245
CrewAI uses LangChain tools natively, making integration seamless:
282246

283-
> **Note**: CrewAI requires Python 3.10+. Install with `pip install 'stackone-ai[examples]'`
247+
> **Note**: CrewAI requires Python 3.10+. Install with `pip install 'stackone-ai[mcp,examples]'`
284248
285249
```python
286250
from crewai import Agent, Crew, Task
287251
from stackone_ai import StackOneToolSet
288252

289253
# Get tools and convert to LangChain format
290254
toolset = StackOneToolSet()
291-
tools = toolset.get_tools("hris_*", account_id="your-account-id")
255+
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=["your-account-id"])
292256
langchain_tools = tools.to_langchain()
293257

294258
# Create CrewAI agent with StackOne tools
295259
agent = Agent(
296260
role="HR Manager",
297-
goal="Analyze employee data and generate insights",
261+
goal="Analyse employee data and generate insights",
298262
backstory="Expert in HR analytics and employee management",
299263
tools=langchain_tools,
300264
llm="gpt-4o-mini"
@@ -323,7 +287,7 @@ from stackone_ai import StackOneToolSet
323287
toolset = StackOneToolSet()
324288

325289
# Get the feedback tool (included with "meta_*" pattern or all tools)
326-
tools = toolset.get_tools("meta_*")
290+
tools = toolset.fetch_tools(actions=["meta_*"])
327291
feedback_tool = tools.get_tool("meta_collect_tool_feedback")
328292

329293
# Submit feedback (typically invoked by AI after user consent)
@@ -346,7 +310,7 @@ Meta tools enable dynamic tool discovery and execution without hardcoding tool n
346310

347311
```python
348312
# Get meta tools for dynamic discovery
349-
tools = toolset.get_tools("hris_*")
313+
tools = toolset.fetch_tools(actions=["hris_*"])
350314
meta_tools = tools.meta_tools()
351315

352316
# Search for relevant tools using natural language
@@ -362,16 +326,31 @@ result = execute_tool.call(toolName="hris_list_employees", params={"limit": 10})
362326

363327
For more examples, check out the [examples/](examples/) directory:
364328

365-
- [Error Handling](examples/error_handling.py)
366329
- [StackOne Account IDs](examples/stackone_account_ids.py)
367-
- [Available Tools](examples/available_tools.py)
368330
- [File Uploads](examples/file_uploads.py)
369331
- [OpenAI Integration](examples/openai_integration.py)
370332
- [LangChain Integration](examples/langchain_integration.py)
371333
- [CrewAI Integration](examples/crewai_integration.py)
372-
- [LangGraph Tool Node](examples/langgraph_tool_node.py)
373334
- [Meta Tools](examples/meta_tools_example.py)
374335

336+
## Migration from `get_tools()` to `fetch_tools()`
337+
338+
If you're upgrading from a previous version that used `get_tools()`, here's how to migrate:
339+
340+
```python
341+
# Before (deprecated)
342+
tools = toolset.get_tools("hris_*", account_id="acc-123")
343+
344+
# After
345+
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=["acc-123"])
346+
```
347+
348+
Key differences:
349+
- `fetch_tools()` uses keyword arguments for all filtering
350+
- `account_id` becomes `account_ids` (list)
351+
- Filter patterns go in the `actions` parameter (list)
352+
- `fetch_tools()` requires the MCP extra (`pip install 'stackone-ai[mcp]'`)
353+
375354
## License
376355

377356
Apache 2.0 License

examples/available_tools.py

Lines changed: 0 additions & 95 deletions
This file was deleted.

examples/crewai_integration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
def crewai_integration():
2020
toolset = StackOneToolSet()
21-
tools = toolset.get_tools("hris_*", account_id=account_id)
21+
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=[account_id])
2222

2323
# CrewAI uses LangChain tools natively
2424
langchain_tools = tools.to_langchain()

examples/custom_base_url.py

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)