You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds optional in-process result caching for list_mcp_tools() to avoid
redundant MCP session round-trips in agentic loops where the tool list
rarely changes.
- New CacheOptions(ttl, max_size) dataclass accepted by list_mcp_tools(cache=...)
- Results cached per filter + auth-type combination with monotonic TTL (default 600 s)
- cache.evict() for caller-triggered invalidation
- LRU eviction when max_size entries exceeded (default 32)
- 19 new unit tests covering hit/miss, TTL expiry, LRU eviction, evict()
- user-guide.md updated with usage examples and CacheOptions API reference
Closes#178
In agentic loops, `list_mcp_tools()` can be called repeatedly. By default every call opens fresh MCP sessions — expensive for a tool list that rarely changes. Pass a `CacheOptions` instance to cache results in-process.
101
+
102
+
```python
103
+
from sap_cloud_sdk.agentgateway import CacheOptions, create_client
The cache is scoped to the `CacheOptions` instance — different instances don't share state. Distinct filter and auth-type combinations are cached as independent entries, up to `max_size` entries total (LRU eviction when the limit is hit).
120
+
121
+
```python
122
+
# Custom TTL and size cap
123
+
cache = CacheOptions(ttl=600, max_size=10)
124
+
```
125
+
126
+
The cache is **in-process only** — not shared across client instances, processes, or Kubernetes pods.
127
+
98
128
### LangChain Integration
99
129
100
130
Convert MCP tools to LangChain `StructuredTool` objects for use with LangChain agents:
@@ -221,6 +251,7 @@ class AgentGatewayClient:
221
251
self,
222
252
user_token: str| Callable[[], str] |None=None,
223
253
filter: MCPToolFilter |None=None,
254
+
cache: CacheOptions |None=None,
224
255
) -> list[MCPTool]
225
256
226
257
asyncdef call_mcp_tool(
@@ -271,16 +302,31 @@ Both fields default to empty lists. `agent_names` is applied after fetching; `or
271
302
from sap_cloud_sdk.agentgateway import MCPToolFilter
272
303
273
304
MCPToolFilter(
274
-
names=[], # tool names to include (matched against MCPTool.name); empty = no filter
305
+
names=[], # tool names to include (matched against MCPTool.name); empty = no filter
275
306
ord_ids=[], # ORD IDs to include (extracted from fragment URL for LoB, or matched
276
-
# against IntegrationDependency.ord_id for customer agents); empty = no filter
307
+
# against IntegrationDependency.ord_id for customer agents); empty = no filter
277
308
)
278
309
```
279
310
280
311
Both fields default to empty lists. `names`is applied after fetching; `ord_ids`is applied before fetching, skipping non-matching fragments.
281
312
282
313
> Both filter classes use AND semantics: if both fields are set, a result must match all of them to be included.
283
314
315
+
### CacheOptions
316
+
317
+
```python
318
+
from sap_cloud_sdk.agentgateway import CacheOptions
319
+
320
+
CacheOptions(
321
+
ttl=600.0, # cache lifetime in seconds; default 600
322
+
max_size=32, # max distinct cached entries (LRU eviction); default 32
323
+
)
324
+
```
325
+
326
+
-`ttl`: How long a cached tool listis considered valid. After expiry the next call fetches fresh from the network.
327
+
-`max_size`: Cap on how many distinct entries (filter+ auth-type combinations) are held in memory. When exceeded, the least-recently-used entry is evicted.
328
+
-`.evict()`: Clears all entries immediately, forcing a fresh fetch on the next call.
0 commit comments