cf-mcp 0.15.5 → 0.16.2
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/CHANGELOG.md +28 -0
- data/Manifest.txt +0 -3
- data/Rakefile +1 -1
- data/lib/cf/mcp/index.rb +8 -0
- data/lib/cf/mcp/index_builder.rb +2 -1
- data/lib/cf/mcp/parser.rb +2 -1
- data/lib/cf/mcp/server.rb +12 -27
- data/lib/cf/mcp/templates/index.erb +1 -1
- data/lib/cf/mcp/tools/find_related.rb +1 -2
- data/lib/cf/mcp/tools/get_details.rb +1 -2
- data/lib/cf/mcp/tools/get_topic.rb +1 -2
- data/lib/cf/mcp/tools/list_category.rb +2 -3
- data/lib/cf/mcp/tools/list_topics.rb +1 -2
- data/lib/cf/mcp/tools/member_search.rb +1 -2
- data/lib/cf/mcp/tools/parameter_search.rb +1 -2
- data/lib/cf/mcp/tools/search_tool.rb +26 -7
- data/lib/cf/mcp/version.rb +1 -1
- data/lib/cf/mcp.rb +11 -0
- metadata +1 -4
- data/lib/cf/mcp/tools/search_enums.rb +0 -59
- data/lib/cf/mcp/tools/search_functions.rb +0 -59
- data/lib/cf/mcp/tools/search_structs.rb +0 -59
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8616f673c57b67cd09602a2b49611c030fc058d63f1701dd2cec2cff2c04d4ad
|
|
4
|
+
data.tar.gz: abc2b55c27a9f4ace220d5fd9d013cb5944c02d8bd6f43106be141ac05aaa208
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7587ed21fd3fe5e3f81a7fd574cc32afc3da7c69b7c9869241508ad8a3f477ec813297f1d893b0dba5c3c9ccc4411773adacce35eeb8e15a936328f613d55186
|
|
7
|
+
data.tar.gz: 02e5f832b1c52dc25ec415d362585e7f104a526a24e7454af38192f48d60abc209c7f91175b60dd5759b0dc1670508fdf16ad61fa7db4aebe25edf7f406d984a
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.16.2] - 2026-01-31
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Enum entries now correctly prefixed with `CF_` (e.g., `CF_KEY_SPACE` instead of `KEY_SPACE`) to match the CF_ENUM macro expansion
|
|
13
|
+
|
|
14
|
+
## [0.16.1] - 2026-01-31
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Fix broken logo image path in dashboard (use favicon.svg instead of non-existent logo.svg)
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Add workflow_dispatch trigger to fly-deploy.yml for manual deployments
|
|
23
|
+
|
|
24
|
+
## [0.16.0] - 2026-01-26
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **Refactored tool loading with Index singleton** - Index is now a singleton, eliminating duplicate schema definitions and simplifying tool initialization
|
|
29
|
+
- Tool classes now use `Index.instance.categories` directly in schema definitions instead of requiring runtime configuration
|
|
30
|
+
- Removed `TOOLS` constant and `configure_tool_schemas` method from Server
|
|
31
|
+
- Tools use autoload for lazy loading, ensuring they see populated categories at load time
|
|
32
|
+
|
|
8
33
|
## [0.15.5] - 2026-01-26
|
|
9
34
|
|
|
10
35
|
### Changed
|
|
@@ -236,6 +261,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
236
261
|
- `cf_list_category` - List items by category
|
|
237
262
|
- `cf_get_details` - Get full documentation by name
|
|
238
263
|
|
|
264
|
+
[0.16.2]: https://github.com/pusewicz/cf-mcp/compare/v0.16.1...v0.16.2
|
|
265
|
+
[0.16.1]: https://github.com/pusewicz/cf-mcp/compare/v0.16.0...v0.16.1
|
|
266
|
+
[0.16.0]: https://github.com/pusewicz/cf-mcp/compare/v0.15.5...v0.16.0
|
|
239
267
|
[0.15.5]: https://github.com/pusewicz/cf-mcp/compare/v0.15.4...v0.15.5
|
|
240
268
|
[0.15.4]: https://github.com/pusewicz/cf-mcp/compare/v0.15.3...v0.15.4
|
|
241
269
|
[0.15.3]: https://github.com/pusewicz/cf-mcp/compare/v0.15.2...v0.15.3
|
data/Manifest.txt
CHANGED
|
@@ -35,10 +35,7 @@ lib/cf/mcp/tools/list_topics.rb
|
|
|
35
35
|
lib/cf/mcp/tools/member_search.rb
|
|
36
36
|
lib/cf/mcp/tools/parameter_search.rb
|
|
37
37
|
lib/cf/mcp/tools/response_helpers.rb
|
|
38
|
-
lib/cf/mcp/tools/search_enums.rb
|
|
39
|
-
lib/cf/mcp/tools/search_functions.rb
|
|
40
38
|
lib/cf/mcp/tools/search_result_formatter.rb
|
|
41
|
-
lib/cf/mcp/tools/search_structs.rb
|
|
42
39
|
lib/cf/mcp/tools/search_tool.rb
|
|
43
40
|
lib/cf/mcp/topic_parser.rb
|
|
44
41
|
lib/cf/mcp/version.rb
|
data/Rakefile
CHANGED
|
@@ -9,7 +9,7 @@ require "standard/rake"
|
|
|
9
9
|
|
|
10
10
|
desc "Generate Manifest.txt from git ls-files"
|
|
11
11
|
task :manifest do
|
|
12
|
-
ignore_patterns = %w[bin/ Gemfile .gitignore test/ .github/ .standard.yml cf-mcp.gemspec .ruby-version CLAUDE.md AGENTS.md fly.toml Procfile Dockerfile .dockerignore .claude/]
|
|
12
|
+
ignore_patterns = %w[bin/ Gemfile .gitignore test/ .github/ .standard.yml cf-mcp.gemspec .ruby-version CLAUDE.md AGENTS.md fly.toml Procfile Dockerfile .dockerignore .claude/ .mcp.json]
|
|
13
13
|
|
|
14
14
|
files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
|
|
15
15
|
ls.readlines("\x0", chomp: true)
|
data/lib/cf/mcp/index.rb
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "singleton"
|
|
4
|
+
|
|
3
5
|
module CF
|
|
4
6
|
module MCP
|
|
5
7
|
class Index
|
|
8
|
+
include Singleton
|
|
9
|
+
|
|
6
10
|
attr_reader :items, :by_type, :by_category, :topic_references
|
|
7
11
|
|
|
8
12
|
def initialize
|
|
13
|
+
reset!
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def reset!
|
|
9
17
|
@items = {}
|
|
10
18
|
@by_type = {
|
|
11
19
|
function: [],
|
data/lib/cf/mcp/index_builder.rb
CHANGED
data/lib/cf/mcp/parser.rb
CHANGED
|
@@ -236,7 +236,8 @@ module CF
|
|
|
236
236
|
# Find the #define block with CF_ENUM macros
|
|
237
237
|
# Pattern: /* @entry description */ followed by CF_ENUM(NAME, VALUE)
|
|
238
238
|
content.scan(%r{/\*\s*@entry\s+(.*?)\s*\*/\s*\\?\s*CF_ENUM\s*\(\s*(\w+)\s*,\s*([^)]*)\)}m) do |description, name, value|
|
|
239
|
-
|
|
239
|
+
# CF_ENUM(K, V) expands to CF_##K = V, so add CF_ prefix
|
|
240
|
+
entries << Models::EnumDoc::Entry.new("CF_#{name.strip}", value.strip, description.strip)
|
|
240
241
|
end
|
|
241
242
|
|
|
242
243
|
entries
|
data/lib/cf/mcp/server.rb
CHANGED
|
@@ -1,37 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "mcp"
|
|
4
|
-
require_relative "tools/search_tool"
|
|
5
|
-
require_relative "tools/search_functions"
|
|
6
|
-
require_relative "tools/search_structs"
|
|
7
|
-
require_relative "tools/search_enums"
|
|
8
|
-
require_relative "tools/list_category"
|
|
9
|
-
require_relative "tools/get_details"
|
|
10
|
-
require_relative "tools/find_related"
|
|
11
|
-
require_relative "tools/parameter_search"
|
|
12
|
-
require_relative "tools/member_search"
|
|
13
|
-
require_relative "tools/list_topics"
|
|
14
|
-
require_relative "tools/get_topic"
|
|
15
4
|
|
|
16
5
|
module CF
|
|
17
6
|
module MCP
|
|
18
7
|
class Server
|
|
19
8
|
attr_reader :server, :index
|
|
20
9
|
|
|
21
|
-
TOOLS = [
|
|
22
|
-
Tools::SearchTool,
|
|
23
|
-
Tools::SearchFunctions,
|
|
24
|
-
Tools::SearchStructs,
|
|
25
|
-
Tools::SearchEnums,
|
|
26
|
-
Tools::ListCategory,
|
|
27
|
-
Tools::GetDetails,
|
|
28
|
-
Tools::FindRelated,
|
|
29
|
-
Tools::ParameterSearch,
|
|
30
|
-
Tools::MemberSearch,
|
|
31
|
-
Tools::ListTopics,
|
|
32
|
-
Tools::GetTopic
|
|
33
|
-
].freeze
|
|
34
|
-
|
|
35
10
|
CORS_HEADERS = {
|
|
36
11
|
"access-control-allow-origin" => "*",
|
|
37
12
|
"access-control-allow-methods" => "GET, POST, DELETE, OPTIONS",
|
|
@@ -65,6 +40,7 @@ module CF
|
|
|
65
40
|
|
|
66
41
|
def initialize(index)
|
|
67
42
|
@index = index
|
|
43
|
+
|
|
68
44
|
configuration = ::MCP::Configuration.new(protocol_version: PROTOCOL_VERSION)
|
|
69
45
|
@server = ::MCP::Server.new(
|
|
70
46
|
name: "cf-mcp",
|
|
@@ -76,7 +52,16 @@ module CF
|
|
|
76
52
|
::MCP::Icon.new(src: "#{WEBSITE_URL}/favicon.svg", mime_type: "image/svg+xml", sizes: ["any"]),
|
|
77
53
|
::MCP::Icon.new(src: "#{WEBSITE_URL}/favicon-96x96.png", mime_type: "image/png", sizes: ["96x96"])
|
|
78
54
|
],
|
|
79
|
-
tools:
|
|
55
|
+
tools: [
|
|
56
|
+
Tools::SearchTool,
|
|
57
|
+
Tools::ListCategory,
|
|
58
|
+
Tools::GetDetails,
|
|
59
|
+
Tools::FindRelated,
|
|
60
|
+
Tools::ParameterSearch,
|
|
61
|
+
Tools::MemberSearch,
|
|
62
|
+
Tools::ListTopics,
|
|
63
|
+
Tools::GetTopic
|
|
64
|
+
],
|
|
80
65
|
resources: build_topic_resources(index)
|
|
81
66
|
)
|
|
82
67
|
@server.server_context = {index: index}
|
|
@@ -100,7 +85,7 @@ module CF
|
|
|
100
85
|
|
|
101
86
|
landing_page = build_landing_page
|
|
102
87
|
index = @index
|
|
103
|
-
tools =
|
|
88
|
+
tools = @server.tools.values
|
|
104
89
|
cors_headers = CORS_HEADERS
|
|
105
90
|
public_dir = PUBLIC_DIR
|
|
106
91
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
18
|
-
<h1><img src="/
|
|
18
|
+
<h1><img src="/favicon.svg" alt="CF Logo" class="title-logo">CF::MCP <small style="font-size: 0.5em; color: #8b949e;">v<%= version %></small></h1>
|
|
19
19
|
<p>MCP (Model Context Protocol) server for the <a href="https://github.com/RandyGaul/cute_framework">Cute Framework</a>, a C/C++ 2D game framework.</p>
|
|
20
20
|
|
|
21
21
|
<div class="stats">
|
|
@@ -32,8 +32,7 @@ module CF
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
def self.call(name:, server_context: {})
|
|
35
|
-
index =
|
|
36
|
-
return error_response("Index not available") unless index
|
|
35
|
+
index = Index.instance
|
|
37
36
|
|
|
38
37
|
item = index.find(name)
|
|
39
38
|
return text_response("Not found: '#{name}'") unless item
|
|
@@ -34,8 +34,7 @@ module CF
|
|
|
34
34
|
NAMING_TIP = "**Tip:** Cute Framework uses `cf_` prefix for functions and `CF_` prefix for types (structs/enums)."
|
|
35
35
|
|
|
36
36
|
def self.call(name:, server_context: {})
|
|
37
|
-
index =
|
|
38
|
-
return error_response("Index not available") unless index
|
|
37
|
+
index = Index.instance
|
|
39
38
|
|
|
40
39
|
item = index.find(name)
|
|
41
40
|
|
|
@@ -18,7 +18,7 @@ module CF
|
|
|
18
18
|
input_schema(
|
|
19
19
|
type: "object",
|
|
20
20
|
properties: {
|
|
21
|
-
category: {type: "string", description: "Category name
|
|
21
|
+
category: {type: "string", enum: Index.instance.categories, description: "Category name. Leave empty to list all categories."},
|
|
22
22
|
type: {type: "string", enum: ["function", "struct", "enum"], description: "Optional: filter by item type"}
|
|
23
23
|
}
|
|
24
24
|
)
|
|
@@ -32,8 +32,7 @@ module CF
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
def self.call(category: nil, type: nil, server_context: {})
|
|
35
|
-
index =
|
|
36
|
-
return error_response("Index not available") unless index
|
|
35
|
+
index = Index.instance
|
|
37
36
|
|
|
38
37
|
if category.nil? || category.empty?
|
|
39
38
|
# List all categories with counts by type
|
|
@@ -32,8 +32,7 @@ module CF
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
def self.call(category: nil, ordered: false, server_context: {})
|
|
35
|
-
index =
|
|
36
|
-
return error_response("Index not available") unless index
|
|
35
|
+
index = Index.instance
|
|
37
36
|
|
|
38
37
|
topics = ordered ? index.topics_ordered : index.topics
|
|
39
38
|
|
|
@@ -33,8 +33,7 @@ module CF
|
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
def self.call(query:, limit: 20, server_context: {})
|
|
36
|
-
index =
|
|
37
|
-
return error_response("Index not available") unless index
|
|
36
|
+
index = Index.instance
|
|
38
37
|
|
|
39
38
|
pattern = Regexp.new(Regexp.escape(query), Regexp::IGNORECASE)
|
|
40
39
|
results = []
|
|
@@ -37,8 +37,7 @@ module CF
|
|
|
37
37
|
)
|
|
38
38
|
|
|
39
39
|
def self.call(type:, direction: "both", server_context: {})
|
|
40
|
-
index =
|
|
41
|
-
return error_response("Index not available") unless index
|
|
40
|
+
index = Index.instance
|
|
42
41
|
|
|
43
42
|
pattern = Regexp.new(Regexp.escape(type), Regexp::IGNORECASE)
|
|
44
43
|
input_matches = []
|
|
@@ -22,7 +22,7 @@ module CF
|
|
|
22
22
|
properties: {
|
|
23
23
|
query: {type: "string", description: "Search query (searches in name, description, and remarks)"},
|
|
24
24
|
type: {type: "string", enum: ["function", "struct", "enum", "topic"], description: "Optional: filter by item type"},
|
|
25
|
-
category: {type: "string", description: "Optional: filter by category
|
|
25
|
+
category: {type: "string", enum: Index.instance.categories, description: "Optional: filter by category"},
|
|
26
26
|
limit: {type: "integer", description: "Maximum number of results to return (default: 20)"}
|
|
27
27
|
},
|
|
28
28
|
required: ["query"]
|
|
@@ -36,21 +36,40 @@ module CF
|
|
|
36
36
|
open_world_hint: false
|
|
37
37
|
)
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
DETAILS_TIPS = {
|
|
40
|
+
"function" => "**Tip:** Use `get_details` with an exact name to get full documentation including signature, parameters, and examples.",
|
|
41
|
+
"struct" => "**Tip:** Use `get_details` with an exact name to get full documentation including members and examples.",
|
|
42
|
+
"enum" => "**Tip:** Use `get_details` with an exact name to get full documentation including values and examples.",
|
|
43
|
+
"topic" => "**Tip:** Use `get_topic` with an exact name to get the full topic guide.",
|
|
44
|
+
nil => "**Tip:** Use `get_details` for API items or `get_topic` for topic guides to get full documentation."
|
|
45
|
+
}.freeze
|
|
46
|
+
|
|
47
|
+
TYPE_LABELS = {
|
|
48
|
+
"function" => "function(s)",
|
|
49
|
+
"struct" => "struct(s)",
|
|
50
|
+
"enum" => "enum(s)",
|
|
51
|
+
"topic" => "topic(s)",
|
|
52
|
+
nil => "result(s)"
|
|
53
|
+
}.freeze
|
|
40
54
|
|
|
41
55
|
def self.call(query:, type: nil, category: nil, limit: 20, server_context: {})
|
|
42
|
-
index =
|
|
43
|
-
return error_response("Index not available") unless index
|
|
56
|
+
index = Index.instance
|
|
44
57
|
|
|
45
58
|
results = index.search(query, type: type, category: category, limit: limit)
|
|
46
59
|
|
|
60
|
+
filter_suggestion = if type
|
|
61
|
+
"To find more results, narrow your search with a `category` filter."
|
|
62
|
+
else
|
|
63
|
+
"To find more results, narrow your search with `type` or `category` filters."
|
|
64
|
+
end
|
|
65
|
+
|
|
47
66
|
text = format_search_results(
|
|
48
67
|
results,
|
|
49
68
|
query: query,
|
|
50
|
-
type_label:
|
|
69
|
+
type_label: TYPE_LABELS[type],
|
|
51
70
|
limit: limit,
|
|
52
|
-
details_tip:
|
|
53
|
-
filter_suggestion:
|
|
71
|
+
details_tip: DETAILS_TIPS[type],
|
|
72
|
+
filter_suggestion: filter_suggestion
|
|
54
73
|
)
|
|
55
74
|
text_response(text)
|
|
56
75
|
end
|
data/lib/cf/mcp/version.rb
CHANGED
data/lib/cf/mcp.rb
CHANGED
|
@@ -20,5 +20,16 @@ module CF
|
|
|
20
20
|
def self.root
|
|
21
21
|
@root ||= Pathname.new(File.expand_path("../..", __dir__))
|
|
22
22
|
end
|
|
23
|
+
|
|
24
|
+
module Tools
|
|
25
|
+
autoload :SearchTool, "cf/mcp/tools/search_tool"
|
|
26
|
+
autoload :ListCategory, "cf/mcp/tools/list_category"
|
|
27
|
+
autoload :GetDetails, "cf/mcp/tools/get_details"
|
|
28
|
+
autoload :FindRelated, "cf/mcp/tools/find_related"
|
|
29
|
+
autoload :ParameterSearch, "cf/mcp/tools/parameter_search"
|
|
30
|
+
autoload :MemberSearch, "cf/mcp/tools/member_search"
|
|
31
|
+
autoload :ListTopics, "cf/mcp/tools/list_topics"
|
|
32
|
+
autoload :GetTopic, "cf/mcp/tools/get_topic"
|
|
33
|
+
end
|
|
23
34
|
end
|
|
24
35
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cf-mcp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Piotr Usewicz
|
|
@@ -125,10 +125,7 @@ files:
|
|
|
125
125
|
- lib/cf/mcp/tools/member_search.rb
|
|
126
126
|
- lib/cf/mcp/tools/parameter_search.rb
|
|
127
127
|
- lib/cf/mcp/tools/response_helpers.rb
|
|
128
|
-
- lib/cf/mcp/tools/search_enums.rb
|
|
129
|
-
- lib/cf/mcp/tools/search_functions.rb
|
|
130
128
|
- lib/cf/mcp/tools/search_result_formatter.rb
|
|
131
|
-
- lib/cf/mcp/tools/search_structs.rb
|
|
132
129
|
- lib/cf/mcp/tools/search_tool.rb
|
|
133
130
|
- lib/cf/mcp/topic_parser.rb
|
|
134
131
|
- lib/cf/mcp/version.rb
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "mcp"
|
|
4
|
-
require_relative "response_helpers"
|
|
5
|
-
require_relative "search_result_formatter"
|
|
6
|
-
|
|
7
|
-
module CF
|
|
8
|
-
module MCP
|
|
9
|
-
module Tools
|
|
10
|
-
class SearchEnums < ::MCP::Tool
|
|
11
|
-
extend ResponseHelpers
|
|
12
|
-
extend SearchResultFormatter
|
|
13
|
-
|
|
14
|
-
TITLE = "Search Enums"
|
|
15
|
-
|
|
16
|
-
tool_name "search_enums"
|
|
17
|
-
title TITLE
|
|
18
|
-
description "Search Cute Framework enums"
|
|
19
|
-
|
|
20
|
-
input_schema(
|
|
21
|
-
type: "object",
|
|
22
|
-
properties: {
|
|
23
|
-
query: {type: "string", description: "Search query"},
|
|
24
|
-
category: {type: "string", description: "Optional: filter by category"},
|
|
25
|
-
limit: {type: "integer", description: "Maximum results (default: 20)"}
|
|
26
|
-
},
|
|
27
|
-
required: ["query"]
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
annotations(
|
|
31
|
-
title: TITLE,
|
|
32
|
-
read_only_hint: true,
|
|
33
|
-
destructive_hint: false,
|
|
34
|
-
idempotent_hint: true,
|
|
35
|
-
open_world_hint: false
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
DETAILS_TIP = "**Tip:** Use `get_details` with an exact name to get full documentation including values and examples."
|
|
39
|
-
|
|
40
|
-
def self.call(query:, category: nil, limit: 20, server_context: {})
|
|
41
|
-
index = server_context[:index]
|
|
42
|
-
return error_response("Index not available") unless index
|
|
43
|
-
|
|
44
|
-
results = index.search(query, type: :enum, category: category, limit: limit)
|
|
45
|
-
|
|
46
|
-
text = format_search_results(
|
|
47
|
-
results,
|
|
48
|
-
query: query,
|
|
49
|
-
type_label: "enum(s)",
|
|
50
|
-
limit: limit,
|
|
51
|
-
details_tip: DETAILS_TIP,
|
|
52
|
-
filter_suggestion: "To find more results, narrow your search with a `category` filter."
|
|
53
|
-
)
|
|
54
|
-
text_response(text)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "mcp"
|
|
4
|
-
require_relative "response_helpers"
|
|
5
|
-
require_relative "search_result_formatter"
|
|
6
|
-
|
|
7
|
-
module CF
|
|
8
|
-
module MCP
|
|
9
|
-
module Tools
|
|
10
|
-
class SearchFunctions < ::MCP::Tool
|
|
11
|
-
extend ResponseHelpers
|
|
12
|
-
extend SearchResultFormatter
|
|
13
|
-
|
|
14
|
-
TITLE = "Search Functions"
|
|
15
|
-
|
|
16
|
-
tool_name "search_functions"
|
|
17
|
-
title TITLE
|
|
18
|
-
description "Search Cute Framework functions"
|
|
19
|
-
|
|
20
|
-
input_schema(
|
|
21
|
-
type: "object",
|
|
22
|
-
properties: {
|
|
23
|
-
query: {type: "string", description: "Search query"},
|
|
24
|
-
category: {type: "string", description: "Optional: filter by category"},
|
|
25
|
-
limit: {type: "integer", description: "Maximum results (default: 20)"}
|
|
26
|
-
},
|
|
27
|
-
required: ["query"]
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
annotations(
|
|
31
|
-
title: TITLE,
|
|
32
|
-
read_only_hint: true,
|
|
33
|
-
destructive_hint: false,
|
|
34
|
-
idempotent_hint: true,
|
|
35
|
-
open_world_hint: false
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
DETAILS_TIP = "**Tip:** Use `get_details` with an exact name to get full documentation including signature, parameters, and examples."
|
|
39
|
-
|
|
40
|
-
def self.call(query:, category: nil, limit: 20, server_context: {})
|
|
41
|
-
index = server_context[:index]
|
|
42
|
-
return error_response("Index not available") unless index
|
|
43
|
-
|
|
44
|
-
results = index.search(query, type: :function, category: category, limit: limit)
|
|
45
|
-
|
|
46
|
-
text = format_search_results(
|
|
47
|
-
results,
|
|
48
|
-
query: query,
|
|
49
|
-
type_label: "function(s)",
|
|
50
|
-
limit: limit,
|
|
51
|
-
details_tip: DETAILS_TIP,
|
|
52
|
-
filter_suggestion: "To find more results, narrow your search with a `category` filter."
|
|
53
|
-
)
|
|
54
|
-
text_response(text)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "mcp"
|
|
4
|
-
require_relative "response_helpers"
|
|
5
|
-
require_relative "search_result_formatter"
|
|
6
|
-
|
|
7
|
-
module CF
|
|
8
|
-
module MCP
|
|
9
|
-
module Tools
|
|
10
|
-
class SearchStructs < ::MCP::Tool
|
|
11
|
-
extend ResponseHelpers
|
|
12
|
-
extend SearchResultFormatter
|
|
13
|
-
|
|
14
|
-
TITLE = "Search Structs"
|
|
15
|
-
|
|
16
|
-
tool_name "search_structs"
|
|
17
|
-
title TITLE
|
|
18
|
-
description "Search Cute Framework structs"
|
|
19
|
-
|
|
20
|
-
input_schema(
|
|
21
|
-
type: "object",
|
|
22
|
-
properties: {
|
|
23
|
-
query: {type: "string", description: "Search query"},
|
|
24
|
-
category: {type: "string", description: "Optional: filter by category"},
|
|
25
|
-
limit: {type: "integer", description: "Maximum results (default: 20)"}
|
|
26
|
-
},
|
|
27
|
-
required: ["query"]
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
annotations(
|
|
31
|
-
title: TITLE,
|
|
32
|
-
read_only_hint: true,
|
|
33
|
-
destructive_hint: false,
|
|
34
|
-
idempotent_hint: true,
|
|
35
|
-
open_world_hint: false
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
DETAILS_TIP = "**Tip:** Use `get_details` with an exact name to get full documentation including members and examples."
|
|
39
|
-
|
|
40
|
-
def self.call(query:, category: nil, limit: 20, server_context: {})
|
|
41
|
-
index = server_context[:index]
|
|
42
|
-
return error_response("Index not available") unless index
|
|
43
|
-
|
|
44
|
-
results = index.search(query, type: :struct, category: category, limit: limit)
|
|
45
|
-
|
|
46
|
-
text = format_search_results(
|
|
47
|
-
results,
|
|
48
|
-
query: query,
|
|
49
|
-
type_label: "struct(s)",
|
|
50
|
-
limit: limit,
|
|
51
|
-
details_tip: DETAILS_TIP,
|
|
52
|
-
filter_suggestion: "To find more results, narrow your search with a `category` filter."
|
|
53
|
-
)
|
|
54
|
-
text_response(text)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|