mcp 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 451bdb587fa89621924916d7cc137cf44a3a2293cf7803c3c6af1d97fb57332a
4
- data.tar.gz: 3175f6a5d60426d5441b99b2bbf6d50b90d31daa9b713796029547f5efc6ab6a
3
+ metadata.gz: fa42259e96ff9b07eb17a7e65ec9ca1324a1cce6f969295a4cb452872302aee9
4
+ data.tar.gz: f353de6d9331617ae6bf14f559b6de94e45885ce16feabbb23f65996dc8a850f
5
5
  SHA512:
6
- metadata.gz: 4b9e312c047ebc31d0826ec2520e14fef34fd0a23f42d9bf849f4a64b8cdb924341aa8a431aab497824849da476de5b8b2d55ad3b3996b9871e04b9022161aa3
7
- data.tar.gz: 772762d9cf650278dd0756867a995e57e13366e1a4a2a5b306433d8d9246e8bed2aadb00e057d4f31a521603dab6f8fadcbcdfc9650806c79d9881e2e1913acb
6
+ metadata.gz: 7b19b451b27926590498eb8320088cf8737c8b20e1897088f7a033e33fa8fec976c88c89e80d9e78d96202ae142e02c1698cc6ece52e9240085ad25b7fd5d4ac
7
+ data.tar.gz: 88f67864aecba8e4b475a53ba49a8651a10f8909c3c7e07138603ce4ea2c489580856494519a7cc6e7e6803e47bb99c38ae32a7802cb11fa268b5c18f9c40cb3
@@ -7,13 +7,17 @@ jobs:
7
7
  strategy:
8
8
  matrix:
9
9
  entry:
10
- - { ruby: 3.2, allowed-failure: false }
11
- - { ruby: 3.3, allowed-failure: false }
12
- - { ruby: 3.4, allowed-failure: false }
13
- - { ruby: head, allowed-failure: true }
10
+ - { ruby: '2.7', allowed-failure: false }
11
+ - { ruby: '3.0', allowed-failure: false }
12
+ - { ruby: '3.1', allowed-failure: false }
13
+ - { ruby: '3.2', allowed-failure: false }
14
+ - { ruby: '3.3', allowed-failure: false }
15
+ - { ruby: '3.4', allowed-failure: false }
16
+ - { ruby: '4.0', allowed-failure: false }
17
+ - { ruby: 'head', allowed-failure: true }
14
18
  name: Test Ruby ${{ matrix.entry.ruby }}
15
19
  steps:
16
- - uses: actions/checkout@v5
20
+ - uses: actions/checkout@v6
17
21
  - uses: ruby/setup-ruby@v1
18
22
  with:
19
23
  ruby-version: ${{ matrix.entry.ruby }}
@@ -25,9 +29,20 @@ jobs:
25
29
  runs-on: ubuntu-latest
26
30
  name: RuboCop
27
31
  steps:
28
- - uses: actions/checkout@v5
32
+ - uses: actions/checkout@v6
29
33
  - uses: ruby/setup-ruby@v1
30
34
  with:
31
- ruby-version: 3.2 # Specify the oldest supported Ruby version.
35
+ ruby-version: 4.0 # Specify the latest supported Ruby version.
32
36
  bundler-cache: true
33
37
  - run: bundle exec rake rubocop
38
+
39
+ yard:
40
+ runs-on: ubuntu-latest
41
+ name: YARD Documentation
42
+ steps:
43
+ - uses: actions/checkout@v6
44
+ - uses: ruby/setup-ruby@v1
45
+ with:
46
+ ruby-version: 4.0 # Specify the latest supported Ruby version.
47
+ bundler-cache: true
48
+ - run: bundle exec yard --no-output
@@ -16,10 +16,42 @@ jobs:
16
16
  id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
17
17
  contents: write # IMPORTANT: this permission is required for `rake release` to push the release tag
18
18
  steps:
19
- - uses: actions/checkout@v5
19
+ - uses: actions/checkout@v6
20
20
  - name: Set up Ruby
21
21
  uses: ruby/setup-ruby@v1
22
22
  with:
23
23
  bundler-cache: true
24
- ruby-version: 3.4
24
+ ruby-version: 4.0
25
25
  - uses: rubygems/release-gem@v1
26
+
27
+ publish_gh_pages:
28
+ if: github.repository_owner == 'modelcontextprotocol'
29
+ name: Publish Documentation to GitHub Pages
30
+ runs-on: ubuntu-latest
31
+ needs: [publish_gem]
32
+
33
+ permissions:
34
+ contents: write
35
+
36
+ steps:
37
+ - uses: actions/checkout@v6
38
+ with:
39
+ fetch-depth: 0 # Fetch all history for all branches and tags
40
+
41
+ - name: Configure Git
42
+ run: |
43
+ git config --global user.name "github-actions[bot]"
44
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
45
+
46
+ - name: Get version tag
47
+ id: version
48
+ run: |
49
+ git fetch --tags
50
+ TAG=$(git describe --tags --exact-match HEAD)
51
+ echo "tag=${TAG}" >> $GITHUB_OUTPUT
52
+
53
+ - name: Generate GitHub Pages
54
+ run: ./bin/generate-gh-pages.sh ${{ steps.version.outputs.tag }}
55
+
56
+ - name: Push to gh-pages
57
+ run: git push origin gh-pages
data/.rubocop.yml CHANGED
@@ -5,6 +5,9 @@ plugins:
5
5
  - rubocop-minitest
6
6
  - rubocop-rake
7
7
 
8
+ AllCops:
9
+ TargetRubyVersion: 2.7
10
+
8
11
  Gemspec/DevelopmentDependencies:
9
12
  Enabled: true
10
13
 
data/AGENTS.md CHANGED
@@ -6,9 +6,9 @@ This is the official Ruby SDK for the Model Context Protocol (MCP), implementing
6
6
 
7
7
  ## Dev environment setup
8
8
 
9
- - Ruby 3.2.0+ required
9
+ - Ruby 3.2.0+ required to run the full test suite, including all Sorbet-related features
10
10
  - Run `bundle install` to install dependencies
11
- - Dependencies: `json_rpc_handler` ~> 0.1, `json-schema` >= 4.1
11
+ - Dependencies: `json-schema` >= 4.1 - Schema validation
12
12
 
13
13
  ## Build and test commands
14
14
 
@@ -100,20 +100,8 @@ This is the official Ruby SDK for the Model Context Protocol (MCP), implementing
100
100
  - `server_context` hash passed through tool/prompt calls for request-specific data
101
101
  - Methods can accept `server_context:` keyword argument for accessing context
102
102
 
103
- ### Dependencies
104
-
105
- - `json_rpc_handler` ~> 0.1 - JSON-RPC 2.0 message handling
106
- - `json-schema` >= 4.1 - Schema validation
107
- - Ruby 3.2.0+ required
108
-
109
103
  ### Integration patterns
110
104
 
111
105
  - **Rails controllers**: Use `server.handle_json(request.body.read)` for HTTP endpoints
112
106
  - **Command-line tools**: Use `StdioTransport.new(server).open` for CLI applications
113
107
  - **HTTP services**: Use `StreamableHttpTransport` for web-based servers
114
-
115
- ### Component definition patterns
116
-
117
- 1. **Class inheritance**: `class MyTool < MCP::Tool`
118
- 2. **Define methods**: `MCP::Tool.define(name: "my_tool") { ... }`
119
- 3. **Server registration**: `server.define_tool(name: "my_tool") { ... }`
data/CHANGELOG.md CHANGED
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-01-11
11
+
12
+ ### Added
13
+
14
+ - Protocol specification version "2025-11-25" support (#184)
15
+ - `icons` parameter support (#205)
16
+ - `websiteUrl` parameter in `serverInfo` (#188)
17
+ - `description` parameter in `serverInfo` (#201)
18
+ - `additionalProperties` support for schema validation (#198)
19
+ - "Draft" protocol version to supported versions (#179)
20
+ - `stateless` mode for high availability (#101)
21
+ - Exception messages for tool call errors (#194)
22
+ - Elicitation skeleton (#178)
23
+ - `prompts/list` and `prompts/get` support to client (#163)
24
+ - Accept header validation for HTTP client transport (#207)
25
+ - Ruby 2.7 - Ruby 3.1 support (#206)
26
+
27
+ ### Changed
28
+
29
+ - Make tool names stricter (#204)
30
+
31
+ ### Fixed
32
+
33
+ - Symlink path comparison in schema validation (#193)
34
+ - Duplicate tool names across namespaces now raise an error (#199)
35
+ - Tool error handling to follow MCP spec (#165)
36
+ - XSS vulnerability in json_rpc_handler (#175)
37
+
10
38
  ## [0.4.0] - 2025-10-15
11
39
 
12
40
  ### Added
data/Gemfile CHANGED
@@ -8,16 +8,18 @@ gemspec
8
8
  # Specify development dependencies below
9
9
  gem "rubocop-minitest", require: false
10
10
  gem "rubocop-rake", require: false
11
- gem "rubocop-shopify", require: false
11
+ gem "rubocop-shopify", ">= 2.18", require: false if RUBY_VERSION >= "3.1"
12
12
 
13
13
  gem "puma", ">= 5.0.0"
14
- gem "rack", ">= 2.0.0"
15
14
  gem "rackup", ">= 2.1.0"
16
15
 
17
16
  gem "activesupport"
18
- gem "debug"
17
+ # Fix io-console install error when Ruby 3.0.
18
+ gem "debug" if RUBY_VERSION >= "3.1"
19
19
  gem "rake", "~> 13.0"
20
- gem "sorbet-static-and-runtime"
20
+ gem "sorbet-static-and-runtime" if RUBY_VERSION >= "3.0"
21
+ gem "yard", "~> 0.9"
22
+ gem "yard-sorbet", "~> 0.9" if RUBY_VERSION >= "3.1"
21
23
 
22
24
  group :test do
23
25
  gem "faraday", ">= 2.0"
data/README.md CHANGED
@@ -131,7 +131,10 @@ Notifications follow the JSON-RPC 2.0 specification and use these method names:
131
131
 
132
132
  ```ruby
133
133
  server = MCP::Server.new(name: "my_server")
134
+
135
+ # Default Streamable HTTP - session oriented
134
136
  transport = MCP::Server::Transports::StreamableHTTPTransport.new(server)
137
+
135
138
  server.transport = transport
136
139
 
137
140
  # When tools change, notify clients
@@ -139,18 +142,28 @@ server.define_tool(name: "new_tool") { |**args| { result: "ok" } }
139
142
  server.notify_tools_list_changed
140
143
  ```
141
144
 
142
- ### Unsupported Features ( to be implemented in future versions )
145
+ You can use Stateless Streamable HTTP, where notifications are not supported and all calls are request/response interactions.
146
+ This mode allows for easy multi-node deployment.
147
+ Set `stateless: true` in `MCP::Server::Transports::StreamableHTTPTransport.new` (`stateless` defaults to `false`):
148
+
149
+ ```ruby
150
+ # Stateless Streamable HTTP - session-less
151
+ transport = MCP::Server::Transports::StreamableHTTPTransport.new(server, stateless: true)
152
+ ```
153
+
154
+ ### Unsupported Features (to be implemented in future versions)
143
155
 
144
156
  - Log Level
145
157
  - Resource subscriptions
146
158
  - Completions
159
+ - Elicitation
147
160
 
148
161
  ### Usage
149
162
 
150
163
  #### Rails Controller
151
164
 
152
165
  When added to a Rails controller on a route that handles POST requests, your server will be compliant with non-streaming
153
- [Streamable HTTP](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) transport
166
+ [Streamable HTTP](https://modelcontextprotocol.io/specification/latest/basic/transports#streamable-http) transport
154
167
  requests.
155
168
 
156
169
  You can use the `Server#handle_json` method to handle requests.
@@ -160,7 +173,7 @@ class ApplicationController < ActionController::Base
160
173
  def index
161
174
  server = MCP::Server.new(
162
175
  name: "my_server",
163
- title: "Example Server Display Name", # WARNING: This is a `Draft` and is not supported in the `Version 2025-06-18 (latest)` specification.
176
+ title: "Example Server Display Name",
164
177
  version: "1.0.0",
165
178
  instructions: "Use the tools of this server as a last resort",
166
179
  tools: [SomeTool, AnotherTool],
@@ -336,6 +349,9 @@ configuration = MCP::Configuration.new(protocol_version: "2024-11-05")
336
349
  MCP::Server.new(name: "test_server", configuration: configuration)
337
350
  ```
338
351
 
352
+ If no protocol version is specified, the latest stable version will be applied by default.
353
+ The latest stable version includes new features from the [draft version](https://modelcontextprotocol.io/specification/draft).
354
+
339
355
  This will make all new server instances use the specified protocol version instead of the default version. The protocol version can be reset to the default by setting it to `nil`:
340
356
 
341
357
  ```ruby
@@ -368,7 +384,7 @@ If no exception reporter is configured, a default no-op reporter is used that si
368
384
 
369
385
  ### Tools
370
386
 
371
- MCP spec includes [Tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools) which provide functionality to LLM apps.
387
+ MCP spec includes [Tools](https://modelcontextprotocol.io/specification/latest/server/tools) which provide functionality to LLM apps.
372
388
 
373
389
  This gem provides a `MCP::Tool` class that can be used to create tools in three ways:
374
390
 
@@ -376,7 +392,7 @@ This gem provides a `MCP::Tool` class that can be used to create tools in three
376
392
 
377
393
  ```ruby
378
394
  class MyTool < MCP::Tool
379
- title "My Tool" # WARNING: This is a `Draft` and is not supported in the `Version 2025-06-18 (latest)` specification.
395
+ title "My Tool"
380
396
  description "This tool performs specific functionality..."
381
397
  input_schema(
382
398
  properties: {
@@ -413,13 +429,13 @@ tool = MyTool
413
429
  ```ruby
414
430
  tool = MCP::Tool.define(
415
431
  name: "my_tool",
416
- title: "My Tool", # WARNING: This is a `Draft` and is not supported in the `Version 2025-06-18 (latest)` specification.
432
+ title: "My Tool",
417
433
  description: "This tool performs specific functionality...",
418
434
  annotations: {
419
435
  read_only_hint: true,
420
436
  title: "My Tool"
421
437
  }
422
- ) do |args, server_context|
438
+ ) do |args, server_context:|
423
439
  MCP::Tool::Response.new([{ type: "text", text: "OK" }])
424
440
  end
425
441
  ```
@@ -435,7 +451,7 @@ server.define_tool(
435
451
  title: "My Tool",
436
452
  read_only_hint: true
437
453
  }
438
- ) do |args, server_context|
454
+ ) do |args, server_context:|
439
455
  Tool::Response.new([{ type: "text", text: "OK" }])
440
456
  end
441
457
  ```
@@ -525,7 +541,7 @@ tool = MCP::Tool.define(
525
541
  },
526
542
  required: ["mean", "median", "count"]
527
543
  }
528
- ) do |args, server_context|
544
+ ) do |args, server_context:|
529
545
  # Calculate statistics and validate against schema
530
546
  MCP::Tool::Response.new([{ type: "text", text: "Statistics calculated" }])
531
547
  end
@@ -551,7 +567,7 @@ Output schema may also describe an array of objects:
551
567
  class WeatherTool < MCP::Tool
552
568
  output_schema(
553
569
  type: "array",
554
- item: {
570
+ items: {
555
571
  properties: {
556
572
  temperature: { type: "number" },
557
573
  condition: { type: "string" },
@@ -566,7 +582,7 @@ end
566
582
  Please note: in this case, you must provide `type: "array"`. The default type
567
583
  for output schemas is `object`.
568
584
 
569
- MCP spec for the [Output Schema](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema) specifies that:
585
+ MCP spec for the [Output Schema](https://modelcontextprotocol.io/specification/latest/server/tools#output-schema) specifies that:
570
586
 
571
587
  - **Server Validation**: Servers MUST provide structured results that conform to the output schema
572
588
  - **Client Validation**: Clients SHOULD validate structured results against the output schema
@@ -582,10 +598,10 @@ Tools can return structured data alongside text content using the `structured_co
582
598
  The structured content will be included in the JSON-RPC response as the `structuredContent` field.
583
599
 
584
600
  ```ruby
585
- class APITool < MCP::Tool
601
+ class WeatherTool < MCP::Tool
586
602
  description "Get current weather and return structured data"
587
603
 
588
- def self.call(endpoint:, server_context:)
604
+ def self.call(location:, units: "celsius", server_context:)
589
605
  # Call weather API and structure the response
590
606
  api_response = WeatherAPI.fetch(location, units)
591
607
  weather_data = {
@@ -607,9 +623,35 @@ class APITool < MCP::Tool
607
623
  end
608
624
  ```
609
625
 
626
+ ### Tool Responses with Errors
627
+
628
+ Tools can return error information alongside text content using the `error` parameter.
629
+
630
+ The error will be included in the JSON-RPC response as the `isError` field.
631
+
632
+ ```ruby
633
+ class WeatherTool < MCP::Tool
634
+ description "Get current weather and return structured data"
635
+
636
+ def self.call(server_context:)
637
+ # Do something here
638
+ content = {}
639
+
640
+ MCP::Tool::Response.new(
641
+ [{
642
+ type: "text",
643
+ text: content.to_json
644
+ }],
645
+ structured_content: content,
646
+ error: true
647
+ )
648
+ end
649
+ end
650
+ ```
651
+
610
652
  ### Prompts
611
653
 
612
- MCP spec includes [Prompts](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts), which enable servers to define reusable prompt templates and workflows that clients can easily surface to users and LLMs.
654
+ MCP spec includes [Prompts](https://modelcontextprotocol.io/specification/latest/server/prompts), which enable servers to define reusable prompt templates and workflows that clients can easily surface to users and LLMs.
613
655
 
614
656
  The `MCP::Prompt` class provides three ways to create prompts:
615
657
 
@@ -618,7 +660,7 @@ The `MCP::Prompt` class provides three ways to create prompts:
618
660
  ```ruby
619
661
  class MyPrompt < MCP::Prompt
620
662
  prompt_name "my_prompt" # Optional - defaults to underscored class name
621
- title "My Prompt" # WARNING: This is a `Draft` and is not supported in the `Version 2025-06-18 (latest)` specification.
663
+ title "My Prompt"
622
664
  description "This prompt performs specific functionality..."
623
665
  arguments [
624
666
  MCP::Prompt::Argument.new(
@@ -657,7 +699,7 @@ prompt = MyPrompt
657
699
  ```ruby
658
700
  prompt = MCP::Prompt.define(
659
701
  name: "my_prompt",
660
- title: "My Prompt", # WARNING: This is a `Draft` and is not supported in the `Version 2025-06-18 (latest)` specification.
702
+ title: "My Prompt",
661
703
  description: "This prompt performs specific functionality...",
662
704
  arguments: [
663
705
  MCP::Prompt::Argument.new(
@@ -772,7 +814,7 @@ This is to avoid potential issues with metric cardinality
772
814
 
773
815
  ### Resources
774
816
 
775
- MCP spec includes [Resources](https://modelcontextprotocol.io/specification/2025-06-18/server/resources).
817
+ MCP spec includes [Resources](https://modelcontextprotocol.io/specification/latest/server/resources).
776
818
 
777
819
  ### Reading Resources
778
820
 
@@ -782,7 +824,7 @@ The `MCP::Resource` class provides a way to register resources with the server.
782
824
  resource = MCP::Resource.new(
783
825
  uri: "https://example.com/my_resource",
784
826
  name: "my-resource",
785
- title: "My Resource", # WARNING: This is a `Draft` and is not supported in the `Version 2025-06-18 (latest)` specification.
827
+ title: "My Resource",
786
828
  description: "Lorem ipsum dolor sit amet",
787
829
  mime_type: "text/html",
788
830
  )
@@ -815,7 +857,7 @@ The `MCP::ResourceTemplate` class provides a way to register resource templates
815
857
  resource_template = MCP::ResourceTemplate.new(
816
858
  uri_template: "https://example.com/my_resource_template",
817
859
  name: "my-resource-template",
818
- title: "My Resource Template", # WARNING: This is a `Draft` and is not supported in the `Version 2025-06-18 (latest)` specification.
860
+ title: "My Resource Template",
819
861
  description: "Lorem ipsum dolor sit amet",
820
862
  mime_type: "text/html",
821
863
  )
@@ -836,6 +878,8 @@ This class supports:
836
878
  - Tool invocation via the `tools/call` method (`MCP::Client#call_tools`)
837
879
  - Resource listing via the `resources/list` method (`MCP::Client#resources`)
838
880
  - Resource reading via the `resources/read` method (`MCP::Client#read_resources`)
881
+ - Prompt listing via the `prompts/list` method (`MCP::Client#prompts`)
882
+ - Prompt retrieval via the `prompts/get` method (`MCP::Client#get_prompt`)
839
883
  - Automatic JSON-RPC 2.0 message formatting
840
884
  - UUID request ID generation
841
885
 
@@ -924,15 +968,7 @@ The client provides a wrapper class for tools returned by the server:
924
968
 
925
969
  This class provides easy access to tool properties like name, description, input schema, and output schema.
926
970
 
927
- ## Releases
928
-
929
- This gem is published to [RubyGems.org](https://rubygems.org/gems/mcp)
930
-
931
- Releases are triggered by PRs to the `main` branch updating the version number in `lib/mcp/version.rb`.
932
-
933
- 1. **Update the version number** in `lib/mcp/version.rb`, following [semver](https://semver.org/)
934
- 1. **Update CHANGELOG.md**, backfilling the changes since the last release if necessary, and adding a new section for the new version, clearing out the Unreleased section
935
- 1. **Create a PR and get approval from a maintainer**
936
- 1. **Merge your PR to the main branch** - This will automatically trigger the release workflow via GitHub Actions
971
+ ## Documentation
937
972
 
938
- When changes are merged to the `main` branch, the GitHub Actions workflow (`.github/workflows/release.yml`) is triggered and the gem is published to RubyGems.
973
+ - [SDK API documentation](https://rubydoc.info/gems/mcp)
974
+ - [Model Context Protocol documentation](https://modelcontextprotocol.io)
data/RELEASE.md ADDED
@@ -0,0 +1,12 @@
1
+ ## Releases
2
+
3
+ This gem is published to [RubyGems.org](https://rubygems.org/gems/mcp)
4
+
5
+ Releases are triggered by PRs to the `main` branch updating the version number in `lib/mcp/version.rb`.
6
+
7
+ 1. **Update the version number** in `lib/mcp/version.rb`, following [semver](https://semver.org/)
8
+ 2. **Update CHANGELOG.md**, backfilling the changes since the last release if necessary, and adding a new section for the new version, clearing out the Unreleased section
9
+ 3. **Create a PR and get approval from a maintainer**
10
+ 4. **Merge your PR to the main branch** - This will automatically trigger the release workflow via GitHub Actions
11
+
12
+ When changes are merged to the `main` branch, the GitHub Actions workflow (`.github/workflows/release.yml`) is triggered and the gem is published to RubyGems.
@@ -0,0 +1,119 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Generates versioned documentation links and commits to gh-pages branch
5
+ #
6
+ # PURPOSE:
7
+ # This script generates a landing page with links to API documentation on
8
+ # RubyDoc.info for a specific version tag. This script is invoked by the
9
+ # publish-gh-pages job in the GitHub Actions workflow
10
+ # (.github/workflows/release.yml) when a release is published.
11
+ #
12
+ # HOW IT WORKS:
13
+ # - Creates isolated git worktrees for the specified tag and gh-pages branch
14
+ # - Copies static Jekyll template files from docs/
15
+ # - Generates _data/versions.yml with list of versions
16
+ # - Commits changes to gh-pages (does not push automatically)
17
+ #
18
+ # WORKFLOW:
19
+ # 1. Run this script with a tag name: `generate-gh-pages.sh v1.2.3`
20
+ # 2. Script generates docs and commits to local gh-pages branch
21
+ # 3. Push gh-pages branch to deploy: `git push origin gh-pages`
22
+
23
+ # Parse semantic version from tag name (ignoring arbitrary prefixes)
24
+ if [[ "${1}" =~ ([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?)$ ]]; then
25
+ VERSION="v${BASH_REMATCH[1]}"
26
+ else
27
+ echo "Error: Must specify a tag name that contains a valid semantic version"
28
+ echo "Usage: ${0} <tag-name>"
29
+ echo "Examples:"
30
+ echo " ${0} 1.2.3"
31
+ echo " ${0} v2.0.0-rc.1"
32
+ exit 1
33
+ fi
34
+
35
+ TAG_NAME="${1}"
36
+ REPO_ROOT="$(git rev-parse --show-toplevel)"
37
+
38
+ echo "Generating documentation for tag: ${TAG_NAME}"
39
+
40
+ # Create temporary directories for both worktrees
41
+ WORKTREE_DIR=$(mktemp -d)
42
+ GHPAGES_WORKTREE_DIR=$(mktemp -d)
43
+
44
+ # Set up trap to clean up both worktrees on exit
45
+ trap 'git worktree remove --force "${WORKTREE_DIR}" 2>/dev/null || true; \
46
+ git worktree remove --force "${GHPAGES_WORKTREE_DIR}" 2>/dev/null || true' EXIT
47
+
48
+ echo "Creating worktree for ${TAG_NAME}..."
49
+ git worktree add --quiet "${WORKTREE_DIR}" "${TAG_NAME}"
50
+
51
+ # Check if gh-pages branch exists
52
+ if git show-ref --verify --quiet refs/heads/gh-pages; then
53
+ echo "Creating worktree for existing gh-pages branch..."
54
+ git worktree add --quiet "${GHPAGES_WORKTREE_DIR}" gh-pages
55
+ elif git ls-remote --exit-code --heads origin gh-pages > /dev/null 2>&1; then
56
+ echo "Creating worktree for gh-pages branch from remote..."
57
+ git worktree add --quiet "${GHPAGES_WORKTREE_DIR}" -b gh-pages origin/gh-pages
58
+ else
59
+ echo "Creating worktree for new orphan gh-pages branch..."
60
+ git worktree add --quiet --detach "${GHPAGES_WORKTREE_DIR}"
61
+ git -C "${GHPAGES_WORKTREE_DIR}" checkout --orphan gh-pages
62
+ git -C "${GHPAGES_WORKTREE_DIR}" rm -rf . > /dev/null 2>&1 || true
63
+ fi
64
+
65
+ # Change to gh-pages worktree
66
+ cd "${GHPAGES_WORKTREE_DIR}"
67
+
68
+ # Determine if this tag is the latest version
69
+ echo "Determining if ${VERSION} is the latest version..."
70
+
71
+ # Get all existing version tags from the repository (reverse sorted, newest first)
72
+ ALL_VERSIONS=$(
73
+ git -C "${REPO_ROOT}" tag --list | \
74
+ sed -nE 's/^[^0-9]*([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?)$/v\1/p' | \
75
+ sort -Vr
76
+ )
77
+
78
+ # Get the latest version from all version tags
79
+ LATEST_VERSION=$(echo "${ALL_VERSIONS}" | head -n 1)
80
+
81
+ if [ "${VERSION}" = "${LATEST_VERSION}" ]; then
82
+ echo "${VERSION} is the latest version"
83
+ else
84
+ echo "${VERSION} is not the latest version (latest is ${LATEST_VERSION})"
85
+ fi
86
+
87
+ # Update custom documentation for latest version
88
+ if [ "${VERSION}" = "${LATEST_VERSION}" ]; then
89
+ echo "Updating custom documentation..."
90
+
91
+ # Clean up old custom docs from gh-pages root
92
+ echo "Cleaning gh-pages root..."
93
+ git ls-tree --name-only HEAD | xargs -r git rm -rf
94
+
95
+ # Copy custom docs from docs/ directory
96
+ echo "Copying custom docs from ${WORKTREE_DIR}/docs/..."
97
+ cp -r "${WORKTREE_DIR}/docs/." "${GHPAGES_WORKTREE_DIR}/"
98
+ fi
99
+
100
+ # Generate version data for Jekyll
101
+ echo "Generating _data/versions.yml..."
102
+ mkdir -p _data
103
+ echo "${ALL_VERSIONS}" | sed 's/^v/- /' > _data/versions.yml
104
+
105
+ # Stage all changes
106
+ git add .
107
+
108
+ # Commit if there are changes
109
+ if git diff --staged --quiet; then
110
+ echo "No changes to commit"
111
+ else
112
+ echo "Committing documentation for ${VERSION}..."
113
+ git commit -m "Add ${VERSION} docs"
114
+
115
+ echo "Documentation committed to gh-pages branch!"
116
+ echo "Push to remote to deploy to GitHub Pages"
117
+ fi
118
+
119
+ echo "Done!"
data/dev.yml CHANGED
@@ -27,5 +27,4 @@ commands:
27
27
  style:
28
28
  desc: Run rubocop
29
29
  aliases: [rubocop, lint]
30
- run: bin/rubocop
31
-
30
+ run: bin/rake rubocop
data/docs/_config.yml ADDED
@@ -0,0 +1,6 @@
1
+ # Use package name as site title
2
+ title: "MCP Ruby SDK"
3
+
4
+ # Include generated files and directories which may start with underscores
5
+ include:
6
+ - "_*"
data/docs/index.md ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ # Empty Jekyll front matter to enable Liquid templating (see {{ ... }} below)
3
+ ---
4
+
5
+ {% for version in site.data.versions -%}
6
+ - [v{{ version }}](https://rubydoc.info/gems/mcp/{{ version }})
7
+ {% endfor %}
@@ -0,0 +1,19 @@
1
+ ---
2
+ # Empty Jekyll front matter to enable Liquid templating (see {{ ... }} below)
3
+ ---
4
+
5
+ <!DOCTYPE html>
6
+ <html>
7
+ <head>
8
+ <meta charset="utf-8">
9
+ <title>Redirecting to latest documentation...</title>
10
+ <meta http-equiv="refresh" content="0; url=https://rubydoc.info/gems/mcp">
11
+ <link rel="canonical" href="https://rubydoc.info/gems/mcp">
12
+ </head>
13
+ <body>
14
+ <p>Redirecting to <a href="https://rubydoc.info/gems/mcp">latest documentation</a>...</p>
15
+ <script>
16
+ window.location.href = "https://rubydoc.info/gems/mcp";
17
+ </script>
18
+ </body>
19
+ </html>
@@ -2,7 +2,6 @@
2
2
 
3
3
  $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
4
4
  require "mcp"
5
- require "rack"
6
5
  require "rackup"
7
6
  require "json"
8
7
  require "logger"
@@ -2,7 +2,6 @@
2
2
 
3
3
  $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
4
4
  require "mcp"
5
- require "rack"
6
5
  require "rackup"
7
6
  require "json"
8
7
  require "logger"