Creating an MCP Server

This guide explains how to create and run a Model Context Protocol (MCP) server using the Agentstr SDK. MCP servers provide tools that agents can call.

Step 1: Initialize Your Project

If you haven’t already, initialize a new project:

agentstr init mcp_server

This creates a mcp_server directory with the basic structure for your MCP server.

Step 2: Update .env File

Update the mcp_server/.env file with your NWC connection string.

NWC_CONN_STR=nostr+walletconnect://<your-nwc-connection-string>

Note

  • NWC_CONN_STR is the default environment variable for NWCRelay to enable Nostr Wallet Connect. You can override this by passing a connection string directly to the NostrMCPServer constructor.

Step 3: Define Your Tools

Modify mcp_server/main.py to define the tools you want to expose and initialize the MCP Server.

 1"""Simple MCP Server"""
 2
 3from dotenv import load_dotenv
 4load_dotenv()
 5
 6import os
 7from agentstr import NostrMCPServer, tool
 8
 9# Addition tool
10async def add(a: int, b: int) -> int:
11    """Add two numbers."""
12    return a + b
13
14# Multiplication tool
15@tool(satoshis=0)
16async def multiply(a: int, b: int) -> int:
17    """Multiply two numbers."""
18    return a * b
19
20# Weather tool (premium tool)
21@tool(satoshis=5)
22async def get_weather(city: str) -> str:
23    """Get weather for a given city."""
24    return f"It's always sunny in {city}!"
25
26
27async def run():
28    # Define the server
29    server = NostrMCPServer(
30        "SimpleMCPServer",
31        nwc_str=os.getenv("NWC_CONN_STR"),
32        tools=[add, multiply, get_weather],
33    )
34
35    # Start the server
36    await server.start()
37
38
39if __name__ == "__main__":
40    import asyncio
41    asyncio.run(run())
42
43

Step 4: Modify the Test Client

Modify mcp_server/test_client.py to list the tools available and call one of them.

 1
 2from dotenv import load_dotenv
 3load_dotenv()
 4
 5import os
 6import json
 7from agentstr import NostrMCPClient, PrivateKey
 8
 9server_public_key = os.getenv("NOSTR_PUBKEY")
10
11async def chat():
12    # Initialize the client
13    mcp_client = NostrMCPClient(mcp_pubkey=server_public_key,
14                                private_key=PrivateKey().bech32())
15
16    # List available tools
17    tools = await mcp_client.list_tools()
18    print(f"Found tools: {json.dumps(tools, indent=4)}")
19
20    # Call a tool
21    result = await mcp_client.call_tool("add", {"a": 69, "b": 420})
22    print(result)
23
24
25if __name__ == "__main__":
26    import asyncio
27    asyncio.run(chat())

Step 5: Start a Local Relay

Start a local Nostr relay for testing:

agentstr relay start

Keep this running in a separate terminal.

Step 6: Run the MCP Server

Execute the script from your terminal:

python mcp_server/main.py

Your MCP server is now running and ready to provide tools to your agents.

Step 7: Test Your MCP Server

Use the test client to interact with your MCP server and check your balance:

python mcp_server/test_client.py

You should see a JSON structure defining the available tools, followed by a tool call response.

Step 8 (Optional): Deploy to the Cloud

Deploy your MCP Server to the cloud for continuous operation and public accessibility. Assuming you are already logged into the Agentstr CLI, follow these steps:

  1. Set your cloud provider:

    export AGENTSTR_PROVIDER=aws  # or gcp, azure
    
  2. Deploy the agent:

    agentstr deploy -f mcp_server/deploy.yml
    

    This command packages your MCP server and deploys it to the specified cloud provider. Ensure your project directory structure is compatible with the deployment requirements.

For more information on cloud deployment and CI/CD, see the Cloud & CI/CD guide.

Next Steps

  • Create an Agent that Uses Tools: See the Tool Calling Agent guide to learn how to create an agent that can connect to this MCP server and use its tools.

  • Explore More MCP Features: Dive into the Model Context Protocol (MCP) documentation for advanced MCP server configurations and tool creation.