A FastAPI-based MCP (Model Context Protocol) server that provides a sequential thinking tool for dynamic and reflective problem-solving through structured thinking processes, plus powerful browserless Playwright automation tools for web scraping and testing.
- Sequential Thinking Tool: Break down complex problems into manageable steps
- Dynamic Thought Revision: Revise and refine thoughts as understanding deepens
- Branching Reasoning: Branch into alternative paths of reasoning
- Adaptive Planning: Adjust the total number of thoughts dynamically
- Hypothesis Generation & Verification: Generate and verify solution hypotheses
- Playwright Browser Automation: Browserless web scraping, screenshots, form filling, and JavaScript execution
- Echo Tool: Simple echo tool for testing and debugging MCP connections
- HTTP Transport: Accessible over streamable HTTP using FastAPI
- n8n Ready: All Playwright tools are designed for seamless integration with n8n workflows
A simple echo tool that returns the message you send to it. Useful for testing the MCP server connection and basic functionality.
Inputs:
message(string): The message to echo back
Returns:
echo(string): The original messagelength(integer): The length of the messagestatus(string): Status of the operation (always "success")
Example:
{
"message": "Hello, World!"
}Response:
{
"echo": "Hello, World!",
"length": 13,
"status": "success"
}All Playwright tools run in browserless headless mode, making them perfect for server environments and n8n workflows. Screenshots are returned as base64-encoded strings for easy integration.
Navigate to a URL and capture a screenshot.
Inputs:
url(string, required): The URL to navigate to (must include http:// or https://)wait_for_selector(string, optional): CSS selector to wait for before screenshotwait_time(integer, optional): Time to wait in milliseconds after page load (default: 1000)full_page(boolean, optional): Whether to capture the full scrollable page (default: false)
Returns:
status(string): "success" or "error"url(string): The URL that was navigated totitle(string): Page titlescreenshot(string): Base64-encoded screenshot imagescreenshot_size(integer): Size of screenshot in bytesfull_page(boolean): Whether full page was captured
Example:
{
"url": "https://example.com",
"full_page": true
}Extract text content from a webpage.
Inputs:
url(string, required): The URL to navigate toselector(string, optional): CSS selector to extract specific content (if None, gets all body text)wait_time(integer, optional): Time to wait in milliseconds after page load (default: 1000)
Returns:
status(string): "success", "warning", or "error"url(string): The URL that was navigated totitle(string): Page titleselector(string): The selector usedtext(string): Extracted text contenttext_length(integer): Length of extracted text
Extract HTML content from a webpage.
Inputs:
url(string, required): The URL to navigate toselector(string, optional): CSS selector to extract specific HTML (if None, gets all page HTML)wait_time(integer, optional): Time to wait in milliseconds after page load (default: 1000)
Returns:
status(string): "success", "warning", or "error"url(string): The URL that was navigated totitle(string): Page titleselector(string): The selector usedhtml(string): Extracted HTML contenthtml_length(integer): Length of extracted HTML
Navigate to a URL and click an element.
Inputs:
url(string, required): The URL to navigate toselector(string, required): CSS selector for the element to clickwait_after_click(integer, optional): Time to wait in milliseconds after clicking (default: 1000)screenshot(boolean, optional): Whether to take a screenshot after clicking (default: true)wait_for_navigation(boolean, optional): Whether to wait for navigation after click (default: false)
Returns:
status(string): "success" or "error"original_url(string): The original URL navigated tocurrent_url(string): The current URL after clickingtitle(string): Page title after clickingselector(string): The selector that was clickedclicked(boolean): Whether the click was successfulscreenshot(string, optional): Base64-encoded screenshot if requestedscreenshot_size(integer, optional): Size of screenshot in bytes
Fill form fields on a webpage.
Inputs:
url(string, required): The URL to navigate tofields(array, required): List of objects with 'selector' and 'value' keys- Example:
[{"selector": "#email", "value": "test@example.com"}, {"selector": "#password", "value": "secret"}]
- Example:
submit_selector(string, optional): CSS selector for submit button (if None, no submit)wait_after_submit(integer, optional): Time to wait in milliseconds after submit (default: 2000)screenshot(boolean, optional): Whether to take a screenshot after filling (default: true)
Returns:
status(string): "success" or "error"original_url(string): The original URL navigated tocurrent_url(string): The current URL after form submissiontitle(string): Page titlefilled_fields(array): List of objects showing which fields were filled successfullysubmitted(boolean): Whether form was submittedscreenshot(string, optional): Base64-encoded screenshot if requestedscreenshot_size(integer, optional): Size of screenshot in bytes
Execute JavaScript on a webpage and get the result.
Inputs:
url(string, required): The URL to navigate toscript(string, required): JavaScript code to execute (should return a JSON-serializable value)wait_time(integer, optional): Time to wait in milliseconds after page load (default: 1000)
Returns:
status(string): "success" or "error"url(string): The URL that was navigated totitle(string): Page titleresult(any): The result returned by the JavaScript code
Example:
{
"url": "https://example.com",
"script": "document.querySelectorAll('a').length"
}Facilitates a detailed, step-by-step thinking process for problem-solving and analysis.
Inputs:
thought(string): The current thinking stepnextThoughtNeeded(boolean): Whether another thought step is neededthoughtNumber(integer): Current thought numbertotalThoughts(integer): Estimated total thoughts neededisRevision(boolean, optional): Whether this revises previous thinkingrevisesThought(integer, optional): Which thought is being reconsideredbranchFromThought(integer, optional): Branching point thought numberbranchId(string, optional): Branch identifierneedsMoreThoughts(boolean, optional): If more thoughts are needed
- Python 3.11 or higher
# Clone the repository
git clone https://github.com/mersdev/fast-api-mcp.git
cd fast-api-mcp
# Run the setup script (creates venv and installs dependencies)
setup.bat# Clone the repository
git clone https://github.com/mersdev/fast-api-mcp.git
cd fast-api-mcp
# Make scripts executable
chmod +x setup.sh run.sh
# Run the setup script (creates venv and installs dependencies)
./setup.shIf you prefer to set up manually:
# Clone the repository
git clone https://github.com/mersdev/fast-api-mcp.git
cd fast-api-mcp
# Create virtual environment
python -m venv .venv
# Activate virtual environment
# On Windows:
.venv\Scripts\activate
# On Linux/Mac:
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Install Playwright browsers (required for Playwright tools)
playwright install chromiumNote: The Playwright tools require Chromium to be installed. The setup scripts will prompt you to install it, or you can run playwright install chromium manually after installing the Python dependencies.
Windows:
run.batLinux/Mac:
./run.shActivate the virtual environment and run the server:
Windows:
.venv\Scripts\activate
python server.pyLinux/Mac:
source .venv/bin/activate
python server.pyThe server will start on http://0.0.0.0:10000 by default.
You can customize the port using the PORT environment variable:
PORT=8000 python server.py-
Make sure your virtual environment is activated and dependencies are installed
-
Launch the inspector:
# Windows
.venv\Scripts\activate
mcp dev server.py
# Linux/Mac
source .venv/bin/activate
mcp dev server.pyThen go to: http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=...
In Cursor, add your MCP server under Chat Settings > MCP Servers:
{
"mcpServers": {
"sequential-thinking": {
"url": "http://localhost:10000/mcp/"
}
}
}✅ Note: You must include the trailing / in the URL.
Add this to your claude_desktop_config.json:
{
"mcpServers": {
"sequential-thinking": {
"url": "http://localhost:10000/mcp/"
}
}
}The Playwright tools are designed to work seamlessly with n8n. To use them:
-
Start the MCP server (make sure it's running on the configured port)
-
In n8n, use the HTTP Request node to call the MCP tools:
- Method: POST
- URL:
http://localhost:10000/mcp/(or your server URL) - Body: JSON with the tool name and parameters
-
Example n8n HTTP Request for screenshot:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "playwright_screenshot", "arguments": { "url": "https://example.com", "full_page": true } } } -
Example n8n HTTP Request for web scraping:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "playwright_scrape_text", "arguments": { "url": "https://example.com", "selector": ".content" } } } -
Process the response in subsequent n8n nodes - screenshots are base64-encoded and can be saved or processed directly.
Common n8n Use Cases:
- Automated website monitoring and screenshots
- Web scraping for data collection
- Form automation for testing
- Content extraction from dynamic websites
- JavaScript execution for advanced data extraction
- Breaking down complex problems into steps
- Planning and design with room for revision
- Analysis that might need course correction
- Problems where the full scope might not be clear initially
- Tasks that need to maintain context over multiple steps
- Situations where irrelevant information needs to be filtered out
- Web Scraping: Extract text or HTML content from dynamic websites
- Visual Monitoring: Capture screenshots of websites for change detection
- Testing: Automate UI testing and verification
- Form Automation: Fill and submit forms programmatically
- Data Extraction: Execute custom JavaScript for advanced data gathering
- n8n Workflows: Integrate browser automation into workflow automation
- API Alternative: Access web content that doesn't have an API
PORT: Server port (default: 10000)DISABLE_THOUGHT_LOGGING: Set totrueto disable thought logging to console (default: false)
To verify the echo tool works correctly:
# Windows
.venv\Scripts\activate
python test_echo.py
# Linux/Mac
source .venv/bin/activate
python test_echo.pyThe echo test verifies:
- ✅ Simple message echo
- ✅ Empty message handling
- ✅ Long message support
- ✅ Special characters support
- ✅ Correct length calculation
To verify the sequential thinking tool works correctly:
# Windows
.venv\Scripts\activate
python test_tool.py
# Linux/Mac
source .venv/bin/activate
python test_tool.pyThe test script verifies:
- ✅ Tool returns proper dictionary output (not JSON strings)
- ✅ Thought sequencing works correctly
- ✅ Revisions are handled properly
- ✅ Thought history is maintained
- ✅ No Pydantic validation errors
.
├── server.py # Main FastAPI MCP server (with echo & sequential_thinking tools)
├── sequential_thinking/ # Sequential thinking library
│ ├── __init__.py
│ └── lib.py # Core logic for thought processing
├── test_echo.py # Test script for the echo tool
├── test_tool.py # Test script for the sequential thinking tool
├── setup.bat # Windows setup script
├── setup.sh # Linux/Mac setup script
├── run.bat # Windows run script
├── run.sh # Linux/Mac run script
├── requirements.txt # Python dependencies
├── pyproject.toml # Project metadata
├── runtime.txt # Python runtime version
├── .python-version # Python version for pyenv/uv
├── .gitignore # Git ignore rules
├── FIX_SUMMARY.md # Documentation of the validation error fix
└── README.md # This file
The server uses the FastMCP library to expose multiple MCP tools over HTTP:
A simple tool that:
- Accepts a message string
- Returns the message along with its length
- Useful for testing MCP connections
Browserless automation tools that:
- Use a singleton Playwright browser instance for efficiency
- Run in headless mode (no GUI required)
- Support screenshots (base64-encoded), text/HTML extraction, clicking, form filling, and JavaScript execution
- Return structured JSON responses perfect for n8n workflows
- Handle errors gracefully with detailed error messages
- Use async operations for better performance
A complex tool that:
- Accepts thought inputs with metadata (thought number, total thoughts, etc.)
- Validates the input data
- Maintains a history of thoughts
- Supports branching and revision of previous thoughts
- Returns structured responses with thought status
# Install dev dependencies
uv pip install pytest
# Run tests (if available)
pytest- server.py: FastAPI server setup and tool definition
- sequential_thinking/lib.py: Core sequential thinking logic
ThoughtData: Data class for thought representationSequentialThinkingServer: Main server class for processing thoughts
MIT License
Based on:
- Sequential Thinking MCP Server by Anthropic
- MCP Servers over Streamable HTTP by Alejandro AO
Contributions are welcome! Please feel free to submit a Pull Request.
- Make sure Python 3.11+ is installed
- Check if port 10000 is available
- Verify all dependencies are installed:
pip list - Make sure virtual environment is activated
- Restart the AI assistant after adding the configuration
- Check that the server is running
- Verify the URL is correct in the configuration
- Check server logs for any errors
This error has been fixed in the latest version. The tool now properly returns dictionary objects instead of JSON strings.
To verify the fix:
python test_tool.pyIf you still see this error:
- Make sure you have the latest version:
git pull - Restart the server
- Clear any cached connections in your AI assistant
- Check that
server.pyimportsjsonand parses the result
# Change the port
PORT=8000 python server.pyFor issues and questions, please open an issue on the GitHub repository.