Skip to main content
Glama
main.py6.94 kB
import asyncio # Optional MCP SDK import with graceful fallback (supports both package names) _MCP_IMPORT_ERROR = None Server = None # type: ignore Tool = None # type: ignore TextContent = None # type: ignore stdio_server = None # type: ignore # Try the canonical 'mcp' package name first try: from mcp.server import Server # type: ignore from mcp.types import Tool, TextContent # type: ignore from mcp.server.stdio import stdio_server # type: ignore except Exception as _e1: # Fallback to the alternative package name used by some distributions try: from modelcontextprotocol.server import Server # type: ignore from modelcontextprotocol.types import Tool, TextContent # type: ignore from modelcontextprotocol.server.stdio import stdio_server # type: ignore except Exception as _e2: _MCP_IMPORT_ERROR = (_e1, _e2) from pydantic import BaseModel from typing import Dict, List, Any import json # Book model class Book(BaseModel): title: str author: str # In-memory storage books: Dict[int, Book] = {} next_id = 1 def _init_sample_books(): global next_id samples = [ {"title": "The Great Gatsby", "author": "F. Scott Fitzgerald"}, {"title": "To Kill a Mockingbird", "author": "Harper Lee"}, {"title": "1984", "author": "George Orwell"}, {"title": "Pride and Prejudice", "author": "Jane Austen"}, {"title": "Moby-Dick", "author": "Herman Melville"}, ] for book in samples: books[next_id] = Book(**book) next_id += 1 _init_sample_books() # Create MCP server (guarded if MCP SDK missing) if Server is None: # type: ignore raise SystemExit( "Missing dependency: MCP Python SDK is required to run this MCP server.\n" "Install one of the following package names (depends on distribution):\n" " - pip install mcp\n" " - pip install modelcontextprotocol\n" "Docs: https://github.com/modelcontextprotocol/python-sdk\n" f"Original import errors: {_MCP_IMPORT_ERROR}" ) server = Server("books-library") @server.list_tools() async def list_tools() -> List[Tool]: return [ Tool( name="get_books", description="Get all books from the library", inputSchema={ "type": "object", "properties": {}, } ), Tool( name="get_book", description="Get a specific book by ID", inputSchema={ "type": "object", "properties": { "book_id": {"type": "integer", "description": "The ID of the book"} }, "required": ["book_id"] } ), Tool( name="create_book", description="Create a new book in the library", inputSchema={ "type": "object", "properties": { "title": {"type": "string", "description": "The title of the book"}, "author": {"type": "string", "description": "The author of the book"} }, "required": ["title", "author"] } ), Tool( name="update_book", description="Update an existing book in the library", inputSchema={ "type": "object", "properties": { "book_id": {"type": "integer", "description": "The ID of the book to update"}, "title": {"type": "string", "description": "The new title of the book"}, "author": {"type": "string", "description": "The new author of the book"} }, "required": ["book_id", "title", "author"] } ), Tool( name="delete_book", description="Delete a book from the library by ID", inputSchema={ "type": "object", "properties": { "book_id": {"type": "integer", "description": "The ID of the book to delete"} }, "required": ["book_id"] } ) ] @server.call_tool() async def call_tool(name: str, arguments: Dict[str, Any]) -> List[TextContent]: try: if name == "get_books": if not books: return [TextContent(type="text", text="No books found in the library.")] book_list = [] for book_id, book in books.items(): book_list.append(f"ID: {book_id}, Title: {book.title}, Author: {book.author}") return [TextContent(type="text", text=f"Books in library:\n" + "\n".join(book_list))] elif name == "get_book": book_id = arguments["book_id"] if book_id not in books: return [TextContent(type="text", text=f"Book with ID {book_id} not found.")] book = books[book_id] return [TextContent(type="text", text=f"Book ID {book_id}:\nTitle: {book.title}\nAuthor: {book.author}")] elif name == "create_book": global next_id book = Book(title=arguments["title"], author=arguments["author"]) book_id = next_id books[book_id] = book next_id += 1 return [TextContent(type="text", text=f"Successfully created book with ID {book_id}:\nTitle: {book.title}\nAuthor: {book.author}")] elif name == "update_book": book_id = arguments["book_id"] if book_id not in books: return [TextContent(type="text", text=f"Book with ID {book_id} not found.")] book = Book(title=arguments["title"], author=arguments["author"]) books[book_id] = book return [TextContent(type="text", text=f"Successfully updated book ID {book_id}:\nTitle: {book.title}\nAuthor: {book.author}")] elif name == "delete_book": book_id = arguments["book_id"] if book_id not in books: return [TextContent(type="text", text=f"Book with ID {book_id} not found.")] deleted_book = books[book_id] del books[book_id] return [TextContent(type="text", text=f"Successfully deleted book:\nTitle: {deleted_book.title}\nAuthor: {deleted_book.author}")] else: return [TextContent(type="text", text=f"Unknown tool: {name}")] except Exception as e: return [TextContent(type="text", text=f"Error executing tool {name}: {str(e)}")] async def main(): async with stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, server.create_initialization_options() ) if __name__ == "__main__": asyncio.run(main())

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SaraNazeer27/MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server