### Configure Environment Variables Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/README.md Initialize the .env file from the provided example. ```bash cp .env.example .env ``` -------------------------------- ### Install Zettelkasten MCP Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/README.md Clone the repository and set up the environment using uv. ```bash # Clone the repository git clone https://github.com/entanglr/zettelkasten-mcp.git cd zettelkasten-mcp # Create a virtual environment with uv uv venv source .venv/bin/activate # On Windows: .venv\Scripts\activate # Install dependencies uv add "mcp[cli]" # Install dev dependencies uv sync --all-extras ``` -------------------------------- ### Start the MCP Server Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/README.md Run the server using the default configuration or with custom paths. ```bash python -m zettelkasten_mcp.main ``` ```bash python -m zettelkasten_mcp.main --notes-dir ./data/notes --database-path ./data/db/zettelkasten.db ``` -------------------------------- ### Initialize project and environment Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Commands to create a new project directory, set up a virtual environment, and install dependencies. ```bash # Create a new directory for our project uv init weather cd weather # Create virtual environment and activate it uv venv source .venv/bin/activate # Install dependencies uv add "mcp[cli]" httpx # Create our server file touch weather.py ``` ```powershell # Create a new directory for our project uv init weather cd weather # Create virtual environment and activate it uv venv .venv\Scripts\activate # Install dependencies uv add mcp[cli] httpx # Create our server file new-item weather.py ``` -------------------------------- ### Define main entry point Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Initializes the MCP client and starts the chat loop with the provided server path. ```kotlin fun main(args: Array) = runBlocking { if (args.isEmpty()) throw IllegalArgumentException("Usage: java -jar /build/libs/kotlin-mcp-client-0.1.0-all.jar ") val serverPath = args.first() val client = MCPClient() client.use { client.connectToServer(serverPath) client.chatLoop() } } ``` -------------------------------- ### Configure Server Paths Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Examples of providing relative, absolute, and Windows-specific paths to the MCP server. ```bash # Relative path java -jar build/libs/client.jar ./server/build/libs/server.jar # Absoulute path java -jar build/libs/client.jar /Users/username/projects/mcp-server/build/libs/server.jar # Windows path (either format works) java -jar build/libs/client.jar C:/projects/mcp-server/build/libs/server.jar java -jar build/libs/client.jar C:\\projects\\mcp-server\\build\\libs\\server.jar ``` -------------------------------- ### Install npx Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Global installation of the npx package manager. ```bash npm install -g npx ``` -------------------------------- ### Initialize Python Project with uv Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Commands to set up a new virtual environment and install necessary dependencies for an MCP client. ```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 ``` -------------------------------- ### Create a simple MCP server Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Example of defining a server with a tool and a dynamic resource using FastMCP. ```python # server.py from mcp.server.fastmcp import FastMCP # Create an MCP server mcp = FastMCP("Demo") # Add an addition tool @mcp.tool() def add(a: int, b: int) -> int: """Add two numbers""" return a + b # Add a dynamic greeting resource @mcp.resource("greeting://{name}") def get_greeting(name: str) -> str: """Get a personalized greeting""" return f"Hello, {name}!" ``` -------------------------------- ### Initialize and Run MCP Server Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Entry point for starting the MCP server using the stdio transport. ```python if __name__ == "__main__": # Initialize and run the server mcp.run(transport='stdio') ``` -------------------------------- ### Initialize TypeScript MCP Project Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Sets up the project directory, initializes npm, and installs necessary dependencies. ```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 ``` ```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 ``` -------------------------------- ### Install uv package manager Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Commands to install the uv package manager on different operating systems. ```bash curl -LsSf https://astral.sh/uv/install.sh | sh ``` ```powershell powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" ``` -------------------------------- ### Verify Java Installation Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Check the installed Java version to ensure compatibility with the project requirements. ```bash java --version ``` -------------------------------- ### Configure Server Path Usage Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Examples of specifying server paths for different operating systems and path types. ```bash # Relative path node build/index.js ./server/build/index.js # Absolute path node build/index.js /Users/username/projects/mcp-server/build/index.js # Windows path (either format works) node build/index.js C:/projects/mcp-server/build/index.js node build/index.js C:\\projects\\mcp-server\\build\\index.js ``` -------------------------------- ### Interact with MCP Server using Python Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/Example - A simple MCP server that exposes a website fetching tool.md Example of initializing an MCP client session over stdio, listing available tools, and executing the 'fetch' tool. ```python import asyncio from mcp.client.session import ClientSession from mcp.client.stdio import StdioServerParameters, stdio_client async def main(): async with stdio_client( StdioServerParameters(command="uv", args=["run", "mcp-simple-tool"]) ) as (read, write): async with ClientSession(read, write) as session: await session.initialize() # List available tools tools = await session.list_tools() print(tools) # Call the fetch tool result = await session.call_tool("fetch", {"url": "https://example.com"}) print(result) asyncio.run(main()) ``` -------------------------------- ### Implement MCP tools in TypeScript and Python Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Examples of setting up a server and handling tool listing and execution requests in TypeScript and Python. ```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"); }); ``` ```python app = Server("example-server") @app.list_tools() async def list_tools() -> list[types.Tool]: return [ types.Tool( name="calculate_sum", description="Add two numbers together", inputSchema={ "type": "object", "properties": { "a": {"type": "number"}, "b": {"type": "number"} }, "required": ["a", "b"] } ) ] @app.call_tool() async def call_tool( name: str, arguments: dict ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: if name == "calculate_sum": a = arguments["a"] b = arguments["b"] result = a + b return [types.TextContent(type="text", text=str(result))] raise ValueError(f"Tool not found: {name}") ``` -------------------------------- ### Clone Repository Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Cloning the Spring AI examples repository and navigating to the Brave chatbot directory. ```bash git clone https://github.com/spring-projects/spring-ai-examples.git cd model-context-protocol/brave-chatbot ``` -------------------------------- ### Verify Node.js Installation Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Checks the installed versions of Node.js and npm to ensure compatibility. ```bash node --version npm --version ``` -------------------------------- ### Install NPM Globally Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Command to ensure NPM is available globally for npx execution. ```bash npm install -g npm ``` -------------------------------- ### Execute MCP Client with Server Paths Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Examples of running a client script with relative, absolute, and Windows-specific server paths. ```bash # Relative path uv run client.py ./server/weather.py # Absolute path uv run client.py /Users/username/projects/mcp-server/weather.py # Windows path (either format works) uv run client.py C:/projects/mcp-server/weather.py uv run client.py C:\\projects\\mcp-server\\weather.py ``` -------------------------------- ### Install and test the MCP server Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Commands to register the server with Claude Desktop or test it using the MCP Inspector. ```bash mcp install server.py ``` ```bash mcp dev server.py ``` -------------------------------- ### Initialize Node.js MCP Client Project Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Commands to create a project directory, initialize npm, and install required dependencies for both Unix-like and Windows systems. ```bash # Create project directory mkdir mcp-client-typescript cd mcp-client-typescript # Initialize npm project npm init -y # Install dependencies npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv # Install dev dependencies npm install -D @types/node typescript # Create source file touch index.ts ``` ```powershell # Create project directory md mcp-client-typescript cd mcp-client-typescript # Initialize npm project npm init -y # Install dependencies npm install @anthropic-ai/sdk @modelcontextprotocol/sdk dotenv # Install dev dependencies npm install -D @types/node typescript # Create source file new-item index.ts ``` -------------------------------- ### Install MCP dependencies Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Commands to add the MCP SDK to a Python project using uv or pip. ```bash uv add "mcp[cli]" ``` ```bash pip install mcp ``` -------------------------------- ### Start MCP Server via CLI Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/Example - A simple MCP server that exposes a website fetching tool.md Commands to launch the server using either the default stdio transport or a custom SSE port. ```bash # Using stdio transport (default) uv run mcp-simple-tool # Using SSE transport on custom port uv run mcp-simple-tool --transport sse --port 8000 ``` -------------------------------- ### Install MCP Server for Claude Desktop Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Configure and register an MCP server for use within the Claude Desktop application. ```bash mcp install server.py # Custom name mcp install server.py --name "My Analytics Server" # Environment variables mcp install server.py -v API_KEY=abc123 -v DB_URL=postgres://... mcp install server.py -f .env ``` -------------------------------- ### Configure Environment Variables for MCP Server Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Example configuration for expanding environment variables like APPDATA within the claude_desktop_config.json file. ```json { "brave-search": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-brave-search"], "env": { "APPDATA": "C:\\Users\\user\\AppData\\Roaming\\", "BRAVE_API_KEY": "..." } } } ``` -------------------------------- ### Manually Run Filesystem MCP Server Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Use these commands to verify the server starts correctly outside of the Claude Desktop environment. ```bash npx -y @modelcontextprotocol/server-filesystem /Users/username/Desktop /Users/username/Downloads ``` ```bash npx -y @modelcontextprotocol/server-filesystem C:\Users\username\Desktop C:\Users\username\Downloads ``` -------------------------------- ### Verify Node.js Installation Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Checks if Node.js is installed and available in the system path. ```bash node --version ``` -------------------------------- ### Initialize Kotlin Project Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Create a new directory and initialize a Gradle project for the MCP client. ```bash # Create a new directory for our project mkdir kotlin-mcp-client cd kotlin-mcp-client # Initialize a new kotlin project gradle init ``` ```powershell # Create a new directory for our project md kotlin-mcp-client cd kotlin-mcp-client # Initialize a new kotlin project gradle init ``` -------------------------------- ### Initialize and Use an MCP Client Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Demonstrates connecting to an MCP server via stdio, initializing the session, and interacting with prompts, resources, and tools. ```python from mcp import ClientSession, StdioServerParameters, types from mcp.client.stdio import stdio_client # Create server parameters for stdio connection server_params = StdioServerParameters( command="python", # Executable args=["example_server.py"], # Optional command line arguments env=None, # Optional environment variables ) # Optional: create a sampling callback async def handle_sampling_message( message: types.CreateMessageRequestParams, ) -> types.CreateMessageResult: return types.CreateMessageResult( role="assistant", content=types.TextContent( type="text", text="Hello, world! from model", ), model="gpt-3.5-turbo", stopReason="endTurn", ) async def run(): async with stdio_client(server_params) as (read, write): async with ClientSession( read, write, sampling_callback=handle_sampling_message ) as session: # Initialize the connection await session.initialize() # List available prompts prompts = await session.list_prompts() # Get a prompt prompt = await session.get_prompt( "example-prompt", arguments={"arg1": "value"} ) # List available resources resources = await session.list_resources() # List available tools tools = await session.list_tools() # Read a resource content, mime_type = await session.read_resource("file://some/path") # Call a tool result = await session.call_tool("tool-name", arguments={"arg1": "value"}) if __name__ == "__main__": import asyncio asyncio.run(run()) ``` -------------------------------- ### Initialize and use the MCP Sync Client Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Demonstrates synchronous interaction with an MCP server, including tool execution, resource management, and prompt retrieval. ```java // Create a sync client with custom configuration McpSyncClient client = McpClient.sync(transport) .requestTimeout(Duration.ofSeconds(10)) .capabilities(ClientCapabilities.builder() .roots(true) // Enable roots capability .sampling() // Enable sampling capability .build()) .sampling(request -> new CreateMessageResult(response)) .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(); ``` -------------------------------- ### Initialize Kotlin Project Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Commands to create a directory and initialize a new Kotlin project via Gradle. ```bash # Initialize a new kotlin project gradle init ``` ```powershell # Create a new directory for our project md weather cd weather # Initialize a new kotlin project gradle init ``` -------------------------------- ### Configure and Manage MCP Servers Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Demonstrates the initialization, capability configuration, and registration of tools, resources, and prompts for both sync and async MCP server implementations. ```java // Create a server with custom configuration McpSyncServer syncServer = McpServer.sync(transportProvider) .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(syncToolSpecification); syncServer.addResource(syncResourceSpecification); syncServer.addPrompt(syncPromptSpecification); // Send logging notifications syncServer.loggingNotification(LoggingMessageNotification.builder() .level(LoggingLevel.INFO) .logger("custom-logger") .data("Server initialized") .build()); // Close the server when done syncServer.close(); ``` ```java // Create an async server with custom configuration McpAsyncServer asyncServer = McpServer.async(transportProvider) .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(asyncToolSpecification) .doOnSuccess(v -> logger.info("Tool registered")) .subscribe(); asyncServer.addResource(asyncResourceSpecification) .doOnSuccess(v -> logger.info("Resource registered")) .subscribe(); asyncServer.addPrompt(asyncPromptSpecification) .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(); ``` -------------------------------- ### Define Main Entry Point Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Initializes the MCP client and manages the connection lifecycle using command-line arguments. ```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()) ``` -------------------------------- ### Request sampling from client Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Example JSON payload for initiating a sampling request via the sampling/createMessage method. ```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 } } ``` -------------------------------- ### Initialize FastMCP Server with Lifespan Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Demonstrates server instantiation, dependency declaration, and asynchronous lifecycle management for database connections. ```python # Add lifespan support for startup/shutdown with strong typing from contextlib import asynccontextmanager from collections.abc import AsyncIterator from dataclasses import dataclass from fake_database import Database # Replace with your actual DB type from mcp.server.fastmcp import Context, FastMCP # Create a named server mcp = FastMCP("My App") # Specify dependencies for deployment and development mcp = FastMCP("My App", dependencies=["pandas", "numpy"]) @dataclass class AppContext: db: Database @asynccontextmanager async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]: """Manage application lifecycle with type-safe context""" # Initialize on startup db = await Database.connect() try: yield AppContext(db=db) finally: # Cleanup on shutdown await db.disconnect() # Pass lifespan to server mcp = FastMCP("My App", lifespan=app_lifespan) # Access type-safe lifespan context in tools @mcp.tool() def query_db(ctx: Context) -> str: """Tool that uses initialized resources""" db = ctx.request_context.lifespan_context["db"] return db.query() ``` -------------------------------- ### Defining Resources Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Resources allow the server to expose data to LLMs, functioning similarly to GET endpoints. ```APIDOC ## @mcp.resource(uri_template) ### Description Registers a function as a resource that provides data to the LLM. ### Parameters - **uri_template** (str) - Required - The URI pattern for the resource (e.g., 'config://app' or 'users://{user_id}/profile'). ``` -------------------------------- ### Initialize and use the MCP Async Client Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Demonstrates asynchronous interaction using Project Reactor, including reactive consumers for tool, resource, and prompt updates. ```java // Create an async client with custom configuration McpAsyncClient client = McpClient.async(transport) .requestTimeout(Duration.ofSeconds(10)) .capabilities(ClientCapabilities.builder() .roots(true) // Enable roots capability .sampling() // Enable sampling capability .build()) .sampling(request -> Mono.just(new CreateMessageResult(response))) .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(); ``` -------------------------------- ### Run the MCP Server Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Main entry point for executing the MCP server. ```kotlin fun main() = `run mcp server`() ``` -------------------------------- ### Create an Echo Server with FastMCP Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Demonstrates basic resource, tool, and prompt registration using the FastMCP high-level API. ```python from mcp.server.fastmcp import FastMCP mcp = FastMCP("Echo") @mcp.resource("echo://{message}") def echo_resource(message: str) -> str: """Echo a message as a resource""" return f"Resource echo: {message}" @mcp.tool() def echo_tool(message: str) -> str: """Echo a message as a tool""" return f"Tool echo: {message}" @mcp.prompt() def echo_prompt(message: str) -> str: """Create an echo prompt""" return f"Please process this message: {message}" ``` -------------------------------- ### Build Application Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Building the project using the Maven wrapper. ```bash ./mvnw clean install ``` -------------------------------- ### Create Project Directory Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Commands to create and enter a new project directory. ```bash # Create a new directory for our project mkdir weather cd weather ``` -------------------------------- ### Build the project Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Command to compile the project using Gradle. ```bash ./gradlew build ``` -------------------------------- ### Create Reusable Prompts Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Define prompt templates to guide LLM interactions, supporting both simple strings and structured message lists. ```python from mcp.server.fastmcp import FastMCP from mcp.server.fastmcp.prompts import base mcp = FastMCP("My App") @mcp.prompt() def review_code(code: str) -> str: return f"Please review this code:\n\n{code}" @mcp.prompt() def debug_error(error: str) -> list[base.Message]: return [ base.UserMessage("I'm seeing this error:"), base.UserMessage(error), base.AssistantMessage("I'll help debug that. What have you tried so far?"), ] ``` -------------------------------- ### Initialize MCP Server Instance Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Main function to configure the MCP server with Stdio transport. ```kotlin // Main function to run the MCP server fun `run mcp server`() { // Create the MCP Server instance with a basic implementation val server = Server( Implementation( name = "weather", // Tool name is "weather" version = "1.0.0" // Version of the implementation ), ServerOptions( capabilities = ServerCapabilities(tools = ServerCapabilities.Tools(listChanged = true)) ) ) // Create a transport using standard IO for server communication val transport = StdioServerTransport( System.`in`.asInput(), System.out.asSink().buffered() ) runBlocking { server.connect(transport) val done = Job() server.onCloseCallback = { done.complete() } done.join() } } ``` -------------------------------- ### Define Root URIs Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Examples of valid URI formats for MCP roots, including local file paths and remote API endpoints. ```text file:///home/user/projects/myapp https://api.example.com/v1 ``` -------------------------------- ### ClientSession.initialize Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Initializes the connection with the MCP server. ```APIDOC ## initialize() ### Description Initializes the connection with the MCP server. ### Method async def initialize() ``` -------------------------------- ### Build and Run via JAR Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Alternative commands to build and execute the application using the generated JAR file. ```bash ./mvnw clean install java -jar ./target/ai-mcp-brave-chatbot-0.0.1-SNAPSHOT.jar ``` -------------------------------- ### Implement SSE Transport Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Use SSE for server-to-client streaming over HTTP. Requires handling both GET requests for the stream and POST requests for messages. ```typescript import express from "express"; const app = express(); const server = new Server({ name: "example-server", version: "1.0.0" }, { capabilities: {} }); let transport: SSEServerTransport | null = null; app.get("/sse", (req, res) => { transport = new SSEServerTransport("/messages", res); server.connect(transport); }); app.post("/messages", (req, res) => { if (transport) { transport.handlePostMessage(req, res); } }); app.listen(3000); ``` ```typescript const client = new Client({ name: "example-client", version: "1.0.0" }, { capabilities: {} }); const transport = new SSEClientTransport( new URL("http://localhost:3000/sse") ); await client.connect(transport); ``` ```python from mcp.server.sse import SseServerTransport from starlette.applications import Starlette from starlette.routing import Route app = Server("example-server") sse = SseServerTransport("/messages") async def handle_sse(scope, receive, send): async with sse.connect_sse(scope, receive, send) as streams: await app.run(streams[0], streams[1], app.create_initialization_options()) async def handle_messages(scope, receive, send): await sse.handle_post_message(scope, receive, send) starlette_app = Starlette( routes=[ Route("/sse", endpoint=handle_sse), Route("/messages", endpoint=handle_messages, methods=["POST"]), ] ) ``` ```python async with sse_client("http://localhost:8000/sse") as streams: async with ClientSession(streams[0], streams[1]) as session: await session.initialize() ``` -------------------------------- ### Configure MCP Client Boot Starter Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Maven dependency and properties configuration for Spring Boot MCP client integration. ```xml org.springframework.ai spring-ai-mcp-client-spring-boot-starter ``` ```properties spring.ai.mcp.client.stdio.servers-configuration=file:PATH/TO/claude_desktop_config.json ``` -------------------------------- ### Implement a basic MCP server Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Basic server implementation demonstrating resource listing and transport connection. ```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 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) ``` -------------------------------- ### client.listPrompts() Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Retrieves a list of available prompt templates from the server. ```APIDOC ## listPrompts() ### Description Returns a list of available prompt templates that can be used for text generation. ### Method SDK Method ``` -------------------------------- ### Implement AI Sampling in MCP Server Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Demonstrates how to define a tool that requests sampling from a client, including checking for capability support and configuring model preferences. ```java // Create a server McpSyncServer server = McpServer.sync(transportProvider) .serverInfo("my-server", "1.0.0") .build(); // Define a tool that uses sampling var calculatorTool = new McpServerFeatures.SyncToolSpecification( new Tool("ai-calculator", "Performs calculations using AI", schema), (exchange, arguments) -> { // Check if client supports sampling if (exchange.getClientCapabilities().sampling() == null) { return new CallToolResult("Client does not support AI capabilities", false); } // Create a sampling request McpSchema.CreateMessageRequest request = McpSchema.CreateMessageRequest.builder() .content(new McpSchema.TextContent("Calculate: " + arguments.get("expression"))) .modelPreferences(McpSchema.ModelPreferences.builder() .hints(List.of( McpSchema.ModelHint.of("claude-3-sonnet"), McpSchema.ModelHint.of("claude") )) .intelligencePriority(0.8) // Prioritize intelligence .speedPriority(0.5) // Moderate speed importance .build()) .systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.") .maxTokens(100) .build(); // Request sampling from the client McpSchema.CreateMessageResult result = exchange.createMessage(request); // Process the result String answer = result.content().text(); return new CallToolResult(answer, false); } ); // Add the tool to the server server.addTool(calculatorTool); ``` ```java // Create a server McpAsyncServer server = McpServer.async(transportProvider) .serverInfo("my-server", "1.0.0") .build(); // Define a tool that uses sampling var calculatorTool = new McpServerFeatures.AsyncToolSpecification( new Tool("ai-calculator", "Performs calculations using AI", schema), (exchange, arguments) -> { // Check if client supports sampling if (exchange.getClientCapabilities().sampling() == null) { return Mono.just(new CallToolResult("Client does not support AI capabilities", false)); } // Create a sampling request McpSchema.CreateMessageRequest request = McpSchema.CreateMessageRequest.builder() .content(new McpSchema.TextContent("Calculate: " + arguments.get("expression"))) .modelPreferences(McpSchema.ModelPreferences.builder() .hints(List.of( McpSchema.ModelHint.of("claude-3-sonnet"), McpSchema.ModelHint.of("claude") )) .intelligencePriority(0.8) // Prioritize intelligence .speedPriority(0.5) // Moderate speed importance .build()) .systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.") .maxTokens(100) .build(); // Request sampling from the client return exchange.createMessage(request) .map(result -> { // Process the result String answer = result.content().text(); return new CallToolResult(answer, false); }); } ); // Add the tool to the server server.addTool(calculatorTool) .subscribe(); ``` -------------------------------- ### Implement Server Connection Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Logic to spawn an MCP server process and establish a transport connection. ```kotlin suspend fun connectToServer(serverScriptPath: String) { try { val command = buildList { when (serverScriptPath.substringAfterLast(".")) { "js" -> add("node") "py" -> add(if (System.getProperty("os.name").lowercase().contains("win")) "python" else "python3") "jar" -> addAll(listOf("java", "-jar")) else -> throw IllegalArgumentException("Server script must be a .js, .py or .jar file") } add(serverScriptPath) } val process = ProcessBuilder(command).start() val transport = StdioClientTransport( input = process.inputStream.asSource().buffered(), output = process.outputStream.asSink().buffered() ) mcp.connect(transport) ``` -------------------------------- ### Configure MCP Server Capabilities Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Initializes server features including resources, tools, prompts, and logging support using the builder pattern. ```java var capabilities = ServerCapabilities.builder() .resources(false, true) // Resource support with list changes notifications .tools(true) // Tool support with list changes notifications .prompts(true) // Prompt support with list changes notifications .logging() // Enable logging support (enabled by default with loging level INFO) .build(); ``` -------------------------------- ### Initialize MCP Server Instance Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Imports required SDK modules and initializes the McpServer instance. ```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", }); ``` -------------------------------- ### Implement MCP Resource Support Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Demonstrates how to register resource listing and reading handlers in an MCP server. ```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() ) ``` -------------------------------- ### Implement Low-Level Server with Stdio Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Provides full control over the server protocol, including manual prompt handling and stdio transport configuration. ```python import mcp.server.stdio import mcp.types as types from mcp.server.lowlevel import NotificationOptions, Server from mcp.server.models import InitializationOptions # Create a server instance server = Server("example-server") @server.list_prompts() async def handle_list_prompts() -> list[types.Prompt]: return [ types.Prompt( name="example-prompt", description="An example prompt template", arguments=[ types.PromptArgument( name="arg1", description="Example argument", required=True ) ], ) ] @server.get_prompt() async def handle_get_prompt( name: str, arguments: dict[str, str] | None ) -> types.GetPromptResult: if name != "example-prompt": raise ValueError(f"Unknown prompt: {name}") return types.GetPromptResult( description="Example prompt", messages=[ types.PromptMessage( role="user", content=types.TextContent(type="text", text="Example prompt text"), ) ], ) async def run(): async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, InitializationOptions( server_name="example", server_version="0.1.0", capabilities=server.get_capabilities( notification_options=NotificationOptions(), experimental_capabilities={}, ), ), ) if __name__ == "__main__": import asyncio asyncio.run(run()) ``` -------------------------------- ### Configure Environment Variables Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Commands to create a .env file and update the .gitignore to secure the Anthropic API key. ```bash # Create .env file touch .env ``` ```bash ANTHROPIC_API_KEY= ``` ```bash echo ".env" >> .gitignore ``` -------------------------------- ### ClientSession.list_tools Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/MCP Python SDK-README.md Lists all tools available on the server. ```APIDOC ## list_tools() ### Description Lists all tools exposed by the MCP server. ``` -------------------------------- ### Implement Tool Execution Handlers Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Configures the HTTP client and registers MCP tools for retrieving weather alerts and forecasts. ```kotlin // Create an HTTP client with a default request configuration and JSON content negotiation val httpClient = HttpClient { defaultRequest { url("https://api.weather.gov") headers { append("Accept", "application/geo+json") append("User-Agent", "WeatherApiClient/1.0") } contentType(ContentType.Application.Json) } // Install content negotiation plugin for JSON serialization/deserialization install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) } } // Register a tool to fetch weather alerts by state server.addTool( name = "get_alerts", description = """ Get weather alerts for a US state. Input is Two-letter US state code (e.g. CA, NY) """.trimIndent(), inputSchema = Tool.Input( properties = JsonObject( mapOf( "state" to JsonObject( mapOf( "type" to JsonPrimitive("string"), "description" to JsonPrimitive("Two-letter US state code (e.g. CA, NY)") ) ), ) ), required = listOf("state") ) ) { request -> val state = request.arguments["state"]?.jsonPrimitive?.content if (state == null) { return@addTool CallToolResult( content = listOf(TextContent("The 'state' parameter is required.")) ) } val alerts = httpClient.getAlerts(state) CallToolResult(content = alerts.map { TextContent(it) }) } // Register a tool to fetch weather forecast by latitude and longitude server.addTool( name = "get_forecast", description = """ Get weather forecast for a specific latitude/longitude """.trimIndent(), inputSchema = Tool.Input( properties = JsonObject( mapOf( "latitude" to JsonObject(mapOf("type" to JsonPrimitive("number"))), "longitude" to JsonObject(mapOf("type" to JsonPrimitive("number"))), ) ), required = listOf("latitude", "longitude") ) ) { request -> val latitude = request.arguments["latitude"]?.jsonPrimitive?.doubleOrNull val longitude = request.arguments["longitude"]?.jsonPrimitive?.doubleOrNull if (latitude == null || longitude == null) { return@addTool CallToolResult( content = listOf(TextContent("The 'latitude' and 'longitude' parameters are required.")) ) } val forecast = httpClient.getForecast(latitude, longitude) CallToolResult(content = forecast.map { TextContent(it) }) } ``` -------------------------------- ### Define Main Execution Entry Point Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Initializes the MCP client and manages the lifecycle of the chat session. ```typescript async function main() { if (process.argv.length < 3) { console.log("Usage: node index.ts "); return; } const mcpClient = new MCPClient(); try { await mcpClient.connectToServer(process.argv[2]); await mcpClient.chatLoop(); } finally { await mcpClient.cleanup(); process.exit(0); } } main(); ``` -------------------------------- ### Configure Claude Desktop Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/README.md Add the server configuration to the Claude Desktop settings file. ```json { "mcpServers": { "zettelkasten": { "command": "/absolute/path/to/zettelkasten-mcp/.venv/bin/python", "args": [ "-m", "zettelkasten_mcp.main" ], "env": { "ZETTELKASTEN_NOTES_DIR": "/absolute/path/to/zettelkasten-mcp/data/notes", "ZETTELKASTEN_DATABASE_PATH": "/absolute/path/to/zettelkasten-mcp/data/db/zettelkasten.db", "ZETTELKASTEN_LOG_LEVEL": "INFO" } } } } ``` -------------------------------- ### Run MCP Client via CLI Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Commands to build and execute the client with different server types. ```bash # Build TypeScript npm run build # Run the client node build/index.js path/to/server.py # python server node build/index.js path/to/build/index.js # node server ``` -------------------------------- ### Initialize MCP Client Structure Source: https://github.com/entanglr/zettelkasten-mcp/blob/main/docs/project-knowledge/dev/llms-full.txt Sets up the necessary imports and the base class for the MCP client in TypeScript. ```typescript import { Anthropic } from "@anthropic-ai/sdk"; import { MessageParam, Tool, } from "@anthropic-ai/sdk/resources/messages/messages.mjs"; import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; import readline from "readline/promises"; import dotenv from "dotenv"; dotenv.config(); const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; if (!ANTHROPIC_API_KEY) { throw new Error("ANTHROPIC_API_KEY is not set"); } class MCPClient { private mcp: Client; private anthropic: Anthropic; private transport: StdioClientTransport | null = null; private tools: Tool[] = []; constructor() { this.anthropic = new Anthropic({ apiKey: ANTHROPIC_API_KEY, }); this.mcp = new Client({ name: "mcp-client-cli", version: "1.0.0" }); } // methods will go here } ```