ruby-mcp-client 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +345 -3
- data/lib/mcp_client/auth/browser_oauth.rb +424 -0
- data/lib/mcp_client/auth/oauth_provider.rb +131 -19
- data/lib/mcp_client/auth.rb +1 -1
- data/lib/mcp_client/client.rb +73 -1
- data/lib/mcp_client/json_rpc_common.rb +3 -1
- data/lib/mcp_client/server_factory.rb +4 -2
- data/lib/mcp_client/server_http.rb +8 -0
- data/lib/mcp_client/server_sse/sse_parser.rb +11 -0
- data/lib/mcp_client/server_sse.rb +126 -0
- data/lib/mcp_client/server_stdio.rb +100 -1
- data/lib/mcp_client/server_streamable_http/json_rpc_transport.rb +8 -1
- data/lib/mcp_client/server_streamable_http.rb +132 -6
- data/lib/mcp_client/tool.rb +40 -4
- data/lib/mcp_client/version.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a5e35c00292938e3c6cd17885d6578e465d12853ed1844f67dc4633096bb2fa3
|
|
4
|
+
data.tar.gz: e9419a3969689a0768ea8290f2a45f5214fcc4b74521ac38aac3bfd842b7ec49
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 063bc6c91cf5d6e82a05b17dd90519e07d3168baf5efb36969e98d0893d40f4d630db3181dfd28929fc255f579780c041b407dfd8bfec17f3461022f2cb84471
|
|
7
|
+
data.tar.gz: e92a6c8d29474c08966008f9e2e5f530520258f546b40694fc0245eaf3da2ad6064ce7bb312596a07d5e4a94f4516603256c2bd7375cfc67065180f636f64eb1
|
data/README.md
CHANGED
|
@@ -40,11 +40,16 @@ with popular AI services with built-in conversions:
|
|
|
40
40
|
- `to_anthropic_tools()` - Formats tools for Anthropic Claude API
|
|
41
41
|
- `to_google_tools()` - Formats tools for Google Vertex AI API (automatically removes "$schema" keys not accepted by Vertex AI)
|
|
42
42
|
|
|
43
|
-
## MCP
|
|
43
|
+
## MCP Protocol Support
|
|
44
44
|
|
|
45
|
-
This Ruby MCP Client implements
|
|
45
|
+
This Ruby MCP Client implements the **MCP 2025-06-18** specification with full backward compatibility.
|
|
46
46
|
|
|
47
|
-
###
|
|
47
|
+
### Key Features
|
|
48
|
+
|
|
49
|
+
**MCP 2025-06-18 (Latest):**
|
|
50
|
+
- **Structured Tool Outputs** - Tools can declare output schemas and return type-safe, validated structured data
|
|
51
|
+
- **Elicitation (Server-initiated User Interactions)** - Servers can request user input during tool execution via bidirectional JSON-RPC (stdio, SSE, and Streamable HTTP transports)
|
|
52
|
+
- **Tool Annotations** - Support for tool behavior annotations (readOnly, destructive, requiresConfirmation) for safer tool execution
|
|
48
53
|
- **OAuth 2.1 Authorization Framework** - Complete authentication with PKCE, dynamic client registration, server discovery, and runtime configuration
|
|
49
54
|
- **Streamable HTTP Transport** - Enhanced transport with Server-Sent Event formatted responses and session management
|
|
50
55
|
- **HTTP Redirect Support** - Automatic redirect handling for both SSE and HTTP transports with configurable limits
|
|
@@ -581,14 +586,22 @@ client = Anthropic::Client.new(access_token: ENV['ANTHROPIC_API_KEY'])
|
|
|
581
586
|
```
|
|
582
587
|
|
|
583
588
|
Complete examples can be found in the `examples/` directory:
|
|
589
|
+
|
|
590
|
+
**AI Integration Examples:**
|
|
584
591
|
- `ruby_openai_mcp.rb` - Integration with alexrudall/ruby-openai gem
|
|
585
592
|
- `openai_ruby_mcp.rb` - Integration with official openai/openai-ruby gem
|
|
586
593
|
- `ruby_anthropic_mcp.rb` - Integration with alexrudall/ruby-anthropic gem
|
|
587
594
|
- `gemini_ai_mcp.rb` - Integration with Google Vertex AI and Gemini models
|
|
595
|
+
|
|
596
|
+
**Transport Examples:**
|
|
588
597
|
- `streamable_http_example.rb` - Streamable HTTP transport with Playwright MCP
|
|
589
598
|
- `echo_server.py` & `echo_server_client.rb` - FastMCP server example with full setup
|
|
590
599
|
- `echo_server_streamable.py` & `echo_server_streamable_client.rb` - Enhanced streamable HTTP server example
|
|
591
600
|
|
|
601
|
+
**MCP 2025 Protocol Features:**
|
|
602
|
+
- `structured_output_server.py` & `test_structured_outputs.rb` - Structured tool outputs (MCP 2025-06-18)
|
|
603
|
+
- `echo_server_with_annotations.py` & `test_tool_annotations.rb` - Tool annotations (MCP 2025-03-26)
|
|
604
|
+
|
|
592
605
|
## MCP Server Compatibility
|
|
593
606
|
|
|
594
607
|
This client works with any MCP-compatible server, including:
|
|
@@ -777,6 +790,83 @@ auth_url = oauth_provider.start_authorization_flow
|
|
|
777
790
|
token = oauth_provider.complete_authorization_flow(code, state)
|
|
778
791
|
```
|
|
779
792
|
|
|
793
|
+
### Browser-Based OAuth Authentication
|
|
794
|
+
|
|
795
|
+
For the easiest authentication experience, use the browser-based OAuth flow that automatically handles the entire process:
|
|
796
|
+
|
|
797
|
+
```ruby
|
|
798
|
+
require 'mcp_client/auth/browser_oauth'
|
|
799
|
+
|
|
800
|
+
# Create OAuth provider
|
|
801
|
+
oauth_provider = MCPClient::Auth::OAuthProvider.new(
|
|
802
|
+
server_url: 'https://api.example.com/mcp',
|
|
803
|
+
redirect_uri: 'http://localhost:8080/callback',
|
|
804
|
+
scope: 'read:tools write:tools' # Optional
|
|
805
|
+
)
|
|
806
|
+
|
|
807
|
+
# Create browser OAuth helper
|
|
808
|
+
browser_oauth = MCPClient::Auth::BrowserOAuth.new(
|
|
809
|
+
oauth_provider,
|
|
810
|
+
callback_port: 8080, # Optional: Port for local server (default: 8080)
|
|
811
|
+
callback_path: '/callback' # Optional: Callback path (default: '/callback')
|
|
812
|
+
)
|
|
813
|
+
|
|
814
|
+
# Authenticate (opens browser automatically and handles callback)
|
|
815
|
+
token = browser_oauth.authenticate(
|
|
816
|
+
timeout: 300, # Optional: 5 minutes (default: 300)
|
|
817
|
+
auto_open_browser: true # Optional: Auto-open browser (default: true)
|
|
818
|
+
)
|
|
819
|
+
|
|
820
|
+
# Create authenticated client (use streamable_http for modern MCP servers)
|
|
821
|
+
server_config = {
|
|
822
|
+
type: 'streamable_http', # or 'http' for simple HTTP-only servers
|
|
823
|
+
base_url: 'https://api.example.com/mcp',
|
|
824
|
+
oauth_provider: oauth_provider
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
client = MCPClient::Client.new(mcp_server_configs: [server_config])
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
**How it works:**
|
|
831
|
+
1. **Automatically starts a local HTTP server** (using pure Ruby `TCPServer`) to handle the OAuth callback
|
|
832
|
+
2. **Opens your default browser** to the authorization page (macOS: `open`, Linux: `xdg-open`, Windows: `start`)
|
|
833
|
+
3. **Captures the authorization code** automatically from the callback
|
|
834
|
+
4. **Completes the OAuth flow** and stores the access token
|
|
835
|
+
5. **Handles token refresh** automatically when tokens expire
|
|
836
|
+
|
|
837
|
+
**Features:**
|
|
838
|
+
- **Zero external dependencies** - Uses pure Ruby stdlib (`TCPServer`)
|
|
839
|
+
- **User-friendly HTML pages** - Shows success/error pages in the browser
|
|
840
|
+
- **Automatic token management** - Handles token refresh transparently
|
|
841
|
+
- **Configurable timeout** - Raises `Timeout::Error` if user doesn't authorize in time
|
|
842
|
+
- **Token storage** - Supports custom storage backends for persistent tokens
|
|
843
|
+
- **Port conflict detection** - Clear error messages if port is already in use
|
|
844
|
+
- **Security hardened** - PKCE, CSRF protection, request validation, header limits
|
|
845
|
+
|
|
846
|
+
**Error Handling:**
|
|
847
|
+
```ruby
|
|
848
|
+
begin
|
|
849
|
+
token = browser_oauth.authenticate
|
|
850
|
+
rescue Timeout::Error
|
|
851
|
+
puts "User took too long to authorize"
|
|
852
|
+
rescue MCPClient::Errors::ConnectionError => e
|
|
853
|
+
puts "OAuth flow failed: #{e.message}"
|
|
854
|
+
# Port already in use, server doesn't support OAuth, etc.
|
|
855
|
+
rescue ArgumentError => e
|
|
856
|
+
puts "Invalid state parameter (CSRF protection)"
|
|
857
|
+
end
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
**Server Requirements:**
|
|
861
|
+
- OAuth 2.1 Protocol with PKCE
|
|
862
|
+
- Authorization Server Discovery via:
|
|
863
|
+
- `/.well-known/oauth-authorization-server` (primary, for self-contained servers)
|
|
864
|
+
- `/.well-known/oauth-protected-resource` (fallback, for delegated auth)
|
|
865
|
+
- Dynamic Client Registration (recommended)
|
|
866
|
+
- Authorization Code Grant Flow
|
|
867
|
+
|
|
868
|
+
For a complete working example, see [`examples/oauth_browser_auth.rb`](examples/oauth_browser_auth.rb).
|
|
869
|
+
|
|
780
870
|
### OAuth Features
|
|
781
871
|
|
|
782
872
|
- **OAuth 2.1 compliance** with PKCE for security
|
|
@@ -785,6 +875,7 @@ token = oauth_provider.complete_authorization_flow(code, state)
|
|
|
785
875
|
- **Token refresh** and automatic token management
|
|
786
876
|
- **Pluggable storage** for tokens and client credentials
|
|
787
877
|
- **Runtime configuration** via getter/setter methods
|
|
878
|
+
- **Browser-based authentication** with automatic callback handling
|
|
788
879
|
|
|
789
880
|
For complete OAuth documentation, see [OAUTH.md](OAUTH.md).
|
|
790
881
|
|
|
@@ -908,6 +999,254 @@ elsif content.binary?
|
|
|
908
999
|
end
|
|
909
1000
|
```
|
|
910
1001
|
|
|
1002
|
+
## Tool Annotations
|
|
1003
|
+
|
|
1004
|
+
MCP 2025-06-18 supports tool annotations that describe tool behavior, enabling safer and more informed tool execution. The Ruby MCP Client provides full support for reading and interpreting these annotations.
|
|
1005
|
+
|
|
1006
|
+
### Annotation Types
|
|
1007
|
+
|
|
1008
|
+
Tools can include the following annotations:
|
|
1009
|
+
|
|
1010
|
+
- **`readOnly`** - Indicates the tool only reads data and doesn't modify state
|
|
1011
|
+
- **`destructive`** - Indicates the tool performs potentially dangerous operations (e.g., deleting data)
|
|
1012
|
+
- **`requiresConfirmation`** - Indicates the tool should require explicit user confirmation before execution
|
|
1013
|
+
|
|
1014
|
+
### Using Tool Annotations
|
|
1015
|
+
|
|
1016
|
+
```ruby
|
|
1017
|
+
# List tools and check their annotations
|
|
1018
|
+
tools = client.list_tools
|
|
1019
|
+
|
|
1020
|
+
tools.each do |tool|
|
|
1021
|
+
puts "Tool: #{tool.name}"
|
|
1022
|
+
|
|
1023
|
+
# Check annotations using helper methods
|
|
1024
|
+
if tool.read_only?
|
|
1025
|
+
puts " → Safe to execute (read-only)"
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
if tool.destructive?
|
|
1029
|
+
puts " ⚠️ Warning: This tool is destructive"
|
|
1030
|
+
end
|
|
1031
|
+
|
|
1032
|
+
if tool.requires_confirmation?
|
|
1033
|
+
puts " 🛡️ Requires user confirmation before execution"
|
|
1034
|
+
end
|
|
1035
|
+
|
|
1036
|
+
# Access raw annotations hash
|
|
1037
|
+
if tool.annotations
|
|
1038
|
+
puts " Annotations: #{tool.annotations.inspect}"
|
|
1039
|
+
end
|
|
1040
|
+
end
|
|
1041
|
+
|
|
1042
|
+
# Make informed decisions based on annotations
|
|
1043
|
+
tool = client.find_tool('delete_user')
|
|
1044
|
+
if tool.destructive? && tool.requires_confirmation?
|
|
1045
|
+
# Prompt user for confirmation before executing
|
|
1046
|
+
puts "This will delete user data. Are you sure? (y/n)"
|
|
1047
|
+
response = gets.chomp
|
|
1048
|
+
if response.downcase == 'y'
|
|
1049
|
+
result = client.call_tool('delete_user', { user_id: 123 })
|
|
1050
|
+
else
|
|
1051
|
+
puts "Operation cancelled"
|
|
1052
|
+
end
|
|
1053
|
+
else
|
|
1054
|
+
# Safe to execute without confirmation
|
|
1055
|
+
result = client.call_tool('get_user', { user_id: 123 })
|
|
1056
|
+
end
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
### Tool Annotation Helper Methods
|
|
1060
|
+
|
|
1061
|
+
The `Tool` class provides convenient helper methods:
|
|
1062
|
+
|
|
1063
|
+
- `tool.read_only?` - Returns true if the tool is marked as read-only
|
|
1064
|
+
- `tool.destructive?` - Returns true if the tool is marked as destructive
|
|
1065
|
+
- `tool.requires_confirmation?` - Returns true if the tool requires confirmation
|
|
1066
|
+
- `tool.annotations` - Returns the raw annotations hash
|
|
1067
|
+
|
|
1068
|
+
### Example
|
|
1069
|
+
|
|
1070
|
+
See `examples/test_tool_annotations.rb` for a complete working example demonstrating:
|
|
1071
|
+
- Listing tools with their annotations
|
|
1072
|
+
- Using annotation helper methods
|
|
1073
|
+
- Making annotation-aware decisions about tool execution
|
|
1074
|
+
- Handling destructive operations safely
|
|
1075
|
+
|
|
1076
|
+
## Structured Tool Outputs
|
|
1077
|
+
|
|
1078
|
+
MCP 2025-06-18 introduces structured tool outputs, allowing tools to declare output schemas and return type-safe, validated data structures instead of just text.
|
|
1079
|
+
|
|
1080
|
+
### Overview
|
|
1081
|
+
|
|
1082
|
+
Tools can now specify an `outputSchema` (JSON Schema) that defines the expected structure of their results. When called, they return data in a `structuredContent` field that validates against this schema, providing:
|
|
1083
|
+
|
|
1084
|
+
- **Type safety** - Predictable, validated data structures
|
|
1085
|
+
- **Better IDE support** - Code completion and type checking
|
|
1086
|
+
- **Easier parsing** - No need to parse text or guess formats
|
|
1087
|
+
- **Backward compatibility** - Text content is still provided alongside structured data
|
|
1088
|
+
|
|
1089
|
+
### Using Structured Outputs
|
|
1090
|
+
|
|
1091
|
+
```ruby
|
|
1092
|
+
# List tools and check for structured output support
|
|
1093
|
+
tools = client.list_tools
|
|
1094
|
+
|
|
1095
|
+
tools.each do |tool|
|
|
1096
|
+
if tool.structured_output?
|
|
1097
|
+
puts "#{tool.name} supports structured output"
|
|
1098
|
+
puts "Output schema: #{tool.output_schema}"
|
|
1099
|
+
end
|
|
1100
|
+
end
|
|
1101
|
+
|
|
1102
|
+
# Call a tool that returns structured output
|
|
1103
|
+
result = client.call_tool('get_weather', { location: 'San Francisco' })
|
|
1104
|
+
|
|
1105
|
+
# Access structured data (type-safe, validated)
|
|
1106
|
+
if result['structuredContent']
|
|
1107
|
+
data = result['structuredContent']
|
|
1108
|
+
puts "Temperature: #{data['temperature']}°C"
|
|
1109
|
+
puts "Conditions: #{data['conditions']}"
|
|
1110
|
+
puts "Humidity: #{data['humidity']}%"
|
|
1111
|
+
end
|
|
1112
|
+
|
|
1113
|
+
# Backward compatibility: text content is still available
|
|
1114
|
+
text_content = result['content']&.first&.dig('text')
|
|
1115
|
+
parsed = JSON.parse(text_content) if text_content
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
### Helper Methods
|
|
1119
|
+
|
|
1120
|
+
The `Tool` class provides a convenient helper method:
|
|
1121
|
+
|
|
1122
|
+
- `tool.structured_output?` - Returns true if the tool has an output schema defined
|
|
1123
|
+
- `tool.output_schema` - Returns the JSON Schema for the tool's output
|
|
1124
|
+
|
|
1125
|
+
### Example
|
|
1126
|
+
|
|
1127
|
+
See `examples/test_structured_outputs.rb` for a complete working example demonstrating:
|
|
1128
|
+
- Detecting tools with structured output support
|
|
1129
|
+
- Accessing output schemas
|
|
1130
|
+
- Calling tools and receiving structured data
|
|
1131
|
+
- Backward compatibility with text content
|
|
1132
|
+
|
|
1133
|
+
The example includes a Python MCP server (`examples/structured_output_server.py`) that provides three tools with structured outputs:
|
|
1134
|
+
- `get_weather` - Weather data with temperature, conditions, humidity
|
|
1135
|
+
- `analyze_text` - Text analysis with word count, character count, statistics
|
|
1136
|
+
- `calculate_stats` - Statistical calculations (mean, median, min, max, etc.)
|
|
1137
|
+
|
|
1138
|
+
## Elicitation (Server-initiated User Interactions) - MCP 2025-06-18
|
|
1139
|
+
|
|
1140
|
+
Elicitation enables MCP servers to request user input during tool execution via bidirectional JSON-RPC.
|
|
1141
|
+
This allows servers to gather additional information, confirm sensitive operations, or interact with users
|
|
1142
|
+
dynamically during the execution of tools.
|
|
1143
|
+
|
|
1144
|
+
### Transport Support
|
|
1145
|
+
|
|
1146
|
+
**Fully Supported:**
|
|
1147
|
+
- ✅ **stdio** - Full bidirectional JSON-RPC over stdin/stdout
|
|
1148
|
+
- ✅ **SSE** - Server sends requests via SSE stream, client responds via HTTP POST
|
|
1149
|
+
- ✅ **Streamable HTTP** - Server sends requests via SSE-formatted responses, client responds via HTTP POST
|
|
1150
|
+
|
|
1151
|
+
**Not Supported:**
|
|
1152
|
+
- ❌ **HTTP** - Pure request-response architecture prevents server-initiated requests
|
|
1153
|
+
|
|
1154
|
+
### Using Elicitation
|
|
1155
|
+
|
|
1156
|
+
To use elicitation, register a handler when creating the client:
|
|
1157
|
+
|
|
1158
|
+
```ruby
|
|
1159
|
+
# Define an elicitation handler
|
|
1160
|
+
elicitation_handler = lambda do |message, requested_schema|
|
|
1161
|
+
puts "Server requests: #{message}"
|
|
1162
|
+
|
|
1163
|
+
# Show expected input format from schema
|
|
1164
|
+
if requested_schema && requested_schema['properties']
|
|
1165
|
+
requested_schema['properties'].each do |field, schema|
|
|
1166
|
+
puts " #{field}: #{schema['type']}"
|
|
1167
|
+
end
|
|
1168
|
+
end
|
|
1169
|
+
|
|
1170
|
+
# Prompt user and return one of three response types:
|
|
1171
|
+
|
|
1172
|
+
# 1. Accept and provide data to the server
|
|
1173
|
+
{
|
|
1174
|
+
'action' => 'accept',
|
|
1175
|
+
'content' => {
|
|
1176
|
+
'field_name' => 'user_input_value'
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
# 2. Decline to provide input
|
|
1181
|
+
# { 'action' => 'decline' }
|
|
1182
|
+
|
|
1183
|
+
# 3. Cancel the operation
|
|
1184
|
+
# { 'action' => 'cancel' }
|
|
1185
|
+
end
|
|
1186
|
+
|
|
1187
|
+
# Create client with elicitation handler
|
|
1188
|
+
# Works with stdio, SSE, and Streamable HTTP transports
|
|
1189
|
+
client = MCPClient::Client.new(
|
|
1190
|
+
mcp_server_configs: [
|
|
1191
|
+
# Stdio transport
|
|
1192
|
+
MCPClient.stdio_config(
|
|
1193
|
+
command: 'python my_server.py',
|
|
1194
|
+
name: 'my-server'
|
|
1195
|
+
),
|
|
1196
|
+
# Or SSE transport
|
|
1197
|
+
MCPClient.sse_config(
|
|
1198
|
+
base_url: 'https://api.example.com/sse',
|
|
1199
|
+
name: 'remote-server'
|
|
1200
|
+
),
|
|
1201
|
+
# Or Streamable HTTP transport
|
|
1202
|
+
MCPClient.streamable_http_config(
|
|
1203
|
+
base_url: 'https://api.example.com',
|
|
1204
|
+
endpoint: '/mcp',
|
|
1205
|
+
name: 'streamable-server'
|
|
1206
|
+
)
|
|
1207
|
+
],
|
|
1208
|
+
elicitation_handler: elicitation_handler
|
|
1209
|
+
)
|
|
1210
|
+
|
|
1211
|
+
# Call tools - connection happens automatically
|
|
1212
|
+
# Server may send elicitation requests during tool execution
|
|
1213
|
+
result = client.call_tool('create_document', { format: 'markdown' }, server: 'my-server')
|
|
1214
|
+
```
|
|
1215
|
+
|
|
1216
|
+
### Response Actions
|
|
1217
|
+
|
|
1218
|
+
The elicitation handler should return a hash with an `action` field:
|
|
1219
|
+
|
|
1220
|
+
1. **Accept** - Provide the requested input:
|
|
1221
|
+
```ruby
|
|
1222
|
+
{
|
|
1223
|
+
'action' => 'accept',
|
|
1224
|
+
'content' => { 'field' => 'value' } # Must match requested schema
|
|
1225
|
+
}
|
|
1226
|
+
```
|
|
1227
|
+
|
|
1228
|
+
2. **Decline** - Refuse to provide input (server should handle gracefully):
|
|
1229
|
+
```ruby
|
|
1230
|
+
{ 'action' => 'decline' }
|
|
1231
|
+
```
|
|
1232
|
+
|
|
1233
|
+
3. **Cancel** - Cancel the entire operation:
|
|
1234
|
+
```ruby
|
|
1235
|
+
{ 'action' => 'cancel' }
|
|
1236
|
+
```
|
|
1237
|
+
|
|
1238
|
+
### Example
|
|
1239
|
+
|
|
1240
|
+
See `examples/elicitation/test_elicitation.rb` for a complete working example demonstrating:
|
|
1241
|
+
- Registering an elicitation handler
|
|
1242
|
+
- Handling different message types and schemas
|
|
1243
|
+
- Responding with accept/decline/cancel actions
|
|
1244
|
+
- Interactive user prompts during tool execution
|
|
1245
|
+
|
|
1246
|
+
The example includes a Python MCP server (`examples/elicitation/elicitation_server.py`) that provides tools using elicitation:
|
|
1247
|
+
- `create_document` - Requests title and content via elicitation
|
|
1248
|
+
- `send_notification` - Confirms before sending a notification
|
|
1249
|
+
|
|
911
1250
|
## Key Features
|
|
912
1251
|
|
|
913
1252
|
### Client Features
|
|
@@ -918,6 +1257,9 @@ end
|
|
|
918
1257
|
- **Server lookup** - Find servers by name using `find_server`
|
|
919
1258
|
- **Tool association** - Each tool knows which server it belongs to
|
|
920
1259
|
- **Tool discovery** - Find tools by name or pattern
|
|
1260
|
+
- **Structured outputs** - Support for MCP 2025-06-18 structured tool outputs with output schemas and type-safe responses
|
|
1261
|
+
- **Tool annotations** - Support for readOnly, destructive, and requiresConfirmation annotations with helper methods
|
|
1262
|
+
- **Elicitation support** - Server-initiated user interactions during tool execution (stdio, SSE, and Streamable HTTP transports)
|
|
921
1263
|
- **Server disambiguation** - Specify which server to use when tools with same name exist in multiple servers
|
|
922
1264
|
- **Atomic tool calls** - Simple API for invoking tools with parameters
|
|
923
1265
|
- **Batch support** - Call multiple tools in a single operation
|