### Start D&D Knowledge Navigator Server Source: https://context7.com/procload/dnd-mcp/llms.txt These bash commands demonstrate how to launch the D&D Knowledge Navigator server using either the `uv` package manager (recommended) or standard Python execution after installation. The expected output confirms successful initialization. ```bash # Using uv (recommended) uv run python dnd_mcp_server.py # Or using pip installation pip install -e . python dnd_mcp_server.py # Expected output: # Starting D&D Knowledge Navigator with FastMCP... # Python version: 3.13.x # Current directory: /path/to/project # Creating FastMCP server... # FastMCP server created successfully # API cache initialized (24-hour TTL, persistent cache in cache/) # Registering D&D API resources... # D&D API resources registered successfully # Registering D&D API tools... # D&D API tools registered successfully # Running FastMCP app... ``` -------------------------------- ### Install uv and Set Up Python Environment Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Installs the 'uv' package manager and sets up a Python virtual environment for the project. It then installs MCP CLI and httpx dependencies. This is crucial for managing project dependencies and ensuring the correct Python environment is used. ```bash curl -LsSf https://astral.sh/uv/install.sh | sh uv init weather cd weather uv venv source .venv/bin/activate uv add "mcp[cli]" httpx touch weather.py ``` ```powershell powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" uv init weather cd weather uv venv .venv\Scripts\activate uv add mcp[cli] httpx new-item weather.py ``` -------------------------------- ### Project Initialization and Dependency Installation (PowerShell) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Creates a new project directory, initializes an npm project, installs necessary SDK and development dependencies, and sets up source files for Windows environments. ```powershell # Create a new directory for our project md weather cd weather # Initialize a new npm project npm init -y # Install dependencies npm install @modelcontextprotocol/sdk zod npm install -D @types/node typescript # Create our files md src new-item src\index.ts ``` -------------------------------- ### Project Initialization and Dependency Installation (Bash) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Creates a new project directory, initializes an npm project, installs necessary SDK and development dependencies, and sets up source files for MacOS and Linux environments. ```bash # Create a new directory for our project mkdir weather cd weather # Initialize a new npm project npm init -y # Install dependencies npm install @modelcontextprotocol/sdk zod npm install -D @types/node typescript # Create our files mkdir src touch src/index.ts ``` -------------------------------- ### MCP Server Implementation Example Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Basic examples demonstrating how to implement an MCP server using TypeScript and Python, including request handling and transport connection. ```APIDOC ## Implementation Example Here's a basic example of implementing an MCP server: ### TypeScript Example ```typescript import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; const server = new Server({ name: "example-server", version: "1.0.0" }, { capabilities: { resources: {} } }); // Handle requests server.setRequestHandler(ListResourcesRequestSchema, async () => { return { resources: [ { uri: "example://resource", name: "Example Resource" } ] }; }); // Connect transport const transport = new StdioServerTransport(); await server.connect(transport); ``` ### Python Example ```python import asyncio import mcp.types as types from mcp.server import Server from mcp.server.stdio import stdio_server app = Server("example-server") @app.list_resources() async def list_resources() -> list[types.Resource]: return [ types.Resource( uri="example://resource", name="Example Resource" ) ] async def main(): async with stdio_server() as streams: await app.run( streams[0], streams[1], app.create_initialization_options() ) if __name__ == "__main__": asyncio.run(main) ``` ``` -------------------------------- ### Python Package Installation for Development Source: https://github.com/procload/dnd-mcp/blob/main/README.md Instructions to clone the repository, set up a virtual environment, and install the D&D Knowledge Navigator package in development mode using pip. ```bash git clone https://github.com/yourusername/dnd-knowledge-navigator.git cd dnd-knowledge-navigator python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate pip install -e . ``` -------------------------------- ### MCP Stdio Transport Setup in TypeScript Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Provides examples for setting up the Standard Input/Output (stdio) transport for MCP in TypeScript, for both server and client applications. This transport is ideal for local integrations and command-line tools. ```typescript const server = new Server({ name: "example-server", version: "1.0.0" }, { capabilities: {} }); const transport = new StdioServerTransport(); await server.connect(transport); ``` ```typescript const client = new Client({ name: "example-client", version: "1.0.0" }, { capabilities: {} }); const transport = new StdioClientTransport({ command: "./server", args: ["--option", "value"] }); await client.connect(transport); ``` -------------------------------- ### MCP Client Roots Configuration Example Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md An example JSON configuration demonstrating how an MCP client might expose roots. This configuration suggests the server focus on specific local and remote resources, logically separating them. ```json { "roots": [ { "uri": "file:///home/user/projects/frontend", "name": "Frontend Repository" }, { "uri": "https://api.example.com/v1", "name": "API Endpoint" } ] } ``` -------------------------------- ### MCP Client Asynchronous API Example (Java) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Illustrates the use of the asynchronous API for the MCP Client, leveraging reactive programming principles. This example shows client creation with custom configurations, initialization, and chained asynchronous operations for listing tools, calling tools, managing resources, and interacting with prompts. It also includes handling root management and client closure. ```java import java.time.Duration; import java.util.Map; // Assuming necessary imports for McpAsyncClient, McpClient, ClientCapabilities, Mono, etc. // Assuming 'logger' is an initialized logger instance // Create an async client with custom configuration McpAsyncClient client = McpClient.async(transport) // 'transport' would be an initialized transport object .requestTimeout(Duration.ofSeconds(10)) .capabilities(ClientCapabilities.builder() .roots(true) // Enable roots capability .sampling() // Enable sampling capability .build()) .sampling(request -> Mono.just(new CreateMessageResult(response))) // 'response' would be defined elsewhere .toolsChangeConsumer(tools -> Mono.fromRunnable(() -> { logger.info("Tools updated: {}", tools); })) .resourcesChangeConsumer(resources -> Mono.fromRunnable(() -> { logger.info("Resources updated: {}", resources); })) .promptsChangeConsumer(prompts -> Mono.fromRunnable(() -> { logger.info("Prompts updated: {}", prompts); })) .build(); // Initialize connection and use features client.initialize() .flatMap(initResult -> client.listTools()) .flatMap(tools -> { return client.callTool(new CallToolRequest( "calculator", Map.of("operation", "add", "a", 2, "b", 3) )); }) .flatMap(result -> { return client.listResources() .flatMap(resources -> client.readResource(new ReadResourceRequest("resource://uri")) ); }) .flatMap(resource -> { return client.listPrompts() .flatMap(prompts -> client.getPrompt(new GetPromptRequest( "greeting", Map.of("name", "Spring") )) ); }) .flatMap(prompt -> { return client.addRoot(new Root("file:///path", "description")) .then(client.removeRoot("file:///path")); }) .doFinally(signalType -> { client.closeGracefully().subscribe(); }) .subscribe(); ``` -------------------------------- ### Install Dependencies with uv Source: https://github.com/procload/dnd-mcp/blob/main/README.md Installs project dependencies using the uv package manager. This is the recommended method for setting up the project environment. It reads dependencies from the requirements.txt file. ```bash uv pip install -r requirements.txt ``` -------------------------------- ### Run Python MCP Server with uvx or pip Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md These commands demonstrate how to run Python-based MCP servers. 'uvx' is the recommended method for managing Python environments, while 'pip' offers a traditional installation approach. The final command executes the installed server. ```bash # Using uvx uvx mcp-server-git ``` ```bash # Using pip pip install mcp-server-git python -m mcp_server_git ``` -------------------------------- ### Install NPM Globally Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Installs NPM globally on a system. This is a prerequisite for using the 'npx' command reliably, especially on Windows, and resolves potential errors related to NPM installation. ```bash npm install -g npm ``` -------------------------------- ### MCP Stdio Transport Setup in Python Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Demonstrates how to configure the Standard Input/Output (stdio) transport for MCP in Python, covering both server and client implementations. This setup is suitable for command-line tools and local process communication. ```python app = Server("example-server") async with stdio_server() as streams: await app.run( streams[0], streams[1], app.create_initialization_options() ) ``` ```python params = StdioServerParameters( command="./server", args=["--option", "value"] ) async with stdio_client(params) as streams: async with ClientSession(streams[0], streams[1]) as session: await session.initialize() ``` -------------------------------- ### Verify Node.js Installation (Bash) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md This command verifies the installed versions of Node.js and npm. It's a standard check to ensure the development environment is set up correctly for Node.js projects. ```bash node --version npm --version ``` -------------------------------- ### JSON: Example Sampling Request Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md An example JSON request for sampling, demonstrating the method, parameters, message structure, system prompt, context inclusion, and token limits. ```json { "method": "sampling/createMessage", "params": { "messages": [ { "role": "user", "content": { "type": "text", "text": "What files are in the current directory?" } } ], "systemPrompt": "You are a helpful file system assistant.", "includeContext": "thisServer", "maxTokens": 100 } } ``` -------------------------------- ### Run D&D Knowledge Navigator Server Source: https://github.com/procload/dnd-mcp/blob/main/docs/package_structure.md Command to start the main entry point for the D&D Knowledge Navigator server. ```bash python dnd_mcp_server.py ``` -------------------------------- ### Resource URI Template Example Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Illustrates a URI template for dynamic resources, following RFC 6570. This allows clients to construct valid resource URIs based on a provided template. ```uri-template {uriTemplate: string; // URI template following RFC 6570 name: string; // Human-readable name for this type description?: string; // Optional description mimeType?: string; // Optional MIME type for all matching resources} ``` -------------------------------- ### Source Attribution System Example (Python) Source: https://github.com/procload/dnd-mcp/blob/main/docs/articles/dndmcp.md Demonstrates how the source attribution system tracks information, including source, API endpoint, confidence level, and relevance score. This metadata is appended to Claude's responses for transparency. Dependencies include `attribution_manager`, `ConfidenceLevel`. ```python from enum import Enum class ConfidenceLevel(Enum): HIGH = "High" MEDIUM = "Medium" LOW = "Low" class AttributionManager: def add_attribution(self, source: str, api_endpoint: str, confidence: ConfidenceLevel, relevance_score: float, tool_used: str, metadata: dict = None) -> str: print(f"Adding attribution: Source={source}, Endpoint={api_endpoint}, Confidence={confidence.value}, Relevance={relevance_score}, Tool={tool_used}, Metadata={metadata}") # In a real system, this would generate a unique ID and store the attribution details. return "attribution_id_xyz" attribution_manager = AttributionManager() # Example of how attribution is added to responses attribution_id = attribution_manager.add_attribution( source="D&D 5e API", api_endpoint="/api/spells/fireball", confidence=ConfidenceLevel.HIGH, relevance_score=0.98, tool_used="search_all_categories", metadata={"spell_level": "3rd", "school": "evocation"} ) # The attribution appears in Claude's response like this: # (This is a representation of the output format, not executable code) # """ # Source: D&D 5e API # Endpoint: /api/spells/fireball # Confidence: High (Direct API match) # Relevance: 0.98 # """ ``` -------------------------------- ### Configure APPDATA Environment Variable (Windows) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Provides an example of how to configure the APPDATA environment variable within the 'env' key in 'claude_desktop_config.json' for Windows. This is necessary when server paths containing `${APPDATA}` fail to load. ```json { "brave-search": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-brave-search"], "env": { "APPDATA": "C:\\Users\\user\\AppData\\Roaming\\", "BRAVE_API_KEY": "..." } } } ``` -------------------------------- ### Run TypeScript MCP Server with npx Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md This command uses npx to directly run a TypeScript-based MCP server. It's a quick way to get started with MCP servers without local installation. ```bash npx -y @modelcontextprotocol/server-memory ``` -------------------------------- ### Set Up Python Environment for MCP Client Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md This snippet outlines the commands to initialize a Python project using `uv`, create a virtual environment, activate it, and install necessary packages like `mcp`, `anthropic`, and `python-dotenv`. It also includes steps for cleaning up boilerplate and creating the main client file. ```bash # Create project directory uv init mcp-client cd mcp-client # Create virtual environment uv venv # Activate virtual environment # On Windows: .venv\Scripts\activate # On Unix or MacOS: source .venv/bin/activate # Install required packages uv add mcp anthropic python-dotenv # Remove boilerplate files rm hello.py # Create our main file touch client.py ``` -------------------------------- ### Implement MCP Prompts in Python Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md This Python code illustrates how to build an MCP server with prompt functionality using the mcp.server library. It defines 'git-commit' and 'explain-code' prompts, similar to the TypeScript example, enabling the server to respond to requests for these prompts. The implementation uses decorators for handling list and get prompt requests. ```python from mcp.server import Server import mcp.types as types # Define available prompts PROMPTS = { "git-commit": types.Prompt( name="git-commit", description="Generate a Git commit message", arguments=[ types.PromptArgument( name="changes", description="Git diff or description of changes", required=True ) ], ), "explain-code": types.Prompt( name="explain-code", description="Explain how code works", arguments=[ types.PromptArgument( name="code", description="Code to explain", required=True ), types.PromptArgument( name="language", description="Programming language", required=False ) ], ) } # Initialize server app = Server("example-prompts-server") @app.list_prompts() async def list_prompts() -> list[types.Prompt]: return list(PROMPTS.values()) @app.get_prompt() async def get_prompt( name: str, arguments: dict[str, str] | None = None ) -> types.GetPromptResult: if name not in PROMPTS: raise ValueError(f"Prompt not found: {name}") if name == "git-commit": changes = arguments.get("changes") if arguments else "" return types.GetPromptResult( messages=[ types.PromptMessage( role="user", content=types.TextContent( type="text", text=f"Generate a concise but descriptive commit message " f"for these changes:\n\n{changes}" ) ) ] ) if name == "explain-code": code = arguments.get("code") if arguments else "" language = arguments.get("language", "Unknown") if arguments else "Unknown" return types.GetPromptResult( messages=[ types.PromptMessage( role="user", content=types.TextContent( type="text", ``` -------------------------------- ### Verify Node.js Installation (Bash) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md This command verifies if Node.js is installed on your system. If you receive an error, you need to download and install Node.js from the official website. ```bash node --version ``` -------------------------------- ### MCP Client Synchronous API Example (Java) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Demonstrates the usage of the synchronous API for the MCP Client. This includes creating a client with custom configurations, initializing the connection, and performing operations such as listing tools, calling tools, managing resources, and interacting with prompts. It also shows how to manage roots and gracefully close the client. ```java import java.time.Duration; import java.util.List; import java.util.Map; // Assuming necessary imports for McpSyncClient, McpClient, ClientCapabilities, etc. // Create a sync client with custom configuration McpSyncClient client = McpClient.sync(transport) // 'transport' would be an initialized transport object .requestTimeout(Duration.ofSeconds(10)) .capabilities(ClientCapabilities.builder() .roots(true) // Enable roots capability .sampling() // Enable sampling capability .build()) .sampling(request -> new CreateMessageResult(response)) // 'response' would be defined elsewhere .build(); // Initialize connection client.initialize(); // List available tools ListToolsResult tools = client.listTools(); // Call a tool CallToolResult result = client.callTool( new CallToolRequest("calculator", Map.of("operation", "add", "a", 2, "b", 3)) ); // List and read resources ListResourcesResult resources = client.listResources(); ReadResourceResult resource = client.readResource( new ReadResourceRequest("resource://uri") ); // List and use prompts ListPromptsResult prompts = client.listPrompts(); GetPromptResult prompt = client.getPrompt( new GetPromptRequest("greeting", Map.of("name", "Spring")) ); // Add/remove roots client.addRoot(new Root("file:///path", "description")); client.removeRoot("file:///path"); // Close client client.closeGracefully(); ``` -------------------------------- ### Create MCP Client and Call Tools (Java) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Demonstrates how to create an MCP client in Java to connect to a server via STDIO transport. It shows initializing the client, listing available tools, and calling the `getWeatherForecastByLocation` and `getAlerts` tools with specific parameters. ```java var stdioParams = ServerParameters.builder("java") .args("-jar", "/ABSOLUTE/PATH/TO/PARENT/FOLDER/mcp-weather-stdio-server-0.0.1-SNAPSHOT.jar") .build(); var stdioTransport = new StdioClientTransport(stdioParams); var mcpClient = McpClient.sync(stdioTransport).build(); mcpClient.initialize(); ListToolsResult toolsList = mcpClient.listTools(); CallToolResult weather = mcpClient.callTool( new CallToolRequest("getWeatherForecastByLocation", Map.of("latitude", "47.6062", "longitude", "-122.3321"))); CallToolResult alert = mcpClient.callTool( new CallToolRequest("getAlerts", Map.of("state", "NY"))); mcpClient.closeGracefully(); ``` -------------------------------- ### Install D&D Knowledge Navigator Package Source: https://github.com/procload/dnd-mcp/blob/main/docs/package_structure.md Commands to install the D&D Knowledge Navigator package using pip. Supports both development mode and regular installation. ```bash pip install -e . pip install . ``` -------------------------------- ### Install Dependencies with pip Source: https://github.com/procload/dnd-mcp/blob/main/README.md Installs project dependencies using the standard pip package manager. This is an alternative method if uv is not available or preferred. It installs the package in editable mode. ```bash pip install . ``` -------------------------------- ### Implement MCP Resource Server Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Provides example implementations for an MCP server handling resource listing and reading operations. It demonstrates setting request handlers for listing available resources and reading specific resource contents, including error handling for unknown resources. ```typescript const server = new Server({ name: "example-server", version: "1.0.0" }, { capabilities: { resources: {} } }); // List available resources server.setRequestHandler(ListResourcesRequestSchema, async () => { return { resources: [ { uri: "file:///logs/app.log", name: "Application Logs", mimeType: "text/plain" } ] }; }); // Read resource contents server.setRequestHandler(ReadResourceRequestSchema, async (request) => { const uri = request.params.uri; if (uri === "file:///logs/app.log") { const logContents = await readLogFile(); return { contents: [ { uri, mimeType: "text/plain", text: logContents } ] }; } throw new Error("Resource not found"); }); ``` ```python app = Server("example-server") @app.list_resources() async def list_resources() -> list[types.Resource]: return [ types.Resource( uri="file:///logs/app.log", name="Application Logs", mimeType="text/plain" ) ] @app.read_resource() async def read_resource(uri: AnyUrl) -> str: if str(uri) == "file:///logs/app.log": log_contents = await read_log_file() return log_contents raise ValueError("Resource not found") # Start server async with stdio_server() as streams: await app.run( streams[0], streams[1], app.create_initialization_options() ) ``` -------------------------------- ### Interact with Prompt System (Java) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Illustrates how to discover available prompt templates and execute them with custom parameters using the synchronous MCP client API. This allows for dynamic text generation. ```java var prompts = client.listPrompts(); prompts.forEach(prompt -> System.out.println(prompt.getName())); var response = client.executePrompt("echo", Map.of( "text", "Hello, World!" )); ``` -------------------------------- ### MCP Server Sync API Implementation in Java Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Demonstrates how to create and configure a synchronous MCP server. This includes setting server information, defining capabilities, registering tools, resources, and prompts, sending logging notifications, and closing the server. It relies on the MCP SDK and a transport implementation. ```java import io.modelcontextprotocol.sdk.server.McpServer; import io.modelcontextprotocol.sdk.server.McpSyncServer; import io.modelcontextprotocol.sdk.server.ServerCapabilities; import io.modelcontextprotocol.sdk.transport.Transport; import io.modelcontextprotocol.sdk.logging.LoggingMessageNotification; import io.modelcontextprotocol.sdk.logging.LoggingLevel; // Assume 'transport' is an initialized Transport object // Assume 'syncToolRegistration', 'syncResourceRegistration', 'syncPromptRegistration' are properly defined // Create a server with custom configuration McpSyncServer syncServer = McpServer.sync(transport) .serverInfo("my-server", "1.0.0") .capabilities(ServerCapabilities.builder() .resources(true) // Enable resource support .tools(true) // Enable tool support .prompts(true) // Enable prompt support .logging() // Enable logging support .build()) .build(); // Register tools, resources, and prompts syncServer.addTool(syncToolRegistration); syncServer.addResource(syncResourceRegistration); syncServer.addPrompt(syncPromptRegistration); // Send logging notifications syncServer.loggingNotification(LoggingMessageNotification.builder() .level(LoggingLevel.INFO) .logger("custom-logger") .data("Server initialized") .build()); // Close the server when done syncServer.close(); ``` -------------------------------- ### Main Entry Point and Execution (Python) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Defines the main execution block for the client script. It handles command-line arguments for the server path, initializes the MCPClient, connects to the server, runs the chat loop, and ensures cleanup occurs. ```python async def main(): if len(sys.argv) < 2: print("Usage: python client.py ") sys.exit(1) client = MCPClient() try: await client.connect_to_server(sys.argv[1]) await client.chat_loop() finally: await client.cleanup() if __name__ == "__main__": import sys asyncio.run(main()) ``` -------------------------------- ### MCP Server Async API Implementation in Java Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Illustrates the creation and configuration of an asynchronous MCP server using reactive programming principles. This involves setting server details, capabilities, registering components, sending notifications, and managing the server lifecycle with reactive streams. Dependencies include the MCP SDK and a transport implementation. ```java import io.modelcontextprotocol.sdk.server.McpServer; import io.modelcontextprotocol.sdk.server.McpAsyncServer; import io.modelcontextprotocol.sdk.server.ServerCapabilities; import io.modelcontextprotocol.sdk.transport.Transport; import io.modelcontextprotocol.sdk.logging.LoggingMessageNotification; import io.modelcontextprotocol.sdk.logging.LoggingLevel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // Assume 'transport' is an initialized Transport object // Assume 'asyncToolRegistration', 'asyncResourceRegistration', 'asyncPromptRegistration' are properly defined private static final Logger logger = LoggerFactory.getLogger(MyAsyncServer.class); // Create an async server with custom configuration McpAsyncServer asyncServer = McpServer.async(transport) .serverInfo("my-server", "1.0.0") .capabilities(ServerCapabilities.builder() .resources(true) // Enable resource support .tools(true) // Enable tool support .prompts(true) // Enable prompt support .logging() // Enable logging support .build()) .build(); // Register tools, resources, and prompts asyncServer.addTool(asyncToolRegistration) .doOnSuccess(v -> logger.info("Tool registered")) .subscribe(); asyncServer.addResource(asyncResourceRegistration) .doOnSuccess(v -> logger.info("Resource registered")) .subscribe(); asyncServer.addPrompt(asyncPromptRegistration) .doOnSuccess(v -> logger.info("Prompt registered")) .subscribe(); // Send logging notifications asyncServer.loggingNotification(LoggingMessageNotification.builder() .level(LoggingLevel.INFO) .logger("custom-logger") .data("Server initialized") .build()); // Close the server when done asyncServer.close() .doOnSuccess(v -> logger.info("Server closed")) .subscribe(); ``` -------------------------------- ### Manage Filesystem Roots (Java) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Demonstrates how to manage filesystem roots for the MCP client, including adding new roots, removing existing ones, and notifying the server of changes. Roots define the accessible filesystem boundaries for servers. ```java // Add a root dynamically client.addRoot(new Root("file:///path", "description")); // Remove a root client.removeRoot("file:///path"); // Notify server of roots changes client.rootsListChangedNotification(); ``` -------------------------------- ### Install FastMCP and Dependencies Source: https://github.com/procload/dnd-mcp/blob/main/docs/architecture.md Installs the FastMCP framework and the requests library using pip. These are essential for building the Python-based server and making HTTP requests to the D&D 5e API. ```bash pip install fastmcp pip install requests ``` -------------------------------- ### Configure Client Capabilities (Java) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Builds a ClientCapabilities object to enable specific features for the MCP client. Options include filesystem roots support with notifications and LLM sampling. ```java var capabilities = ClientCapabilities.builder() .roots(true) // Enable filesystem roots support with list changes notifications .sampling() // Enable LLM sampling support .build(); ``` -------------------------------- ### Get Weather Forecast using TypeScript Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Retrieves and formats the weather forecast for a specified location using latitude and longitude. It makes requests to the NWS API to get grid point and forecast data, handling potential errors and formatting the output. Dependencies include NWS API endpoints and request functions. ```typescript server.tool( "get-forecast", "Get weather forecast for a location", { latitude: z.number().min(-90).max(90).describe("Latitude of the location"), longitude: z.number().min(-180).max(180).describe("Longitude of the location"), }, async ({ latitude, longitude }) => { // Get grid point data const pointsUrl = `${NWS_API_BASE}/points/${latitude.toFixed(4)},${longitude.toFixed(4)}`; const pointsData = await makeNWSRequest(pointsUrl); if (!pointsData) { return { content: [ { type: "text", text: `Failed to retrieve grid point data for coordinates: ${latitude}, ${longitude}. This location may not be supported by the NWS API (only US locations are supported).`, }, ], }; } const forecastUrl = pointsData.properties?.forecast; if (!forecastUrl) { return { content: [ { type: "text", text: "Failed to get forecast URL from grid point data", }, ], }; } // Get forecast data const forecastData = await makeNWSRequest(forecastUrl); if (!forecastData) { return { content: [ { type: "text", text: "Failed to retrieve forecast data", }, ], }; } const periods = forecastData.properties?.periods || []; if (periods.length === 0) { return { content: [ { type: "text", text: "No forecast periods available", }, ], }; } // Format forecast periods const formattedForecast = periods.map((period: ForecastPeriod) => [ `${period.name || "Unknown"}:`, `Temperature: ${period.temperature || "Unknown"}°${period.temperatureUnit || "F"}`, `Wind: ${period.windSpeed || "Unknown"} ${period.windDirection || ""}`, `${period.shortForecast || "No forecast available"}`, "---", ].join("\n"), ); const forecastText = `Forecast for ${latitude}, ${longitude}:\n\n${formattedForecast.join("\n")}`; return { content: [ { type: "text", text: forecastText, }, ], }; }, ); ``` -------------------------------- ### Get Weather Forecast API Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Retrieves the weather forecast for a given latitude and longitude. ```APIDOC ## GET /procload/dnd-mcp/forecast ### Description Fetches the weather forecast for a specified geographical location using latitude and longitude. ### Method GET ### Endpoint /procload/dnd-mcp/forecast ### Parameters #### Query Parameters - **latitude** (number) - Required - The latitude of the location (between -90 and 90). - **longitude** (number) - Required - The longitude of the location (between -180 and 180). ### Response #### Success Response (200) - **content** (array) - An array of content objects, typically containing text with forecast information. - **type** (string) - The type of content, e.g., "text". - **text** (string) - The formatted forecast information. #### Response Example ```json { "content": [ { "type": "text", "text": "Forecast for 40.7128, -74.0060:\n\nTonight:\nTemperature: 55°F\nWind: 10 mph W\nPartly cloudy\n---\nTomorrow:\nTemperature: 68°F\nWind: 15 mph SW\nSunny\n---" } ] } ``` #### Error Response Example ```json { "content": [ { "type": "text", "text": "Failed to retrieve grid point data for coordinates: 91, -74. This location may not be supported by the NWS API (only US locations are supported)." } ] } ``` ``` -------------------------------- ### Get Active Alerts API Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Retrieves active weather alerts for a specified state code. ```APIDOC ## GET /procload/dnd-mcp/alerts ### Description Fetches active weather alerts for a given state code. ### Method GET ### Endpoint /procload/dnd-mcp/alerts ### Parameters #### Query Parameters - **stateCode** (string) - Required - The state code for which to retrieve alerts. ### Response #### Success Response (200) - **content** (array) - An array of content objects, typically containing text with alert information. - **type** (string) - The type of content, e.g., "text". - **text** (string) - The formatted alert information or a message indicating no active alerts. #### Response Example ```json { "content": [ { "type": "text", "text": "Active alerts for CA:\n\nPacific Northwest: High Wind Warning\nValid: Until 10 PM PDT on October 26, 2023\nDetails: Strong winds expected..." } ] } ``` #### Error Response Example ```json { "content": [ { "type": "text", "text": "No active alerts for TX" } ] } ``` ``` -------------------------------- ### Initialize MCP Server and Import Dependencies (TypeScript) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Imports necessary classes from the @modelcontextprotocol/sdk for creating a server and transport, and the 'zod' library for schema validation. It also sets up constants for the NWS API and creates an instance of the McpServer. ```typescript import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; const NWS_API_BASE = "https://api.weather.gov"; const USER_AGENT = "weather-app/1.0"; // Create server instance const server = new McpServer({ name: "weather", version: "1.0.0", }); ``` -------------------------------- ### GET /item_details Source: https://github.com/procload/dnd-mcp/blob/main/docs/architecture.md Retrieves detailed information for a specific D&D 5e item using its URI. ```APIDOC ## GET /item_details ### Description Retrieves detailed information for a specific D&D 5e item using its URI. The data is cached for performance. ### Method GET ### Endpoint /item_details ### Parameters #### Query Parameters - **uri** (string) - Required - The full URI of the item for which to retrieve details. ### Response #### Success Response (200) - **contents** (string) - A stringified JSON object containing the detailed data for the item. #### Response Example ```json { "contents": "{\"index\": \"amulet-of-health\", \"name\": \"Amulet of Health\", \"equipment_category\": {\"index\": \"clothing\", \"name\": \"Clothing\", \"url\": \"/api/equipment-categories/clothing\"}, \"weight\": 1, \"cost\": {\"quantity\": 500, \"unit\": \"gp\", \"వెయిట్\": \"gp\"}, \"desc\": [\"While wearing this amulet, you gain a bonus to your Armor Class equal to your Constitution modifier.\"], \"special\": [\"Requires attunement\"], \"id\": \"amulet-of-health\"}" } ``` ``` -------------------------------- ### WebFlux Starter Dependency for MCP Client Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md This dependency is for WebFlux-based applications and enables the integration of Spring AI with an MCP client using a WebFlux-based SSE transport. It is recommended for production deployments requiring reactive programming. ```xml org.springframework.ai spring-ai-mcp-client-webflux-spring-boot-starter ``` -------------------------------- ### D&D 5e API Prompts Source: https://github.com/procload/dnd-mcp/blob/main/docs/architecture.md Templates for LLM prompts to guide interactions with D&D 5e data. ```APIDOC ## POST /api/prompts/describe_item ### Description Generates a descriptive prompt template for an item, suitable for LLM guidance. ### Method POST ### Endpoint /api/prompts/describe_item ### Parameters #### Query Parameters None #### Request Body - **item_name** (string) - Required - The name of the item to generate a description prompt for. ### Request Example ```json { "example": { "item_name": "Wand" } } ``` ### Response #### Success Response (200) - **name** (string) - The name of the prompt. - **description** (string) - The prompt template. - **arguments** (array) - Arguments required by the prompt. - **name** (string) - The name of the argument. - **required** (boolean) - Whether the argument is required. #### Response Example ```json { "example": { "name": "describe_item", "description": "Describe the D&D 5e item: {item_name}. Include its cost, weight, and any special properties.", "arguments": [ { "name": "item_name", "required": true } ] } } ``` ``` -------------------------------- ### Implement Basic Tool in MCP Server (TypeScript) Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Demonstrates how to implement a basic 'calculate_sum' tool in an MCP server using TypeScript. It covers defining available tools and handling tool execution requests. This requires the 'Server' class and schema definitions for requests. ```typescript const server = new Server({ name: "example-server", version: "1.0.0" }, { capabilities: { tools: {} } }); // Define available tools server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [{ name: "calculate_sum", description: "Add two numbers together", inputSchema: { type: "object", properties: { a: { type: "number" }, b: { type: "number" } }, required: ["a", "b"] } }] }; }); // Handle tool execution server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === "calculate_sum") { const { a, b } = request.params.arguments; return { content: [ { type: "text", text: String(a + b) } ] }; } throw new Error("Tool not found"); }); ``` -------------------------------- ### GET /categories Source: https://github.com/procload/dnd-mcp/blob/main/docs/architecture.md Retrieves a list of available D&D 5e resource categories, including their names, descriptions, and URIs. ```APIDOC ## GET /categories ### Description Retrieves a list of available D&D 5e resource categories, including their names, descriptions, and URIs. ### Method GET ### Endpoint /categories ### Parameters #### Query Parameters - **max_items** (integer) - Optional - The maximum number of items to return per category. ### Response #### Success Response (200) - **name** (string) - The name of the category. - **description** (string) - A brief description of the category. - **uri** (string) - The API endpoint URI for this category. #### Response Example ```json [ { "name": "equipment", "description": "Gear and items for adventuring in D&D 5e", "uri": "https://www.dnd5eapi.co/api/equipment" }, { "name": "races", "description": "Playable races with proficiencies and traits", "uri": "https://www.dnd5eapi.co/api/races" } ] ``` ``` -------------------------------- ### Implement MCP Server in Python Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Shows a basic implementation of an MCP server in Python using the 'mcp' library. It includes setting up a resource listing endpoint and running the server over stdio transport. Requires the 'mcp' library. ```python import asyncio import mcp.types as types from mcp.server import Server from mcp.server.stdio import stdio_server app = Server("example-server") @app.list_resources() async def list_resources() -> list[types.Resource]: return [ types.Resource( uri="example://resource", name="Example Resource" ) ] async def main(): async with stdio_server() as streams: await app.run( streams[0], streams[1], app.create_initialization_options() ) if __name__ == "__main__": asyncio.run(main) ``` -------------------------------- ### Multi-step Workflows Source: https://github.com/procload/dnd-mcp/blob/main/mcp.md Illustrates how to implement multi-step workflows for prompts, allowing for sequential interactions and context building between the user and the assistant. ```APIDOC ## Multi-step Workflows ### Description This section describes the implementation of multi-step workflows, where prompts can involve a series of back-and-forth messages between the user and the assistant to achieve a complex task or gather detailed information. ### Example (TypeScript) ```typescript const debugWorkflow = { name: "debug-error", async getMessages(error: string) { return [ { role: "user", content: { type: "text", text: `Here's an error I'm seeing: ${error}`, }, }, { role: "assistant", content: { type: "text", text: "I'll help analyze this error. What have you tried so far?", }, }, { role: "user", content: { type: "text", text: "I've tried restarting the service, but the error persists.", }, }, ]; }, }; ``` ```