tsikol 0.1.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 +7 -0
- data/CHANGELOG.md +22 -0
- data/CONTRIBUTING.md +84 -0
- data/LICENSE +21 -0
- data/README.md +579 -0
- data/Rakefile +12 -0
- data/docs/README.md +69 -0
- data/docs/api/middleware.md +721 -0
- data/docs/api/prompt.md +858 -0
- data/docs/api/resource.md +651 -0
- data/docs/api/server.md +509 -0
- data/docs/api/test-helpers.md +591 -0
- data/docs/api/tool.md +527 -0
- data/docs/cookbook/authentication.md +651 -0
- data/docs/cookbook/caching.md +877 -0
- data/docs/cookbook/dynamic-tools.md +970 -0
- data/docs/cookbook/error-handling.md +887 -0
- data/docs/cookbook/logging.md +1044 -0
- data/docs/cookbook/rate-limiting.md +717 -0
- data/docs/examples/code-assistant.md +922 -0
- data/docs/examples/complete-server.md +726 -0
- data/docs/examples/database-manager.md +1198 -0
- data/docs/examples/devops-tools.md +1382 -0
- data/docs/examples/echo-server.md +501 -0
- data/docs/examples/weather-service.md +822 -0
- data/docs/guides/completion.md +472 -0
- data/docs/guides/getting-started.md +462 -0
- data/docs/guides/middleware.md +823 -0
- data/docs/guides/project-structure.md +434 -0
- data/docs/guides/prompts.md +920 -0
- data/docs/guides/resources.md +720 -0
- data/docs/guides/sampling.md +804 -0
- data/docs/guides/testing.md +863 -0
- data/docs/guides/tools.md +627 -0
- data/examples/README.md +92 -0
- data/examples/advanced_features.rb +129 -0
- data/examples/basic-migrated/app/prompts/weather_chat.rb +44 -0
- data/examples/basic-migrated/app/resources/weather_alerts.rb +18 -0
- data/examples/basic-migrated/app/tools/get_current_weather.rb +34 -0
- data/examples/basic-migrated/app/tools/get_forecast.rb +30 -0
- data/examples/basic-migrated/app/tools/get_weather_by_coords.rb +48 -0
- data/examples/basic-migrated/server.rb +25 -0
- data/examples/basic.rb +73 -0
- data/examples/full_featured.rb +175 -0
- data/examples/middleware_example.rb +112 -0
- data/examples/sampling_example.rb +104 -0
- data/examples/weather-service/app/prompts/weather/chat.rb +90 -0
- data/examples/weather-service/app/resources/weather/alerts.rb +59 -0
- data/examples/weather-service/app/tools/weather/get_current.rb +82 -0
- data/examples/weather-service/app/tools/weather/get_forecast.rb +90 -0
- data/examples/weather-service/server.rb +28 -0
- data/exe/tsikol +6 -0
- data/lib/tsikol/cli/templates/Gemfile.erb +10 -0
- data/lib/tsikol/cli/templates/README.md.erb +38 -0
- data/lib/tsikol/cli/templates/gitignore.erb +49 -0
- data/lib/tsikol/cli/templates/prompt.rb.erb +53 -0
- data/lib/tsikol/cli/templates/resource.rb.erb +29 -0
- data/lib/tsikol/cli/templates/server.rb.erb +24 -0
- data/lib/tsikol/cli/templates/tool.rb.erb +60 -0
- data/lib/tsikol/cli.rb +203 -0
- data/lib/tsikol/error_handler.rb +141 -0
- data/lib/tsikol/health.rb +198 -0
- data/lib/tsikol/http_transport.rb +72 -0
- data/lib/tsikol/lifecycle.rb +149 -0
- data/lib/tsikol/middleware.rb +168 -0
- data/lib/tsikol/prompt.rb +101 -0
- data/lib/tsikol/resource.rb +53 -0
- data/lib/tsikol/router.rb +190 -0
- data/lib/tsikol/server.rb +660 -0
- data/lib/tsikol/stdio_transport.rb +108 -0
- data/lib/tsikol/test_helpers.rb +261 -0
- data/lib/tsikol/tool.rb +111 -0
- data/lib/tsikol/version.rb +5 -0
- data/lib/tsikol.rb +72 -0
- metadata +219 -0
@@ -0,0 +1,462 @@
|
|
1
|
+
# Getting Started with Tsikol
|
2
|
+
|
3
|
+
Welcome to Tsikol! This guide will help you create your first MCP (Model Context Protocol) server in Ruby.
|
4
|
+
|
5
|
+
## Table of Contents
|
6
|
+
|
7
|
+
1. [Installation](#installation)
|
8
|
+
2. [Quick Start](#quick-start)
|
9
|
+
3. [Understanding MCP](#understanding-mcp)
|
10
|
+
4. [CLI Usage](#cli-usage)
|
11
|
+
5. [Basic Concepts](#basic-concepts)
|
12
|
+
6. [Your First Server](#your-first-server)
|
13
|
+
7. [Testing Your Server](#testing-your-server)
|
14
|
+
8. [Next Steps](#next-steps)
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
### Prerequisites
|
19
|
+
|
20
|
+
- Ruby 3.0 or higher
|
21
|
+
- Bundler gem
|
22
|
+
|
23
|
+
### Install Tsikol
|
24
|
+
|
25
|
+
```bash
|
26
|
+
gem install tsikol
|
27
|
+
```
|
28
|
+
|
29
|
+
Or add to your Gemfile:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
gem 'tsikol'
|
33
|
+
```
|
34
|
+
|
35
|
+
## Quick Start
|
36
|
+
|
37
|
+
Create a new MCP server in under a minute:
|
38
|
+
|
39
|
+
```bash
|
40
|
+
# Create a new project
|
41
|
+
tsikol new my-mcp-server
|
42
|
+
cd my-mcp-server
|
43
|
+
|
44
|
+
# Install dependencies
|
45
|
+
bundle install
|
46
|
+
|
47
|
+
# Run the server
|
48
|
+
ruby server.rb
|
49
|
+
```
|
50
|
+
|
51
|
+
## Understanding MCP
|
52
|
+
|
53
|
+
### What is MCP?
|
54
|
+
|
55
|
+
The Model Context Protocol (MCP) is a standard for communication between AI assistants and external tools. It enables:
|
56
|
+
|
57
|
+
- **Tools**: Functions the AI can call
|
58
|
+
- **Resources**: Data the AI can access
|
59
|
+
- **Prompts**: Reusable AI configurations
|
60
|
+
- **Completion**: Intelligent autocomplete
|
61
|
+
- **Sampling**: AI text generation capabilities
|
62
|
+
|
63
|
+
### How It Works
|
64
|
+
|
65
|
+
```
|
66
|
+
┌─────────────┐ MCP Protocol ┌─────────────┐
|
67
|
+
│ AI Client │ ◄──────────────────► │ MCP Server │
|
68
|
+
│ (Claude, │ │ (Your Ruby │
|
69
|
+
│ ChatGPT) │ │ Server) │
|
70
|
+
└─────────────┘ └─────────────┘
|
71
|
+
```
|
72
|
+
|
73
|
+
## CLI Usage
|
74
|
+
|
75
|
+
### Create a New Project
|
76
|
+
|
77
|
+
```bash
|
78
|
+
tsikol new PROJECT_NAME [OPTIONS]
|
79
|
+
|
80
|
+
# Examples
|
81
|
+
tsikol new weather-server
|
82
|
+
tsikol new code-assistant --git
|
83
|
+
tsikol new file-manager --test minitest
|
84
|
+
```
|
85
|
+
|
86
|
+
Options:
|
87
|
+
- `--git` / `--no-git` - Initialize git repository (default: true)
|
88
|
+
- `--test [framework]` - Testing framework: minitest, rspec, none (default: minitest)
|
89
|
+
|
90
|
+
### Generate Components
|
91
|
+
|
92
|
+
```bash
|
93
|
+
# Generate a new tool
|
94
|
+
tsikol generate tool process_file path:string operation:string
|
95
|
+
|
96
|
+
# Generate a resource
|
97
|
+
tsikol generate resource system_status
|
98
|
+
|
99
|
+
# Generate a prompt
|
100
|
+
tsikol generate prompt code_review language:string code:string
|
101
|
+
|
102
|
+
# Short alias
|
103
|
+
tsikol g tool my_tool param1:type param2:type
|
104
|
+
```
|
105
|
+
|
106
|
+
The generators automatically:
|
107
|
+
- Create the component file
|
108
|
+
- Add proper requires to server.rb
|
109
|
+
- Register the component with the server
|
110
|
+
|
111
|
+
## Basic Concepts
|
112
|
+
|
113
|
+
### Tools
|
114
|
+
|
115
|
+
Tools are functions that AI can call:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
tool "greet" do |name:|
|
119
|
+
"Hello, #{name}!"
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
### Resources
|
124
|
+
|
125
|
+
Resources provide read-only data:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
resource "version" do
|
129
|
+
"1.0.0"
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
### Prompts
|
134
|
+
|
135
|
+
Prompts configure AI behavior:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
prompt "translator" do |text:, language:|
|
139
|
+
[
|
140
|
+
{
|
141
|
+
role: "system",
|
142
|
+
content: { type: "text", text: "Translate to #{language}" }
|
143
|
+
},
|
144
|
+
{
|
145
|
+
role: "user",
|
146
|
+
content: { type: "text", text: text }
|
147
|
+
}
|
148
|
+
]
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
## Your First Server
|
153
|
+
|
154
|
+
Let's build a simple MCP server step by step.
|
155
|
+
|
156
|
+
### 1. Create the Project
|
157
|
+
|
158
|
+
```bash
|
159
|
+
tsikol new hello-mcp
|
160
|
+
cd hello-mcp
|
161
|
+
```
|
162
|
+
|
163
|
+
### 2. Define a Tool
|
164
|
+
|
165
|
+
```bash
|
166
|
+
tsikol generate tool greeting name:string style:string
|
167
|
+
```
|
168
|
+
|
169
|
+
Edit `app/tools/greeting.rb`:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
class Greeting < Tsikol::Tool
|
173
|
+
description "Generate personalized greetings"
|
174
|
+
|
175
|
+
parameter :name do
|
176
|
+
type :string
|
177
|
+
required
|
178
|
+
description "Person's name"
|
179
|
+
end
|
180
|
+
|
181
|
+
parameter :style do
|
182
|
+
type :string
|
183
|
+
optional
|
184
|
+
default "friendly"
|
185
|
+
enum ["friendly", "formal", "casual"]
|
186
|
+
description "Greeting style"
|
187
|
+
end
|
188
|
+
|
189
|
+
def execute(name:, style: "friendly")
|
190
|
+
case style
|
191
|
+
when "friendly"
|
192
|
+
"Hey #{name}! How's it going?"
|
193
|
+
when "formal"
|
194
|
+
"Good day, #{name}. I hope you are well."
|
195
|
+
when "casual"
|
196
|
+
"Yo #{name}, what's up?"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
202
|
+
### 3. Add a Resource
|
203
|
+
|
204
|
+
```bash
|
205
|
+
tsikol generate resource server_info
|
206
|
+
```
|
207
|
+
|
208
|
+
Edit `app/resources/server_info.rb`:
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
class ServerInfo < Tsikol::Resource
|
212
|
+
uri "server/info"
|
213
|
+
description "Information about this server"
|
214
|
+
|
215
|
+
def read
|
216
|
+
{
|
217
|
+
name: "Hello MCP Server",
|
218
|
+
version: "1.0.0",
|
219
|
+
author: "Your Name",
|
220
|
+
capabilities: ["greetings", "server info"]
|
221
|
+
}.to_json
|
222
|
+
end
|
223
|
+
end
|
224
|
+
```
|
225
|
+
|
226
|
+
### 4. Create a Prompt
|
227
|
+
|
228
|
+
```bash
|
229
|
+
tsikol generate prompt friendly_assistant topic:string
|
230
|
+
```
|
231
|
+
|
232
|
+
Edit `app/prompts/friendly_assistant.rb`:
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
class FriendlyAssistant < Tsikol::Prompt
|
236
|
+
name "friendly_assistant"
|
237
|
+
description "A helpful and friendly AI assistant"
|
238
|
+
|
239
|
+
argument :topic do
|
240
|
+
type :string
|
241
|
+
required
|
242
|
+
description "What to help with"
|
243
|
+
end
|
244
|
+
|
245
|
+
def get_messages(topic:)
|
246
|
+
[
|
247
|
+
{
|
248
|
+
role: "system",
|
249
|
+
content: {
|
250
|
+
type: "text",
|
251
|
+
text: "You are a friendly and helpful assistant. Be concise but warm."
|
252
|
+
}
|
253
|
+
},
|
254
|
+
{
|
255
|
+
role: "user",
|
256
|
+
content: {
|
257
|
+
type: "text",
|
258
|
+
text: "I need help with: #{topic}"
|
259
|
+
}
|
260
|
+
}
|
261
|
+
]
|
262
|
+
end
|
263
|
+
end
|
264
|
+
```
|
265
|
+
|
266
|
+
### 5. Configure the Server
|
267
|
+
|
268
|
+
The generated `server.rb` already includes your components:
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
#!/usr/bin/env ruby
|
272
|
+
|
273
|
+
require 'bundler/setup'
|
274
|
+
require 'tsikol'
|
275
|
+
|
276
|
+
# Require all components
|
277
|
+
Dir.glob('app/**/*.rb').each { |file| require_relative file }
|
278
|
+
|
279
|
+
Tsikol.start(name: "hello-mcp") do
|
280
|
+
# Components are auto-registered by the generator
|
281
|
+
tool Greeting
|
282
|
+
resource ServerInfo
|
283
|
+
prompt FriendlyAssistant
|
284
|
+
|
285
|
+
# Enable features
|
286
|
+
completion true
|
287
|
+
sampling true
|
288
|
+
|
289
|
+
# Add middleware
|
290
|
+
use Tsikol::LoggingMiddleware, level: :info
|
291
|
+
end
|
292
|
+
```
|
293
|
+
|
294
|
+
## Testing Your Server
|
295
|
+
|
296
|
+
### 1. Manual Testing
|
297
|
+
|
298
|
+
Run your server:
|
299
|
+
|
300
|
+
```bash
|
301
|
+
ruby server.rb
|
302
|
+
```
|
303
|
+
|
304
|
+
The server listens on stdin/stdout for MCP protocol messages.
|
305
|
+
|
306
|
+
### 2. Using MCP Inspector
|
307
|
+
|
308
|
+
Install the MCP Inspector:
|
309
|
+
|
310
|
+
```bash
|
311
|
+
npm install -g @modelcontextprotocol/inspector
|
312
|
+
```
|
313
|
+
|
314
|
+
Run the inspector:
|
315
|
+
|
316
|
+
```bash
|
317
|
+
mcp-inspector ruby server.rb
|
318
|
+
```
|
319
|
+
|
320
|
+
Visit http://localhost:5173 to interact with your server.
|
321
|
+
|
322
|
+
### 3. Writing Tests
|
323
|
+
|
324
|
+
Create `test/tools/greeting_test.rb`:
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
require_relative '../test_helper'
|
328
|
+
|
329
|
+
class GreetingTest < TsikolTest
|
330
|
+
def setup
|
331
|
+
super
|
332
|
+
@server.register_tool_instance(Greeting.new)
|
333
|
+
@client.initialize_connection
|
334
|
+
end
|
335
|
+
|
336
|
+
def test_friendly_greeting
|
337
|
+
response = @client.call_tool("greeting", {
|
338
|
+
"name" => "Alice",
|
339
|
+
"style" => "friendly"
|
340
|
+
})
|
341
|
+
|
342
|
+
assert_successful_response(response)
|
343
|
+
assert_match /Hey Alice/, response.dig(:result, :content, 0, :text)
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_formal_greeting
|
347
|
+
response = @client.call_tool("greeting", {
|
348
|
+
"name" => "Dr. Smith",
|
349
|
+
"style" => "formal"
|
350
|
+
})
|
351
|
+
|
352
|
+
assert_successful_response(response)
|
353
|
+
assert_match /Good day, Dr. Smith/, response.dig(:result, :content, 0, :text)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
```
|
357
|
+
|
358
|
+
Run tests:
|
359
|
+
|
360
|
+
```bash
|
361
|
+
bundle exec rake test
|
362
|
+
```
|
363
|
+
|
364
|
+
## Connecting to AI Clients
|
365
|
+
|
366
|
+
### Claude Desktop
|
367
|
+
|
368
|
+
Add to Claude's configuration:
|
369
|
+
|
370
|
+
```json
|
371
|
+
{
|
372
|
+
"mcpServers": {
|
373
|
+
"hello-mcp": {
|
374
|
+
"command": "ruby",
|
375
|
+
"args": ["/path/to/hello-mcp/server.rb"],
|
376
|
+
"env": {}
|
377
|
+
}
|
378
|
+
}
|
379
|
+
}
|
380
|
+
```
|
381
|
+
|
382
|
+
### Other Clients
|
383
|
+
|
384
|
+
Most MCP clients support similar configuration. Provide:
|
385
|
+
- Command: `ruby`
|
386
|
+
- Arguments: `["/full/path/to/server.rb"]`
|
387
|
+
- Any required environment variables
|
388
|
+
|
389
|
+
## Common Patterns
|
390
|
+
|
391
|
+
### Environment Variables
|
392
|
+
|
393
|
+
```ruby
|
394
|
+
# In server.rb
|
395
|
+
Tsikol.start(name: "my-server") do
|
396
|
+
# Use environment variables for configuration
|
397
|
+
if api_key = ENV['API_KEY']
|
398
|
+
metadata api_key: api_key[0..5] + "..."
|
399
|
+
end
|
400
|
+
end
|
401
|
+
```
|
402
|
+
|
403
|
+
### Error Handling
|
404
|
+
|
405
|
+
```ruby
|
406
|
+
class SafeTool < Tsikol::Tool
|
407
|
+
def execute(input:)
|
408
|
+
validate_input!(input)
|
409
|
+
process(input)
|
410
|
+
rescue ValidationError => e
|
411
|
+
"Validation failed: #{e.message}"
|
412
|
+
rescue => e
|
413
|
+
log :error, "Unexpected error", error: e.message
|
414
|
+
"An error occurred. Please try again."
|
415
|
+
end
|
416
|
+
end
|
417
|
+
```
|
418
|
+
|
419
|
+
### Logging
|
420
|
+
|
421
|
+
```ruby
|
422
|
+
class VerboseTool < Tsikol::Tool
|
423
|
+
def execute(data:)
|
424
|
+
log :info, "Processing started", size: data.size
|
425
|
+
|
426
|
+
result = process_data(data)
|
427
|
+
|
428
|
+
log :info, "Processing complete", result_size: result.size
|
429
|
+
|
430
|
+
result
|
431
|
+
end
|
432
|
+
end
|
433
|
+
```
|
434
|
+
|
435
|
+
## Next Steps
|
436
|
+
|
437
|
+
Now that you have a working MCP server:
|
438
|
+
|
439
|
+
1. **Learn More**:
|
440
|
+
- [Tools Guide](tools.md) - Deep dive into tools
|
441
|
+
- [Resources Guide](resources.md) - Managing data
|
442
|
+
- [Prompts Guide](prompts.md) - AI configurations
|
443
|
+
- [Middleware Guide](middleware.md) - Cross-cutting concerns
|
444
|
+
|
445
|
+
2. **Explore Examples**:
|
446
|
+
- [Echo Server](../examples/echo-server.md) - Simple example
|
447
|
+
- [Weather Service](../examples/weather-service.md) - API integration
|
448
|
+
- [Code Assistant](../examples/code-assistant.md) - Complex tools
|
449
|
+
|
450
|
+
3. **Advanced Topics**:
|
451
|
+
- [Testing Guide](testing.md) - Comprehensive testing
|
452
|
+
- [Error Handling](../cookbook/error-handling.md) - Robust servers
|
453
|
+
- [Authentication](../cookbook/authentication.md) - Secure servers
|
454
|
+
|
455
|
+
## Getting Help
|
456
|
+
|
457
|
+
- **Documentation**: Read through the guides in this folder
|
458
|
+
- **Examples**: Check the [examples](../examples/) directory
|
459
|
+
- **Issues**: Report bugs on [GitHub](https://github.com/your-username/tsikol)
|
460
|
+
- **Community**: Join our Discord/Slack (if applicable)
|
461
|
+
|
462
|
+
Happy building with Tsikol! 🚀
|