Duck MCP Server
by theddnc
README.md
# Duck MCP Server š¦
A simple MCP (Model Context Protocol) server built with [FastMCP](https://gofastmcp.com/).
## Features
This server provides the following tools:
- **select_option**: Ask user to select one option from provided choices (uses elicitation)
- **provide_information**: Request additional information from user in natural language (uses elicitation)
- **request_manual_test**: Request the user to perform manual testing and report results (uses elicitation)
## Installation
### Prerequisites
- Python 3.10 or higher
- [uv](https://docs.astral.sh/uv/getting-started/installation/) (recommended) or pip
### Install Dependencies
Using uv (recommended):
```bash
uv sync
```
Using pip:
```bash
pip install -e .
```
## Usage
### Running the Server
#### Using the FastMCP CLI (recommended):
```bash
# Run with default configuration from fastmcp.json
fastmcp run
# Or specify the config file explicitly
fastmcp run fastmcp.json
# Run with HTTP transport for testing
fastmcp run --transport http --port 8000
```
#### Using Python directly:
```bash
python server.py
```
### Running with uv:
```bash
uv run fastmcp run server.py
```
### Development Mode
Run with the FastMCP Inspector UI:
```bash
fastmcp dev
```
### Inspect Server Capabilities
View all available tools, resources, and prompts:
```bash
fastmcp inspect
```
## Installing to MCP Clients
### Claude Desktop
```bash
fastmcp install claude-desktop
```
### Cursor
```bash
fastmcp install cursor
```
### Claude Code (VS Code Extension)
```bash
fastmcp install claude-code
```
## Testing
You can test the server using a FastMCP client:
```python
import asyncio
from fastmcp import Client
async def test_server():
async with Client("http://localhost:8000/mcp") as client:
# Ping the server to check connectivity
await client.ping()
print("Server is running!")
if __name__ == "__main__":
asyncio.run(test_server())
```
### Testing Elicitation Tools
The `select_option`, `provide_information`, and `request_manual_test` tools use FastMCP's elicitation feature to interactively request information from users:
```python
import asyncio
from fastmcp import Client
async def elicitation_handler(message: str, response_type: type, params, context):
"""Handler that responds to server's elicitation requests"""
print(f"Server asks: {message}")
user_input = input("Your response: ")
return response_type(selected_option=user_input) if hasattr(response_type, '__annotations__') and 'selected_option' in response_type.__annotations__ else response_type(information=user_input)
async def test_elicitation():
async with Client("http://localhost:8000/mcp", elicitation_handler=elicitation_handler) as client:
# Test select_option tool
result = await client.call_tool("select_option", {
"question": "What's your favorite programming language?",
"options": ["Python", "JavaScript", "Rust", "Go"]
})
print(result.data)
# Test provide_information tool
result = await client.call_tool("provide_information", {
"question": "What would you like to build today?"
})
print(result.data)
# Test request_manual_test tool
result = await client.call_tool("request_manual_test", {
"test_description": "Navigate to the login page and verify the form renders correctly",
"expected_outcome": "Login form should display username/password fields and submit button"
})
print(result.data)
if __name__ == "__main__":
asyncio.run(test_elicitation())
```
## Project Structure
```
duck-mcp/
āāā server.py # Main server implementation
āāā fastmcp.json # FastMCP configuration
āāā pyproject.toml # Project metadata and dependencies
āāā README.md # This file
āāā tests/ # Test files (optional)
```
## Development
### Adding New Tools
To add a new tool to the server, simply decorate a function with `@mcp.tool`:
```python
@mcp.tool
def my_new_tool(arg1: str, arg2: int) -> str:
"""Description of what this tool does"""
# Your implementation here
return "result"
```
### Running Tests
```bash
pytest
```
## Deployment
### Local Deployment
The server runs with stdio transport by default, making it compatible with local MCP clients like Claude Desktop.
### HTTP Deployment
For remote access, run with HTTP transport:
```bash
fastmcp run --transport http --host 0.0.0.0 --port 8000
```
### FastMCP Cloud
Deploy to FastMCP Cloud for managed hosting (requires account):
```bash
fastmcp cloud deploy
```
## Configuration
The `fastmcp.json` file contains the server configuration:
- **source**: Location and entrypoint of the server code
- **environment**: Python version and dependencies
- **deployment**: Runtime configuration (transport, logging, etc.)
You can override any configuration via CLI arguments:
```bash
fastmcp run --port 8080 --log-level DEBUG
```
### MCP Client Configuration
To use this MCP server with MCP-compatible clients (like Claude Desktop), add the following configuration to your client's `mcp.json` file:
#### Using uv (recommended):
```json
{
"mcpServers": {
"duck-mcp": {
"command": "uv",
"args": ["run", "fastmcp", "run", "server.py"],
"cwd": "/path/to/duck-mcp"
}
}
}
```
#### Using Python directly:
```json
{
"mcpServers": {
"duck-mcp": {
"command": "python",
"args": ["server.py"],
"cwd": "/path/to/duck-mcp"
}
}
}
```
Replace `/path/to/duck-mcp` with the actual path to your duck-mcp directory. The `cwd` (current working directory) ensures the server runs from the correct location.
## Learn More
- [FastMCP Documentation](https://gofastmcp.com/)
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [FastMCP GitHub](https://github.com/jlowin/fastmcp)
## License
MIT
TDQS
B3.4/5.0
Scored across 3 tools
Disambiguation5/5
Each tool has a distinct purpose: providing information, requesting manual tests, and selecting options. There is no overlap or ambiguity between them.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern (provide_information, request_manual_test, select_option), with clear and descriptive naming.
Tool Count4/5
With 3 tools, the set is minimal but well-scoped for a server focused on user interaction requests. It is slightly thin but appropriate for its apparent purpose.
Completeness3/5
The tools cover key user elicitation tasks (info, manual test, option selection), but lack general action requests or confirmations, leaving some gaps in the interaction surface.
Maintenance
ActivityInactive
ResponsivenessNo issues