MCP Tools
Live on this serverProvides tools to AI agents such as Claude via the Model Context Protocol.
A library that AI agents such as Claude can use: it offers tools to find books and to lend them to readers,
via the Model Context Protocol (MCP). Every method of LibraryTools marked with [Tool] is a tool. Its name,
its parameters and the [Summary] texts tell the agent what the tool does and how to call it, and [Range]
limits what it may pass.
Add the server to your agent (see the commands below) and ask it, for example, which books about Rome the
library has: the agent finds them with find_books, and may lend one with lend_book.
To run it, create a console app (dotnet new console), add GenHTTP (dotnet add package GenHTTP.Full), replace Program.cs with the code below and start it with dotnet run - it answers at http://localhost:8080/.
using System.ComponentModel.DataAnnotations;
using GenHTTP.Engine.Internal;
using GenHTTP.Api.Content;
using GenHTTP.Api.Content.Documentation;
using GenHTTP.Api.Protocol;
using GenHTTP.Modules.Mcp;
using GenHTTP.Modules.Practices;
var app = Tools.Create()
.Server("library", "1.0.0", "Library")
.Instructions("Search for books before lending them to a reader.")
.Add<LibraryTools>()
.Add("get_time", "Returns the current time of the library (UTC)", [Tool(ReadOnly = true)] () => DateTime.UtcNow);
await Host.Create()
.Handler(app)
.Defaults()
.RunAsync();
public record Book(int Id, string Title, string? LentTo);
public class LibraryTools
{
private static readonly List<Book> Books =
[
new(1, "SPQR: A History of Ancient Rome", null),
new(2, "The Lord of the Rings", null)
];
[Tool(ReadOnly = true)]
[Summary("Searches the books of the library by title")]
public List<Book> FindBooks([Summary("Part of the title, e.g. 'Rome'")] string query, [Range(1, 50)] int limit = 10)
{
lock (Books) return Books.Where(b => b.Title.Contains(query, StringComparison.OrdinalIgnoreCase)).Take(limit).ToList();
}
[Tool(Destructive = false)]
[Summary("Lends a book to a reader")]
public Book LendBook([Summary("The id of the book, as returned by find_books")] int bookId, [Summary("The name of the reader")] string reader)
{
lock (Books)
{
var book = Books.FirstOrDefault(b => b.Id == bookId)
?? throw new ProviderException(ResponseStatus.NotFound, $"There is no book with id {bookId}.");
if (book.LentTo != null)
{
throw new ProviderException(ResponseStatus.Conflict, $"'{book.Title}' is already lent to {book.LentTo}.");
}
var lent = book with { LentTo = reader };
Books[Books.IndexOf(book)] = lent;
return lent;
}
}
}
Try it
Send the requests to the sample running on this server - change the path, headers or body as you like, or copy them as curl commands.
Add the server to Claude Code
Then ask Claude "Which books about Rome are in the library?"
claude mcp add --transport http library https://genhttp.org/demo/mcp/List the tools, as an agent would
curl -i -X POST -H 'Content-Type: application/json' -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }' 'https://genhttp.org/demo/mcp/'Call a tool
curl -i -X POST -H 'Content-Type: application/json' -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "find_books", "arguments": { "query": "Rome" } } }' 'https://genhttp.org/demo/mcp/'