Class: VectorMCP::Rails::Tool

Inherits:
Tool
  • Object
show all
Defined in:
lib/vector_mcp/rails/tool.rb

Overview

Rails-aware base class for declarative tool definitions.

Adds ergonomics for the common patterns that show up in ActiveRecord- backed MCP tools:

  • find! -- fetch a record or raise VectorMCP::NotFoundError
  • respond_with -- standard success/error payload from a record
  • with_transaction -- wrap a mutation in an AR transaction
  • Auto-rescue of ActiveRecord::RecordNotFound (-> NotFoundError) and ActiveRecord::RecordInvalid (-> error payload)
  • Arguments delivered to #call as a HashWithIndifferentAccess so args[:id] and args["id"] both work

Examples:

class UpdateProvider < VectorMCP::Rails::Tool
  tool_name   "update_provider"
  description "Update an existing provider"

  param :id,   type: :integer, required: true
  param :name, type: :string

  def call(args, _session)
    provider = find!(Provider, args[:id])
    provider.update(args.except(:id))
    respond_with(provider, name: provider.name)
  end
end

Instance Method Summary collapse

Instance Method Details

#find!(model, id) ⇒ ActiveRecord::Base

Finds a record by id or raises VectorMCP::NotFoundError.

Parameters:

  • model (Class)

    an ActiveRecord model class

  • id (Integer, String)

    the record id

Returns:

  • (ActiveRecord::Base)


58
59
60
61
# File 'lib/vector_mcp/rails/tool.rb', line 58

def find!(model, id)
  model.find_by(id: id) ||
    raise(VectorMCP::NotFoundError, "#{model.name} #{id} not found")
end

#respond_with(record, **extras) ⇒ Hash

Builds a standard response payload from a record.

Success shape: { success: true, id: record.id, **extras } Error shape: { success: false, errors: record.errors.full_messages }

Parameters:

  • record (ActiveRecord::Base)
  • extras (Hash)

    additional keys to merge into the success payload

Returns:

  • (Hash)


71
72
73
74
75
76
77
# File 'lib/vector_mcp/rails/tool.rb', line 71

def respond_with(record, **extras)
  if record.persisted? && record.errors.empty?
    { success: true, id: record.id, **extras }
  else
    { success: false, errors: record.errors.full_messages }
  end
end

#with_transactionObject

Runs the given block inside an ActiveRecord transaction.



80
81
82
# File 'lib/vector_mcp/rails/tool.rb', line 80

def with_transaction(&)
  ActiveRecord::Base.transaction(&)
end