{"id":33926956,"url":"https://github.com/dirmacs/daedra","last_synced_at":"2026-02-01T12:09:02.205Z","repository":{"id":327659569,"uuid":"1110255691","full_name":"dirmacs/daedra","owner":"dirmacs","description":"Daedra is a high-performance DuckDuckGo-powered web search and research Model Context Protocol (MCP) server written in Rust. It provides web search and page fetching capabilities that can be used with AI assistants like Claude.","archived":false,"fork":false,"pushed_at":"2025-12-15T19:10:20.000Z","size":143,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-13T22:58:51.764Z","etag":null,"topics":["ai","ddg","duckduckgo","json-rpc","mcp","mcp-server","model-context-protocol","rust","tool-calling","web-search"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dirmacs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-04T23:43:41.000Z","updated_at":"2025-12-27T21:34:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dirmacs/daedra","commit_stats":null,"previous_names":["dirmacs/daedra"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/dirmacs/daedra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirmacs%2Fdaedra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirmacs%2Fdaedra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirmacs%2Fdaedra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirmacs%2Fdaedra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dirmacs","download_url":"https://codeload.github.com/dirmacs/daedra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dirmacs%2Fdaedra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28632781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","ddg","duckduckgo","json-rpc","mcp","mcp-server","model-context-protocol","rust","tool-calling","web-search"],"created_at":"2025-12-12T10:38:00.592Z","updated_at":"2026-02-01T12:09:02.195Z","avatar_url":"https://github.com/dirmacs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔍 Daedra\n\n[![Crates.io](https://img.shields.io/crates/v/daedra.svg)](https://crates.io/crates/daedra)\n[![Documentation](https://docs.rs/daedra/badge.svg)](https://docs.rs/daedra)\n[![CI](https://github.com/dirmacs/daedra/actions/workflows/ci.yml/badge.svg)](https://github.com/dirmacs/daedra/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n**Daedra** is a high-performance web search and research [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server written in Rust. It provides web search and page fetching capabilities that can be used with AI assistants like Claude.\n\n## Features\n\n- 🔎 **Web Search**: Search the web using DuckDuckGo with customizable options\n- 📄 **Page Fetching**: Extract and convert web page content to Markdown\n- 🚀 **High Performance**: Built in Rust with async I/O and connection pooling\n- 💾 **Caching**: Built-in response caching for improved performance\n- 🔌 **Dual Transport**: Support for both STDIO and HTTP (SSE) transports\n- 📦 **Library \u0026 CLI**: Use as a Rust library or standalone command-line tool\n\n## Installation\n\n### From crates.io\n\n```bash\ncargo install daedra\n```\n\n### From source\n\n```bash\ngit clone https://github.com/dirmacs/daedra.git\ncd daedra\ncargo install --path .\n```\n\n### Using Cargo\n\nAdd to your `Cargo.toml`:\n\n```toml\n[dependencies]\ndaedra = \"0.1\"\n```\n\n## Quick Start\n\n### As an MCP Server\n\n#### STDIO Transport (for Claude Desktop, Cursor, etc.)\n\nAdd to your Claude Desktop configuration (`claude_desktop_config.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"daedra\": {\n      \"command\": \"daedra\",\n      \"args\": [\"serve\", \"--transport\", \"stdio\", \"--quiet\"]\n    }\n  }\n}\n```\n\n\u003e **Note:** The `--quiet` flag is recommended for MCP clients to suppress log output. Without it, logs are written to stderr which some clients may display.\n```\n\n#### SSE Transport (HTTP)\n\n```bash\ndaedra serve --transport sse --port 3000 --host 127.0.0.1\n```\n\n### As a CLI Tool\n\n#### Search the web\n\n```bash\n# Basic search\ndaedra search \"rust programming\"\n\n# With options\ndaedra search \"rust async\" --num-results 20 --region us-en --safe-search moderate\n\n# Output as JSON\ndaedra search \"rust web frameworks\" --format json\n```\n\n#### Fetch a webpage\n\n```bash\n# Fetch and extract content\ndaedra fetch https://rust-lang.org\n\n# Fetch with a specific selector\ndaedra fetch https://example.com --selector \"article.main\"\n\n# Output as JSON\ndaedra fetch https://example.com --format json\n```\n\n#### Server information\n\n```bash\ndaedra info\n```\n\n#### Configuration check\n\n```bash\ndaedra check\n```\n\n### As a Rust Library\n\n```rust\nuse daedra::{DaedraServer, ServerConfig, TransportType};\nuse daedra::tools::{search, fetch};\nuse daedra::types::{SearchArgs, SearchOptions, VisitPageArgs};\n\n// Start an MCP server\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    let config = ServerConfig::default();\n    let server = DaedraServer::new(config)?;\n    server.run(TransportType::Stdio).await?;\n    Ok(())\n}\n\n// Or use tools directly\nasync fn search_example() -\u003e anyhow::Result\u003c()\u003e {\n    let args = SearchArgs {\n        query: \"rust programming\".to_string(),\n        options: Some(SearchOptions {\n            num_results: 10,\n            region: \"wt-wt\".to_string(),\n            ..Default::default()\n        }),\n    };\n\n    let results = search::perform_search(\u0026args).await?;\n    println!(\"Found {} results\", results.data.len());\n\n    for result in results.data {\n        println!(\"- {} ({})\", result.title, result.url);\n    }\n\n    Ok(())\n}\n\nasync fn fetch_example() -\u003e anyhow::Result\u003c()\u003e {\n    let args = VisitPageArgs {\n        url: \"https://rust-lang.org\".to_string(),\n        selector: None,\n        include_images: false,\n    };\n\n    let content = fetch::fetch_page(\u0026args).await?;\n    println!(\"Title: {}\", content.title);\n    println!(\"Word count: {}\", content.word_count);\n\n    Ok(())\n}\n```\n\n## MCP Tools\n\n### `search_duckduckgo`\n\nSearch the web using DuckDuckGo.\n\n**Input Schema:**\n\n```json\n{\n  \"query\": \"search terms\",\n  \"options\": {\n    \"region\": \"wt-wt\",\n    \"safe_search\": \"MODERATE\",\n    \"num_results\": 10,\n    \"time_range\": \"w\"\n  }\n}\n```\n\n**Options:**\n- `region`: Search region (e.g., `us-en`, `wt-wt` for worldwide)\n- `safe_search`: `OFF`, `MODERATE`, or `STRICT`\n- `num_results`: Number of results (1-50)\n- `time_range`: Time filter (`d`=day, `w`=week, `m`=month, `y`=year)\n\n### `visit_page`\n\nFetch and extract content from a web page.\n\n**Input Schema:**\n\n```json\n{\n  \"url\": \"https://example.com\",\n  \"selector\": \"article.main\",\n  \"include_images\": false\n}\n```\n\n**Options:**\n- `url`: URL to fetch (required)\n- `selector`: CSS selector for specific content (optional)\n- `include_images`: Include image references (default: false)\n\n## Configuration\n\n### Environment Variables\n\n- `RUST_LOG`: Set logging level (`debug`, `info`, `warn`, `error`)\n\n### CLI Options\n\n```\ndaedra serve [OPTIONS]\n\nOptions:\n  -t, --transport \u003cTRANSPORT\u003e  Transport type [default: stdio] [possible values: stdio, sse]\n  -p, --port \u003cPORT\u003e            Port for SSE transport [default: 3000]\n      --host \u003cHOST\u003e            Host to bind to [default: 127.0.0.1]\n      --no-cache               Disable result caching\n      --cache-ttl \u003cSECONDS\u003e    Cache TTL in seconds [default: 300]\n  -v, --verbose                Enable verbose output (debug logging)\n  -q, --quiet                  Disable all logging output\n  -f, --format \u003cFORMAT\u003e        Output format [default: pretty] [possible values: pretty, json, json-compact]\n      --no-color               Disable colored output\n```\n\n\u003e **Note:** For stdio transport, logs are automatically routed to stderr to prevent corruption of the JSON-RPC stream. Use `--quiet` to disable logging entirely.\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                        CLI Binary                           │\n│  (clap argument parsing, colored output, TUI)               │\n└─────────────────────────────────────────────────────────────┘\n                              │\n                              ▼\n┌─────────────────────────────────────────────────────────────┐\n│                     Library (daedra)                         │\n├─────────────────────────────────────────────────────────────┤\n│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │\n│  │   Server     │  │    Tools     │  │    Cache     │       │\n│  │  (rmcp MCP)  │  │ (search/     │  │   (moka)     │       │\n│  │              │  │  fetch)      │  │              │       │\n│  └──────────────┘  └──────────────┘  └──────────────┘       │\n├─────────────────────────────────────────────────────────────┤\n│  Transport Layer: STDIO | SSE (HTTP)                         │\n└─────────────────────────────────────────────────────────────┘\n```\n\n## Performance\n\nDaedra is designed for high performance:\n\n- **Async I/O**: Built on Tokio for efficient async operations\n- **Connection Pooling**: HTTP connections are pooled and reused\n- **Caching**: Results are cached to avoid redundant requests\n- **Concurrent Processing**: Parallel search execution support\n- **Efficient Parsing**: Fast HTML parsing with the `scraper` crate\n\n## Development\n\n### Prerequisites\n\n- Rust 1.91 or later\n- Cargo\n\n### Building\n\n```bash\n# Debug build\ncargo build\n\n# Release build\ncargo build --release\n```\n\n### Testing\n\n```bash\n# Run all tests\ncargo test\n\n# Run unit tests only\ncargo test --lib\n\n# Run integration tests (requires network)\ncargo test -- integration\n\n# Run with logging\nRUST_LOG=debug cargo test\n```\n\n### Benchmarks\n\n```bash\ncargo bench\n```\n\n### Documentation\n\n```bash\n# Generate and open documentation\ncargo doc --open\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n### Code Style\n\nThis project uses:\n- `rustfmt` for formatting\n- `clippy` for linting\n\nRun before committing:\n\n```bash\ncargo fmt\ncargo clippy -- -D warnings\n```\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Related Projects\n\n- [rmcp](https://github.com/modelcontextprotocol/rust-sdk) - Rust MCP SDK\n- [mcp-duckduckresearch](https://github.com/bkataru-workshop/mcp-duckduckresearch) - TypeScript inspiration\n- [DIRMACS](https://github.com/dirmacs) - Parent organization\n---\n\nMade with ❤️ by [DIRMACS Global Services](https://dirmacs.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirmacs%2Fdaedra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdirmacs%2Fdaedra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdirmacs%2Fdaedra/lists"}