listToolsPage method
Future<ListToolsResult>
listToolsPage({
- String? cursor,
- Map<
String, dynamic> ? meta, - RequestOptions? options,
One page of tools/list: pass the previous page's nextCursor as
cursor for the next one.
Implementation
Future<ListToolsResult> listToolsPage({String? cursor, Map<String, dynamic>? meta, RequestOptions? options}) async {
if (!_initialized) {
throw McpError('Client is not initialized');
}
if (!_statelessMode && _serverCapabilities?.tools != true) {
throw McpError('Server does not support tools');
}
final response = await _sendRequest(
'tools/list', _withMeta({if (cursor != null) 'cursor': cursor}, meta), options);
var result = ListToolsResult.fromJson(Map<String, dynamic>.from(response as Map));
// 2026-07-28 Streamable HTTP: a tool whose x-mcp-header annotations are
// invalid is left out of the list (with a warning), the rest stay usable.
if (_mirrorsParamHeaders) {
final kept = <Tool>[];
for (final tool in result.tools) {
final annotations = mcpParamHeaders(tool.toJson()['inputSchema']);
if (annotations.problem != null) {
_logger.warning('Tool "${tool.name}" rejected: ${annotations.problem}');
continue;
}
_toolParamHeaders[tool.name] = annotations.headers;
kept.add(tool);
}
if (kept.length != result.tools.length) {
result = ListToolsResult.fromJson({
...result.toJson(),
'tools': [for (final t in kept) t.toJson()],
});
}
}
for (final tool in result.tools) {
_rememberOutputSchema(tool);
final execution = tool.toJson()['execution'];
_toolTaskSupport[tool.name] =
(execution is Map ? execution['taskSupport'] as String? : null) ?? 'forbidden';
}
return result;
}