Skip to content

Commit f82faa8

Browse files
committed
Introduce a singleton
This allows the tools to populate the enums for category.
1 parent ad508c9 commit f82faa8

23 files changed

+79
-96
lines changed

lib/cf/mcp.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,16 @@ class Error < StandardError; end
2020
def self.root
2121
@root ||= Pathname.new(File.expand_path("../..", __dir__))
2222
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
2334
end
2435
end

lib/cf/mcp/index.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
# frozen_string_literal: true
22

3+
require "singleton"
4+
35
module CF
46
module MCP
57
class Index
8+
include Singleton
9+
610
attr_reader :items, :by_type, :by_category, :topic_references
711

812
def initialize
13+
reset!
14+
end
15+
16+
def reset!
917
@items = {}
1018
@by_type = {
1119
function: [],

lib/cf/mcp/index_builder.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ def initialize(root: nil, download: false)
1818

1919
def build
2020
parser = Parser.new
21-
index = Index.new
21+
index = Index.instance
22+
index.reset!
2223

2324
parser.parse_directory(headers_path).each do |item|
2425
index.add(item)

lib/cf/mcp/server.rb

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,12 @@
11
# frozen_string_literal: true
22

33
require "mcp"
4-
require_relative "tools/search_tool"
5-
require_relative "tools/list_category"
6-
require_relative "tools/get_details"
7-
require_relative "tools/find_related"
8-
require_relative "tools/parameter_search"
9-
require_relative "tools/member_search"
10-
require_relative "tools/list_topics"
11-
require_relative "tools/get_topic"
124

135
module CF
146
module MCP
157
class Server
168
attr_reader :server, :index
179

18-
TOOLS = [
19-
Tools::SearchTool,
20-
Tools::ListCategory,
21-
Tools::GetDetails,
22-
Tools::FindRelated,
23-
Tools::ParameterSearch,
24-
Tools::MemberSearch,
25-
Tools::ListTopics,
26-
Tools::GetTopic
27-
].freeze
28-
2910
CORS_HEADERS = {
3011
"access-control-allow-origin" => "*",
3112
"access-control-allow-methods" => "GET, POST, DELETE, OPTIONS",
@@ -59,6 +40,7 @@ def self.build_rack_app(root: nil, download: false)
5940

6041
def initialize(index)
6142
@index = index
43+
6244
configuration = ::MCP::Configuration.new(protocol_version: PROTOCOL_VERSION)
6345
@server = ::MCP::Server.new(
6446
name: "cf-mcp",
@@ -70,7 +52,16 @@ def initialize(index)
7052
::MCP::Icon.new(src: "#{WEBSITE_URL}/favicon.svg", mime_type: "image/svg+xml", sizes: ["any"]),
7153
::MCP::Icon.new(src: "#{WEBSITE_URL}/favicon-96x96.png", mime_type: "image/png", sizes: ["96x96"])
7254
],
73-
tools: 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+
],
7465
resources: build_topic_resources(index)
7566
)
7667
@server.server_context = {index: index}
@@ -94,7 +85,7 @@ def rack_app
9485

9586
landing_page = build_landing_page
9687
index = @index
97-
tools = TOOLS
88+
tools = @server.tools.values
9889
cors_headers = CORS_HEADERS
9990
public_dir = PUBLIC_DIR
10091

lib/cf/mcp/tools/find_related.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ class FindRelated < ::MCP::Tool
3232
)
3333

3434
def self.call(name:, server_context: {})
35-
index = server_context[:index]
36-
return error_response("Index not available") unless index
35+
index = Index.instance
3736

3837
item = index.find(name)
3938
return text_response("Not found: '#{name}'") unless item

lib/cf/mcp/tools/get_details.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ class GetDetails < ::MCP::Tool
3434
NAMING_TIP = "**Tip:** Cute Framework uses `cf_` prefix for functions and `CF_` prefix for types (structs/enums)."
3535

3636
def self.call(name:, server_context: {})
37-
index = server_context[:index]
38-
return error_response("Index not available") unless index
37+
index = Index.instance
3938

4039
item = index.find(name)
4140

lib/cf/mcp/tools/get_topic.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ class GetTopic < ::MCP::Tool
3232
)
3333

3434
def self.call(name:, server_context: {})
35-
index = server_context[:index]
36-
return error_response("Index not available") unless index
35+
index = Index.instance
3736

3837
topic = index.find(name)
3938

lib/cf/mcp/tools/list_category.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ListCategory < ::MCP::Tool
1818
input_schema(
1919
type: "object",
2020
properties: {
21-
category: {type: "string", description: "Category name (e.g., 'app', 'sprite', 'graphics'). Leave empty to list all categories."},
21+
category: {type: "string", enum: Index.instance.categories, description: "Category name. Leave empty to list all categories."},
2222
type: {type: "string", enum: ["function", "struct", "enum"], description: "Optional: filter by item type"}
2323
}
2424
)
@@ -32,8 +32,7 @@ class ListCategory < ::MCP::Tool
3232
)
3333

3434
def self.call(category: nil, type: nil, server_context: {})
35-
index = server_context[:index]
36-
return error_response("Index not available") unless index
35+
index = Index.instance
3736

3837
if category.nil? || category.empty?
3938
# List all categories with counts by type

lib/cf/mcp/tools/list_topics.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ class ListTopics < ::MCP::Tool
3232
)
3333

3434
def self.call(category: nil, ordered: false, server_context: {})
35-
index = server_context[:index]
36-
return error_response("Index not available") unless index
35+
index = Index.instance
3736

3837
topics = ordered ? index.topics_ordered : index.topics
3938

lib/cf/mcp/tools/member_search.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ class MemberSearch < ::MCP::Tool
3333
)
3434

3535
def self.call(query:, limit: 20, server_context: {})
36-
index = server_context[:index]
37-
return error_response("Index not available") unless index
36+
index = Index.instance
3837

3938
pattern = Regexp.new(Regexp.escape(query), Regexp::IGNORECASE)
4039
results = []

0 commit comments

Comments
 (0)