# urlDNA MCP Server [Blog](https://urldna.io/blog/introducing-the-urldna-mcp-server-native-threat-intelligence-for-llm-agents) ![Claude Prompt](https://github.com/urldna/mcp/blob/main/claude_prompt.png?raw=true) The `urlDNA MCP Server` enables native tool use for security-focused LLM agents like OpenAI GPT, Google Gemini and Claude Desktop, providing a direct interface to interact with the [urlDNA](https://urldna.io) threat intelligence platform via API. The repository exposes the same toolset over two transports: - `stdio` for local desktop integrations such as Claude Desktop. - `streamable-http` for hosted deployments such as Cloud Run. --- ## Installation & Setup This project uses [uv](https://docs.astral.sh/uv/) for fast Python package management. ### Prerequisites Install uv if you haven't already: ```bash # On macOS and Linux curl -LsSf https://astral.sh/uv/install.sh | sh # On Windows powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Or with pip pip install uv ``` ### Quick Start 1. **Clone and setup the project:** ```bash git clone cd urlDNA-mcp-server uv sync ``` 2. **Run the MCP server locally (stdio mode):** ```bash uv run python urldna_mcp/run.py ``` 3. **Run the MCP server in streamable HTTP mode:** ```bash uv run python urldna_mcp/server.py ``` The hosted server reads these environment variables: - `PORT`: HTTP port to bind to. Defaults to `8080`. - `MCP_PATH`: Public MCP endpoint path. Defaults to `/`. ### Development ```bash # Install development dependencies uv sync --dev # Run tests (when available) uv run pytest # Format code uv run black . # Type checking uv run mypy . # Lint code uv run flake8 . ``` --- ## Hosted MCP Server The `urlDNA MCP` server is already **hosted and available** at: ``` https://mcp.urldna.io/ ``` This server is accessible over **streamable HTTP**, which makes it suitable for Cloud Run and other request-driven platforms. You can use it directly with any platform or LLM that supports the MCP specification (e.g., Claude Desktop, OpenAI GPT, Google Gemini). --- ## Supported Tools ### Scanning | Tool | Description | |--------------|-----------------------------------------------------------------------------| | `fast_check` | Instantly check if a URL has been scanned. Returns SAFE / MALICIOUS / UNRATED. | | `new_scan` | Submit a URL for a full scan and wait for the result (~30–60s). | | `get_scan` | Retrieve a complete scan result by ID. | ### Search | Tool | Description | |----------|---------------------------------------------------------------------------------------------------| | `search` | Search scans using CQL (Custom Query Language) across domain, IP, technology, malicious flag, and more. Supports `AND` and `OR` expressions plus pagination (page 2+ requires PREMIUM). | ### Saved Queries | Tool | Description | |-----------------------|--------------------------------------------------------------------------| | `list_queries` | List all saved queries for the authenticated user. | | `get_query` | Retrieve a specific saved query and its filters by ID. | | `create_query` | Create a new saved query with one or more CQL filter conditions. | | `update_query` | Update an existing query's name and filters (full replacement). | | `delete_query` | Permanently delete a saved query by ID. | | `query_scans` | Retrieve all matching scans for a saved query. | ### Brand Monitoring | Tool | Description | |-------------------|--------------------------------------------------------------------------------------------------| | `list_brands` | List available brands with optional name search and visibility filter (ALL / FREE / PREMIUM / USER_BRANDS). | | `get_brand` | Retrieve full details of a specific brand by ID. | | `brand_scans` | Get all scans associated with a brand. Supports additional CQL filtering. | ### API Reference | Tool | Description | |----------------|--------------------------------------------------------------------------| | `search_docs` | Fetch the full urlDNA OpenAPI and documentations. | --- ## Integration with Claude Desktop To integrate the `urlDNA MCP server` in Claude Desktop, update your `claude_desktop_config.json`: ```json { "mcpServers": { "urlDNA": { "command": "uv", "args": [ "--directory", "\\urldna_mcp", "run", "urldna_mcp\\run.py" ], "env": { "x-api-key": "" } } } } ``` > Replace `` with the parent directory that contains this repository and `` with your API key from [https://urldna.io](https://urldna.io). For hosted MCP clients, point them at `https://mcp.urldna.io/` or your own deployed `MCP_PATH`. Once configured, you can prompt Claude with natural language, for example: > **"Search in urlDNA for malicious scans with title like paypal"** > **"Create a saved query for mobile scans from Italy that are flagged as malicious"** > **"Show me all scans associated with the Google brand"** Claude will automatically call the correct tool and return results from the urlDNA platform. --- ## Using the MCP Server with OpenAI GPT ```python from openai import OpenAI # Initialize OpenAI client (assumes OPENAI_API_KEY is set via environment variable) client = OpenAI() response = client.responses.create( model="gpt-3.5-turbo", # Note: MCP tool use requires a Responses API-compatible model input=[ { "role": "system", "content": [{"type": "input_text", "text": "You are a cybersecurity analyst using urlDNA."}] }, { "role": "user", "content": [{"type": "input_text", "text": "Search in urlDNA for malicious scans with title like paypal or login"}] } ], text={"format": {"type": "text"}}, reasoning={}, tools=[ { "type": "mcp", "server_label": "urlDNA", "server_url": "https://mcp.urldna.io/", "headers": { "x-api-key": "" # Replace with your urlDNA API key }, "allowed_tools": [ # --- Scanning --- "new_scan", # Submit a URL for a full scan and wait for the result "get_scan", # Retrieve a scan result by ID "fast_check", # Lightweight instant safety check (SAFE / MALICIOUS / UNRATED) # --- Search --- "search", # Search scans using CQL (Custom Query Language, AND/OR supported) # --- Saved Queries (PREMIUM) --- "list_queries", "get_query", "create_query", "update_query", "delete_query", "query_scans", # --- Brand Monitoring (PREMIUM) --- "list_brands", "get_brand", "brand_scans", # --- API Reference --- "search_docs", ], "require_approval": "never" } ], temperature=0.7, top_p=1, max_output_tokens=2048, store=True ) print(response.output) ``` --- ## Using the MCP Server with Google Gemini Gemini connects to the `urlDNA MCP` server via `fastmcp`, and tools are auto-discovered rather than passed as an `allowed_tools` list. ```python import os import asyncio from fastmcp import Client from fastmcp.client.transports import StreamableHttpTransport from google import genai async def main(): # 1. Connect FastMCP client directly to streamable-http transport = StreamableHttpTransport( "https://mcp.urldna.io/", headers={"x-api-key": os.getenv("URLDNA_API_KEY", "YOUR_KEY")}, ) client_mcp = Client(transport) async with client_mcp: ai = genai.Client(vertexai=True, project=os.getenv("GOOGLE_CLOUD_PROJECT", "YOUR_PROJECT_ID")) response = await ai.aio.models.generate_content( model="gemini-2.5-flash", contents="Search in urlDNA for malicious scans with title like paypal", # Pass the live MCP session (not just tool declarations) so Gemini # can automatically call tools and receive their results. config=genai.types.GenerateContentConfig(tools=[client_mcp.session]), ) print(response.text) if __name__ == "__main__": asyncio.run(main()) ``` --- ## Container Deployment Build and run with Docker: ```bash # Build the container docker build -t urldna-mcp-server . # Run the server docker run -p 8080:8080 -e x-api-key= urldna-mcp-server # Optional: override the public MCP path if you do not want / docker run -p 8080:8080 -e MCP_PATH=/custom-path -e x-api-key= urldna-mcp-server # Cloud Run example gcloud run deploy urldna-mcp-server \ --source . \ --allow-unauthenticated \ --set-env-vars MCP_PATH=/ ``` ## Search Syntax The `search` and `brand_scans` tools forward the provided CQL directly to the urlDNA API. You can combine conditions with either `AND` or `OR`. Examples: ```text malicious = true AND technology LIKE wordpress domain = google.com OR domain = youtube.com (domain = paypal.com OR title LIKE paypal) AND country_code = IT ``` --- ## Contributing 1. Fork the repository 2. Create a feature branch: `git checkout -b feature-name` 3. Install development dependencies: `uv sync --dev` 4. Make your changes and ensure tests pass 5. Format code: `uv run black .` 6. Submit a pull request --- ## Contact & Support For support or API access, visit [https://urldna.io](https://urldna.io) or email urldna@urldna.io.