19
19
20
20
from .transport import create_transport
21
21
22
+ REFETCH_TIMEOUT_MS = 24 * 60 * 60 * 1000 # 1 day
23
+
22
24
23
25
class McpToolDetails (BaseModel ):
24
26
"""Details of an MCP tool."""
@@ -35,11 +37,11 @@ def __init__(
35
37
self ,
36
38
transport : Optional [str ] = None ,
37
39
available_tools : Optional [List [McpToolDetails ]] = None ,
38
- last_attempted_fetch : Optional [float ] = None ,
40
+ last_fetched : Optional [float ] = None ,
39
41
):
40
42
self .transport = transport
41
43
self .available_tools = available_tools or []
42
- self .last_attempted_fetch = last_attempted_fetch
44
+ self .last_fetched = last_fetched
43
45
44
46
45
47
class McpClientPluginParams :
@@ -69,7 +71,7 @@ def __init__(
69
71
version : str = "0.0.0" ,
70
72
cache : Optional [Dict [str , McpCachedValue ]] = None ,
71
73
logger : Optional [logging .Logger ] = None ,
72
- refetch_timeout_ms : int = 24 * 60 * 60 * 1000 , # 1 day
74
+ refetch_timeout_ms : int = REFETCH_TIMEOUT_MS , # 1 day
73
75
):
74
76
super ().__init__ (name )
75
77
@@ -78,6 +80,13 @@ def __init__(
78
80
self ._logger = logger .getChild (self .name ) if logger else ConsoleLogger ().create_logger (self .name )
79
81
self ._refetch_timeout_ms = refetch_timeout_ms
80
82
83
+ # If cache is provided, update last_fetched for entries with tools
84
+ if cache :
85
+ current_time = time .time () * 1000
86
+ for cached_value in cache .values ():
87
+ if cached_value .available_tools and not cached_value .last_fetched :
88
+ cached_value .last_fetched = current_time
89
+
81
90
# Track MCP server URLs and their parameters
82
91
self ._mcp_server_params : Dict [str , McpClientPluginParams ] = {}
83
92
@@ -105,7 +114,7 @@ def add_mcp_server(self, url: str, params: Optional[McpClientPluginParams] = Non
105
114
self ._cache [url ] = McpCachedValue (
106
115
transport = params .transport ,
107
116
available_tools = params .available_tools ,
108
- last_attempted_fetch = None ,
117
+ last_fetched = time . time () * 1000 , # Set to current time in milliseconds
109
118
)
110
119
111
120
async def on_build_functions (self , functions : List [Function [BaseModel ]]) -> List [Function [BaseModel ]]:
@@ -127,7 +136,12 @@ async def on_build_functions(self, functions: List[Function[BaseModel]]) -> List
127
136
return all_functions
128
137
129
138
async def _fetch_tools_if_needed (self ) -> None :
130
- """Fetch tools from MCP servers if needed."""
139
+ """
140
+ Fetch tools from MCP servers if needed.
141
+
142
+ We check if there the cached value has met its expiration
143
+ for being refetched. Or if the tools have never been fetched at all
144
+ """
131
145
fetch_needed : List [Tuple [str , McpClientPluginParams ]] = []
132
146
current_time = time .time () * 1000 # Convert to milliseconds
133
147
@@ -140,9 +154,8 @@ async def _fetch_tools_if_needed(self) -> None:
140
154
should_fetch = (
141
155
not cached_data
142
156
or not cached_data .available_tools
143
- or not cached_data .last_attempted_fetch
144
- or (current_time - cached_data .last_attempted_fetch )
145
- > (params .refetch_timeout_ms or self ._refetch_timeout_ms )
157
+ or not cached_data .last_fetched
158
+ or (current_time - cached_data .last_fetched ) > (params .refetch_timeout_ms or self ._refetch_timeout_ms )
146
159
)
147
160
148
161
if should_fetch :
@@ -164,7 +177,7 @@ async def _fetch_tools_if_needed(self) -> None:
164
177
if url not in self ._cache :
165
178
self ._cache [url ] = McpCachedValue ()
166
179
self ._cache [url ].available_tools = result
167
- self ._cache [url ].last_attempted_fetch = current_time
180
+ self ._cache [url ].last_fetched = current_time
168
181
self ._cache [url ].transport = params .transport
169
182
170
183
self ._logger .debug (f"Cached { len (result )} tools for { url } " )
0 commit comments