A CLI client and Python library for interacting with dulayni RAG agents via API with support for multiple authentication methods.
-
Clone the repository:
git clone https://github.com/moctarjallo/dulayni-client.git cd dulayni-client -
Ensure Python 3.12 is installed:
python --version # should output 3.12.x -
Create a virtual environment & install dependencies:
python -m venv .venv source .venv/bin/activate pip install -e .
-
Initialize your project:
dulayni init
The dulayni-client supports two authentication methods:
- Request Verification: Client sends phone number to
/authendpoint - Receive Code: Server sends 4-digit verification code via WhatsApp
- Verify Code: Client submits the code to
/verifyendpoint - Get Token: Server returns authentication token for API access
- Make Queries: All subsequent queries include the auth token
- Provide API Key: Set your Dulayni API key (starts with
sk-) - Automatic Authentication: No verification code needed
- Make Queries: All queries include the API key in headers
Initialize a new dulayni project:
dulayni initThis will:
- Set up Git repository (if not already present)
- Create configuration files
- Set up FRPC tunneling for MCP servers
- Guide you through authentication setup
During initialization, you'll choose between:
- WhatsApp authentication (requires phone number)
- Dulayni API key authentication (requires API key)
from dulayni import DulayniClient
# Initialize with WhatsApp authentication
client = DulayniClient(
phone_number="+1234567890",
api_url="http://localhost:8002"
)
# Or initialize with Dulayni API key
client = DulayniClient(
dulayni_api_key="sk-your-api-key-here",
api_url="http://localhost:8002"
)
# Authenticate (WhatsApp only - will prompt for verification code)
def get_verification_code():
return input("Enter 4-digit verification code: ")
client.request_verification_code()
code = get_verification_code()
client.verify_code(code)
# Now you can make queries
response = client.query("What's the weather like?")
print(response)
# Check account balance (WhatsApp authentication only)
balance = client.get_balance()
print(f"Account balance: {balance['balance']:.2f}")
# Stream responses
for message in client.query_stream("Tell me a story"):
print(message["content"])dulayni initStart an interactive REPL:
dulayni runRun a single query non-interactively:
dulayni run -q "What's (3 + 5) x 12?" --print_mode richdulayni balancedulayni statusdulayni logout-m, --model: Model name (default:gpt-5-nano)-p, --phone-number: Your phone number for authentication-k, --dulayni-key: Dulayni API key for authentication-q, --query: Query string for batch mode-md, --markdown: Path to markdown file containing query-a, --agent_type: Agent type (reactordeep_react, default:react)--api_url: Dulayni server URL--thread_id: Thread ID for conversation continuity--print_mode: Output format (jsonorrich)--system_prompt: Custom system prompt--stream: Enable streaming mode--check-balance: Check account balance before query--skip-frpc: Skip FRPC container check
dulayni-client/
├── config/
│ ├── config.json # Main configuration
│ ├── development.json # Development environment config
│ └── production.json # Production environment config
├── src/dulayni/
│ ├── auth/ # Authentication management
│ ├── config/ # Configuration management
│ ├── infrastructure/ # Infrastructure utilities
│ ├── mcp/ # Model Context Protocol integration
│ ├── project/ # Project management
│ ├── client.py # Main client class
│ ├── cli.py # CLI implementation
│ └── exceptions.py # Custom exceptions
└── .dulayni_key # API key storage (if using Dulayni auth)
The dulayni-client includes a built-in MCP (Model Context Protocol) filesystem server that provides:
- File reading and writing operations
- Directory listing and navigation
- Secure command execution
- File search and editing capabilities
The MCP server runs automatically on port 8003 when using the CLI.
For remote MCP server access, the client sets up FRPC (Fast Reverse Proxy Client) tunneling:
- Automatic Docker container setup
- Secure tunneling to relay server
- Domain-based routing (
{identifier}.157.230.76.226.nip.io)
The main client class for interacting with dulayni agents.
api_url (str): URL of the Dulayni API serverphone_number (str): Phone number for WhatsApp authenticationdulayni_api_key (str): API key for Dulayni authenticationmodel (str): Model name to use (default:"gpt-5-nano")agent_type (str): Type of agent ("react"or"deep_react")thread_id (str): Thread ID for conversation continuitysystem_prompt (str): Custom system prompt for the agentmcp_servers (dict): MCP server configurationsmemory_db (str): Path to SQLite database for conversation memorypg_uri (str): PostgreSQL URI for memory storagerequest_timeout (float): Timeout for API requests in seconds
Authentication
request_verification_code(phone_number: str = None) -> dictverify_code(verification_code: str, session_id: str = None) -> dictauthenticate(verification_code_callback = None) -> bool
Query
query(content: str, **kwargs) -> strquery_json(content: str, **kwargs) -> dictquery_stream(content: str, **kwargs) -> Generator[Dict[str, Any], None, None]
Account Management
get_balance() -> Dict[str, Any](WhatsApp authentication only)
Utility
health_check() -> dictis_healthy() -> boolset_thread_id(thread_id: str)set_system_prompt(prompt: str)set_phone_number(phone_number: str)set_dulayni_api_key(dulayni_api_key: str)
DulayniClientError– Base exception for client errorsDulayniConnectionError– Raised when unable to connect to serverDulayniTimeoutError– Raised when requests time outDulayniAuthenticationError– Raised when authentication fails or is requiredDulayniPaymentRequiredError– Raised when payment is required
See the examples/ directory for more detailed usage examples.
- dulayni server running on the specified API URL
- Phone number for WhatsApp authentication OR Dulayni API key
- Python 3.12+
- Docker (for FRPC tunneling)
Install development dependencies:
pip install -e ".[dev]"Run tests:
pytestFormat code:
black src/ tests/
ruff check src/ tests/If you encounter issues with the FRPC container:
- Check if Docker is running:
docker info - Check FRPC container status:
docker ps -a - Restart FRPC container:
docker restart frpc
For WhatsApp authentication issues:
- Ensure your phone number is in international format (+1234567890)
- Check that you can receive WhatsApp messages
For API key authentication issues:
- Ensure your API key starts with
sk- - Check that the API key has not expired
If the MCP server fails to start:
- Check if port 8003 is available:
lsof -i :8003 - Try running with a different port:
dulayni run --mcp-port 8004