1 min read

Agentic AI with Ruby

Using the Model Context Protocol (MCP) to augment LLM capabilities
Agentic AI with Ruby
Photo by Chris Yang / Unsplash

The Model Context Protocol (MCP) allows you describe how to use tools for Large Language Models. I'm going to build a MCP server which will let a LLM use my open source Cucumber linter, Chutney.

I'm going to use the fast-mcp library which makes the construction of a MCP Server trivial.

require 'chutney'
require 'fast_mcp'

class ChutneyTool < FastMcp::Tool
  description <<~DESCRIPTION
    Chutney is a tool for linting Gherkin files and making sure they
    conform to the standards set out by the organisation.
  DESCRIPTION
  tool_name 'Chutney'

  arguments do
    required(:filename)
      .filled(:string)
      .description('The absolute full path of the Cucumber feature file to lint, not a relative path')
  end

  def call(filename:)
    linter = Chutney::ChutneyLint.new(filename)
    report = linter.analyse
    report.to_h
  end
end

Creating a Tool

Here we create a class which defines a tool, in this case Chutney. I provide it a description which will be read by the LLM. I also give it a name – this is important because without an explicit name, it will use the class name and, if you are using modules, the :: module separator will appear in the name and VS Code doesn't like this.

Chutney needs a filename as an argument. The tool describes the parameter is wants and what type it is. It also gives the LLM a description of what this parameter actually is. Chat GPT models insisted on providing a relative path until it was explicitly told not to.

The only thing left to do is to implement the call method. I won't get into the details of Chutney, but given a filename, the code above will return a JSON response with details of any linting violations. You'll see that I'm not giving any details about the content or meaning of this response – LLMs are smart enough to interpret this without any decoration.

The only thing left to do is to register the tool and start the server.

server = FastMcp::Server.new(name: 'ChutneyMCP', version: '1.0.0')
server.register_tool(ChutneyTool)

server.start

That's it, Fast-MCP will create a server listening on STDIO.