hyperclient-mcp 0.1.0 → 0.2.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: 788205f7a40dcce22ef7e160e7077833c28666c7ad27f0564916a1d18e6a7679
4
- data.tar.gz: fead56f84529c880a3524e9b0ed732bf1838c6eb14db400b1b659904cd28e11a
3
+ metadata.gz: 1354eb080921be3ba1f7cb9403722f7206b7f1fbc1a720ccfe80a903642f4675
4
+ data.tar.gz: ed39ecbf6f6f92bfc9554916f4469874503259c05dea132c89e3942a40c1b135
5
5
  SHA512:
6
- metadata.gz: ca6f4fe3fcfb2ffaaeb03aae44736f1746da4b41fe22f8f0eb76fb12c9f70eb79a24b5411962b38497f0265649c0fb7b463ff103b35d1fac22140efaaeed985c
7
- data.tar.gz: e0fd1072626e0a35b370ab595edf0a81990aaed104e4afae01e9918ea7103d8e913303e55a696da933ebc6fafdae8738c91477512a73807de59f2e30ffe84265
6
+ metadata.gz: 6cd9503b583cd298b319d1309c954f67a6ba74255455be388e930a48bb3644ac8051e0134e957fafe113f8f6520e588900fb2162ee3e8ac84f0a835732cbecb4
7
+ data.tar.gz: befb7ebb79e55b542bba8795c1fb4c557309850a9c9673cec35309bff16673c2ba88f577f21fe9fc854d39e047fdbbfcf23d3946a2ba2e80f7778e786e6b8aed
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ### 0.2.0 (Next)
2
+
3
+ * Added a command-line `hyperclient-mcp` tool - [@dblock](https://github.com/dblock).
4
+ * Your contribution here.
5
+
1
6
  ### 0.1.0 (2025/09/12)
2
7
 
3
8
  * Initial public release - [@dblock](https://github.com/dblock).
data/README.md CHANGED
@@ -35,7 +35,39 @@ end
35
35
 
36
36
  ### Use Hyperclient MCP
37
37
 
38
- To turn any hypermedia API into an MCP, create an mcp wrapper and register its `resources` with FastMcp and mount it as usual.
38
+ #### Command Line
39
+
40
+ Start the Hyperclient MCP server for any existing API using the convenient command-line proxy.
41
+
42
+ ```bash
43
+ hyperclient-mcp --api https://sup2.playplay.io/api --header X-Access-Token=$TOKEN start
44
+ ```
45
+
46
+ Register with Claude.
47
+
48
+ ```bash
49
+ claude mcp add --transport sse local http://127.0.0.1:9292/mcp/sse
50
+ ```
51
+
52
+ Check that it was registered.
53
+
54
+ ```bash
55
+ $ claude mcp list
56
+ Checking MCP server health...
57
+ local: http://127.0.0.1:9292/mcp/sse (SSE) - ✓ Connected
58
+ ```
59
+
60
+ Run Claude, try asking a question.
61
+
62
+ ```bash
63
+ $ claude "use the local mcp to find the name of the team with ID 64124ac95d758400015faecf"
64
+
65
+ The team name is dblock.
66
+ ```
67
+
68
+ #### Programmatically
69
+
70
+ To turn any hypermedia API into an MCP in code, create an mcp wrapper and register its `resources` with FastMcp and mount it as usual.
39
71
 
40
72
  ```ruby
41
73
  hyperclient_mcp = Hyperclient::Mcp::Api.new(api)
@@ -46,9 +78,7 @@ mcp_server.register_resources(*hyperclient_mcp.resources)
46
78
  use FastMcp::Transports::RackTransport, mcp_server
47
79
  ```
48
80
 
49
- ### See It
50
-
51
- The MCP code in [examples/sup.playplay.io](examples/sup.playplay.io/) can be directly used with Claude.
81
+ For example, the MCP code in [examples/sup.playplay.io](examples/sup.playplay.io/) starts an MCP server using code similar to above, and can be directly used with Claude.
52
82
 
53
83
  ```bash
54
84
  bundle install
@@ -61,9 +91,9 @@ claude mcp add --transport sse local http://127.0.0.1:4567/mcp/sse
61
91
 
62
92
  ![](examples/sup.playplay.io/mcp.gif)
63
93
 
64
- ## Examples
94
+ ## More Examples
65
95
 
66
- See [examples/grape-with-roar](examples/grape-with-roar/) for a complete example.
96
+ See [examples/grape-with-roar](examples/grape-with-roar/) for a complete example that uses the [grape-with-roar demo project](https://github.com/ruby-grape/grape-with-roar).
67
97
 
68
98
  ## Upgrading
69
99
 
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyperclient
4
+ module Mcp
5
+ module Cli
6
+ class App
7
+ desc 'List resources.'
8
+ command 'resources' do |command|
9
+ command.action do |global, _options, _args|
10
+ global['mcp'].resources.each do |resource|
11
+ puts resource
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyperclient
4
+ module Mcp
5
+ module Cli
6
+ class App
7
+ desc 'Start an MCP server.'
8
+ command 'start' do |command|
9
+ command.flag 'h', 'host', desc: 'server host', type: String, default_value: '0.0.0.0'
10
+ command.flag 'p', 'port', desc: 'server port', type: Integer, default_value: 9292
11
+ command.flag 'n', 'name', desc: 'mcp server name', type: String, default_value: 'Hyperclient MCP'
12
+ command.flag 'v', 'version', desc: 'mcp server version', type: String, default_value: '0.0.1'
13
+ command.action do |global, options, _args|
14
+ require 'sinatra'
15
+ require 'puma'
16
+ require 'rack/handler/puma'
17
+
18
+ mcp_server = FastMcp::Server.new(name: options['name'], version: options['version'])
19
+ mcp_server.register_resources(*global['mcp'].resources)
20
+
21
+ app = Class.new(Sinatra::Base) do
22
+ set :environment, ENV.fetch('RACK_ENV', 'development')
23
+
24
+ use FastMcp::Transports::RackTransport, mcp_server
25
+
26
+ get '/' do
27
+ 'OK'
28
+ end
29
+ end
30
+
31
+ host = options['host'] || ENV.fetch('HOST', '0.0.0.0')
32
+ port = options['port'] || Integer(ENV.fetch('PORT', 9292))
33
+
34
+ Rack::Handler::Puma.run(app, Host: host, Port: port)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gli'
3
+ require 'hyperclient-mcp'
4
+
5
+ module Hyperclient
6
+ module Mcp
7
+ module Cli
8
+ class App
9
+ extend GLI::App
10
+
11
+ version Hyperclient::Mcp::VERSION
12
+
13
+ arguments :strict
14
+ subcommand_option_handling :normal
15
+
16
+ program_desc 'Hypermedia API MCP Server.'
17
+
18
+ default_command :help
19
+
20
+ flag ['api'], desc: 'API endpoint.', type: String, must_match: /\A#{URI::DEFAULT_PARSER.make_regexp}\z/
21
+ flag %w[h header], desc: 'Additional HTTP request header(s).', multiple: true
22
+ flag ['vcr-cassette-name'], desc: 'Offline VCR cassette.'
23
+
24
+ commands_from File.expand_path('commands', __dir__)
25
+
26
+ pre do |global_options, _command, options, _args|
27
+ # Offline VCR cassette
28
+ if global_options['vcr-cassette-name']
29
+ require 'vcr'
30
+ VCR.configure do |config|
31
+ config.cassette_library_dir = File.expand_path('../spec/fixtures', __dir__)
32
+ config.default_cassette_options = { record: :new_episodes }
33
+ config.hook_into :faraday
34
+ # config.debug_logger = $stderr
35
+ config.filter_sensitive_data('<TOKEN>') do
36
+ ENV.fetch('TOKEN', nil)
37
+ end
38
+ end
39
+ VCR.insert_cassette global_options['vcr-cassette-name']
40
+ end
41
+
42
+ # remove any nil values from options
43
+ options.compact!
44
+
45
+ api = Hyperclient.new(global_options['api']) do |client|
46
+ global_options['header']&.each do |header|
47
+ k, v = header.split('=', 2)
48
+ client.headers[k] = v
49
+ end
50
+ end
51
+
52
+ global_options['mcp'] = Hyperclient::Mcp::Api.new(api)
53
+
54
+ true
55
+ end
56
+
57
+ post do |global_options, _command, _options, _args|
58
+ VCR.eject_cassette if global_options['vcr-cassette-name']
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ exit Hyperclient::Mcp::Cli::App.run(ARGV)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Hyperclient
4
4
  module Mcp
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyperclient-mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Doubrovkine
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-09-12 00:00:00.000000000 Z
10
+ date: 2025-09-19 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: fast-mcp
@@ -23,6 +23,20 @@ dependencies:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
25
  version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: gli
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
26
40
  - !ruby/object:Gem::Dependency
27
41
  name: hyperclient
28
42
  requirement: !ruby/object:Gem::Requirement
@@ -37,14 +51,46 @@ dependencies:
37
51
  - - ">="
38
52
  - !ruby/object:Gem::Version
39
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: puma
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: sinatra
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
40
82
  email: dblock@dblock.org
41
- executables: []
83
+ executables:
84
+ - hyperclient-mcp
42
85
  extensions: []
43
86
  extra_rdoc_files: []
44
87
  files:
45
88
  - CHANGELOG.md
46
89
  - LICENSE.md
47
90
  - README.md
91
+ - bin/commands/resources.rb
92
+ - bin/commands/start.rb
93
+ - bin/hyperclient-mcp
48
94
  - lib/hyperclient-mcp.rb
49
95
  - lib/hyperclient-mcp/api.rb
50
96
  - lib/hyperclient-mcp/resource.rb