Skip to content

Commit 52656a8

Browse files
committed
add output_schema
1 parent b4db99c commit 52656a8

File tree

11 files changed

+752
-213
lines changed

11 files changed

+752
-213
lines changed

app/tools/posts/create_tool.rb

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,62 @@ class CreateTool < MCP::Tool
1717
required: [ "title", "description" ]
1818
)
1919

20+
output_schema(
21+
properties: {
22+
success: {
23+
type: "boolean",
24+
description: "Se a operação foi bem-sucedida"
25+
},
26+
post: {
27+
type: "object",
28+
properties: {
29+
id: { type: "integer" },
30+
title: { type: "string" },
31+
description: { type: "string" },
32+
created_at: { type: "string", format: "date-time" },
33+
updated_at: { type: "string", format: "date-time" }
34+
}
35+
},
36+
message: {
37+
type: "string",
38+
description: "Mensagem de retorno"
39+
}
40+
},
41+
required: [ "success", "message" ]
42+
)
43+
2044
def self.call(title:, description:, server_context:)
2145
post = Post.new(title: title, description: description)
2246

2347
if post.save
48+
result = {
49+
success: true,
50+
post: {
51+
id: post.id,
52+
title: post.title,
53+
description: post.description,
54+
created_at: post.created_at.iso8601,
55+
updated_at: post.updated_at.iso8601
56+
},
57+
message: "Post criado com sucesso!"
58+
}
59+
60+
output_schema.validate_result(result)
61+
2462
MCP::Tool::Response.new([ {
2563
type: "text",
26-
text: "Post criado com sucesso! ID: #{post.id}, Título: #{post.title}"
64+
text: result.to_json
2765
} ])
2866
else
2967
MCP::Tool::Response.new([ {
3068
type: "text",
31-
text: "Erro ao criar post: #{post.errors.full_messages.join(', ')}"
69+
text: { success: false, message: "Erro ao criar post: #{post.errors.full_messages.join(', ')}" }.to_json
3270
} ])
3371
end
3472
rescue StandardError => e
3573
MCP::Tool::Response.new([ {
3674
type: "text",
37-
text: "Erro ao criar post: #{e.message}"
75+
text: { success: false, message: "Erro ao criar post: #{e.message}" }.to_json
3876
} ])
3977
end
4078
end

app/tools/posts/delete_tool.rb

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,62 @@ class DeleteTool < MCP::Tool
1313
required: [ "id" ]
1414
)
1515

16+
output_schema(
17+
properties: {
18+
success: {
19+
type: "boolean",
20+
description: "Se a operação foi bem-sucedida"
21+
},
22+
post: {
23+
type: "object",
24+
properties: {
25+
id: { type: "integer" },
26+
title: { type: "string" }
27+
}
28+
},
29+
message: {
30+
type: "string",
31+
description: "Mensagem de retorno"
32+
}
33+
},
34+
required: [ "success", "message" ]
35+
)
36+
1637
def self.call(id:, server_context:)
1738
post = Post.find(id)
18-
title = post.title
39+
post_data = {
40+
id: post.id,
41+
title: post.title
42+
}
1943

2044
if post.destroy
45+
result = {
46+
success: true,
47+
post: post_data,
48+
message: "Post deletado com sucesso!"
49+
}
50+
51+
output_schema.validate_result(result)
52+
2153
MCP::Tool::Response.new([ {
2254
type: "text",
23-
text: "Post '#{title}' (ID: #{id}) deletado com sucesso!"
55+
text: result.to_json
2456
} ])
2557
else
2658
MCP::Tool::Response.new([ {
2759
type: "text",
28-
text: "Erro ao deletar post: #{post.errors.full_messages.join(', ')}"
60+
text: { success: false, message: "Erro ao deletar post: #{post.errors.full_messages.join(', ')}" }.to_json
2961
} ])
3062
end
3163
rescue ActiveRecord::RecordNotFound
3264
MCP::Tool::Response.new([ {
3365
type: "text",
34-
text: "Post com ID #{id} não encontrado"
66+
text: { success: false, message: "Post com ID #{id} não encontrado" }.to_json
3567
} ])
3668
rescue StandardError => e
3769
MCP::Tool::Response.new([ {
3870
type: "text",
39-
text: "Erro ao deletar post: #{e.message}"
71+
text: { success: false, message: "Erro ao deletar post: #{e.message}" }.to_json
4072
} ])
4173
end
4274
end

app/tools/posts/index_tool.rb

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class IndexTool < MCP::Tool
55

66
input_schema(
77
properties: {
8-
search_term: {
8+
search_term: {
99
type: "string",
1010
description: "Termo de busca para filtrar postagens (busca em título e descrição)"
1111
},
@@ -37,6 +37,37 @@ class IndexTool < MCP::Tool
3737
}
3838
)
3939

40+
output_schema(
41+
properties: {
42+
success: {
43+
type: "boolean",
44+
description: "Se a operação foi bem-sucedida"
45+
},
46+
posts: {
47+
type: "array",
48+
items: {
49+
type: "object",
50+
properties: {
51+
id: { type: "integer" },
52+
title: { type: "string" },
53+
description: { type: "string" },
54+
created_at: { type: "string", format: "date-time" },
55+
updated_at: { type: "string", format: "date-time" }
56+
}
57+
}
58+
},
59+
total: {
60+
type: "integer",
61+
description: "Total de posts retornados"
62+
},
63+
message: {
64+
type: "string",
65+
description: "Mensagem de retorno"
66+
}
67+
},
68+
required: [ "success", "posts", "total", "message" ]
69+
)
70+
4071
def self.call(search_term: nil, limit: 20, offset: 0, sort_by: "created_at", sort_order: "desc", server_context:)
4172
posts = Post.where(
4273
"title ILIKE :search OR description ILIKE :search",
@@ -45,22 +76,31 @@ def self.call(search_term: nil, limit: 20, offset: 0, sort_by: "created_at", sor
4576

4677
posts_data = posts.map do |post|
4778
{
48-
id: post.id,
49-
title: post.title,
79+
id: post.id,
80+
title: post.title,
5081
description: post.description,
51-
created_at: post.created_at.iso8601,
52-
updated_at: post.updated_at.iso8601
82+
created_at: post.created_at.iso8601,
83+
updated_at: post.updated_at.iso8601
5384
}
5485
end
5586

87+
result = {
88+
success: true,
89+
posts: posts_data,
90+
total: posts.count,
91+
message: "Posts listados com sucesso!"
92+
}
93+
94+
output_schema.validate_result(result)
95+
5696
MCP::Tool::Response.new([ {
5797
type: "text",
58-
text: "Total de posts: #{posts.count}\n\n#{posts_data.to_json}"
98+
text: result.to_json
5999
} ])
60100
rescue StandardError => e
61101
MCP::Tool::Response.new([ {
62102
type: "text",
63-
text: "Erro ao listar posts: #{e.message}"
103+
text: { success: false, posts: [], total: 0, message: "Erro ao listar posts: #{e.message}" }.to_json
64104
} ])
65105
end
66106
end

app/tools/posts/show_tool.rb

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,60 @@ class ShowTool < MCP::Tool
1313
required: [ "id" ]
1414
)
1515

16+
output_schema(
17+
properties: {
18+
success: {
19+
type: "boolean",
20+
description: "Se a operação foi bem-sucedida"
21+
},
22+
post: {
23+
type: "object",
24+
properties: {
25+
id: { type: "integer" },
26+
title: { type: "string" },
27+
description: { type: "string" },
28+
created_at: { type: "string", format: "date-time" },
29+
updated_at: { type: "string", format: "date-time" }
30+
}
31+
},
32+
message: {
33+
type: "string",
34+
description: "Mensagem de retorno"
35+
}
36+
},
37+
required: [ "success", "message" ]
38+
)
39+
1640
def self.call(id:, server_context:)
1741
post = Post.find(id)
1842

19-
post_data = {
20-
id: post.id,
21-
title: post.title,
22-
description: post.description,
23-
created_at: post.created_at.iso8601,
24-
updated_at: post.updated_at.iso8601
43+
result = {
44+
success: true,
45+
post: {
46+
id: post.id,
47+
title: post.title,
48+
description: post.description,
49+
created_at: post.created_at.iso8601,
50+
updated_at: post.updated_at.iso8601
51+
},
52+
message: "Post encontrado com sucesso!"
2553
}
2654

55+
output_schema.validate_result(result)
56+
2757
MCP::Tool::Response.new([ {
2858
type: "text",
29-
text: "Post encontrado:\n#{post_data.to_json}"
59+
text: result.to_json
3060
} ])
3161
rescue ActiveRecord::RecordNotFound
3262
MCP::Tool::Response.new([ {
3363
type: "text",
34-
text: "Post com ID #{id} não encontrado"
64+
text: { success: false, message: "Post com ID #{id} não encontrado" }.to_json
3565
} ])
3666
rescue StandardError => e
3767
MCP::Tool::Response.new([ {
3868
type: "text",
39-
text: "Erro ao buscar post: #{e.message}"
69+
text: { success: false, message: "Erro ao buscar post: #{e.message}" }.to_json
4070
} ])
4171
end
4272
end

app/tools/posts/update_tool.rb

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,30 @@ class UpdateTool < MCP::Tool
2121
required: [ "id" ]
2222
)
2323

24+
output_schema(
25+
properties: {
26+
success: {
27+
type: "boolean",
28+
description: "Se a operação foi bem-sucedida"
29+
},
30+
post: {
31+
type: "object",
32+
properties: {
33+
id: { type: "integer" },
34+
title: { type: "string" },
35+
description: { type: "string" },
36+
created_at: { type: "string", format: "date-time" },
37+
updated_at: { type: "string", format: "date-time" }
38+
}
39+
},
40+
message: {
41+
type: "string",
42+
description: "Mensagem de retorno"
43+
}
44+
},
45+
required: [ "success", "message" ]
46+
)
47+
2448
def self.call(id:, title: nil, description: nil, server_context:)
2549
post = Post.find(id)
2650

@@ -31,30 +55,44 @@ def self.call(id:, title: nil, description: nil, server_context:)
3155
if update_params.empty?
3256
return MCP::Tool::Response.new([ {
3357
type: "text",
34-
text: "Nenhum campo fornecido para atualização"
58+
text: { success: false, message: "Nenhum campo fornecido para atualização" }.to_json
3559
} ])
3660
end
3761

3862
if post.update(update_params)
63+
result = {
64+
success: true,
65+
post: {
66+
id: post.id,
67+
title: post.title,
68+
description: post.description,
69+
created_at: post.created_at.iso8601,
70+
updated_at: post.updated_at.iso8601
71+
},
72+
message: "Post atualizado com sucesso!"
73+
}
74+
75+
output_schema.validate_result(result)
76+
3977
MCP::Tool::Response.new([ {
4078
type: "text",
41-
text: "Post atualizado com sucesso! ID: #{post.id}, Título: #{post.title}"
79+
text: result.to_json
4280
} ])
4381
else
4482
MCP::Tool::Response.new([ {
4583
type: "text",
46-
text: "Erro ao atualizar post: #{post.errors.full_messages.join(', ')}"
84+
text: { success: false, message: "Erro ao atualizar post: #{post.errors.full_messages.join(', ')}" }.to_json
4785
} ])
4886
end
4987
rescue ActiveRecord::RecordNotFound
5088
MCP::Tool::Response.new([ {
5189
type: "text",
52-
text: "Post com ID #{id} não encontrado"
90+
text: { success: false, message: "Post com ID #{id} não encontrado" }.to_json
5391
} ])
5492
rescue StandardError => e
5593
MCP::Tool::Response.new([ {
5694
type: "text",
57-
text: "Erro ao atualizar post: #{e.message}"
95+
text: { success: false, message: "Erro ao atualizar post: #{e.message}" }.to_json
5896
} ])
5997
end
6098
end

0 commit comments

Comments
 (0)