SurveyMCP
Allows fetching unread messages, downloading PDF attachments, parsing sender email addresses, and sending HTML-rich emails via the Gmail API.
Generates structured survey summaries from PDF text using Google Gemini's natural language processing capabilities.
Provides monitoring dashboards and provisioning for tracking survey processing metrics and document status.
Stores and updates task status documents for tracking processing state of survey generation.
Stores document metadata including sender, file name, and processing status for each survey.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@SurveyMCPprocess my inbox for new survey PDFs"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Survey Generation & Email Workflow
Project Scope
This repository implements a queued survey generation workflow for PDF documents received by Gmail. It uses ActiveMQ as the message broker, PostgreSQL and MongoDB for persistence, and Google Gemini for natural language processing. The workflow extracts text from incoming PDFs, generates a structured survey summary, produces HTML or PDF output, and sends the result back to the original sender.
Related MCP server: Gmail MCP Server
What this project does
Reads unread Gmail messages and downloads attached PDF files
Extracts text from PDFs using PyMuPDF
Queues document processing tasks with ActiveMQ / STOMP
Consumes tasks in a worker process
Generates report summaries using Google Gemini (
google.genaipreferred)Converts generated summaries into HTML email content
Sends HTML email replies via Gmail API
Tracks metadata in PostgreSQL and task status in MongoDB
Uses environment-based configuration via
.env
Libraries and Technologies Used
python-dotenv- load environment variables from.envstomp.py- STOMP client for ActiveMQpsycopg2-binary- PostgreSQL database adapterpymongo- MongoDB clientgoogle-genai/google-generativeai- Gemini text generationgoogle-api-python-client/google-auth-oauthlib/google-auth-httplib2- Gmail API integrationPyMuPDF- PDF text extractionreportlab- PDF generation from survey textmarkdown- Markdown-to-HTML conversionopentelemetry-api/opentelemetry-sdk/opentelemetry-exporter-otlp- telemetry and tracingdocker- project includes Docker Compose support for service orchestrationGrafana- dashboards and provisioning for monitoring and visualization
High-level Flow
Email ingestion
app/server.pypolls Gmail for unread messages and downloads PDF attachments viaapp/gmail_utils.pyEach valid PDF becomes a task message published to ActiveMQ
Metadata is stored in PostgreSQL and MongoDB as
pending
Task queueing
app/queue_manager.pypublishes the task to the configured ActiveMQ queueEach task includes
email_id,sender,pdf_path,document_uuid, anddocument_name
Worker consumption
app/worker.pysubscribes to the queue and receives tasksWhen a task arrives, the worker:
marks the task
in_progressin MongoDBextracts PDF text via
app/pdf_utils.pygenerates survey content with
app/gemini_utils.pyconverts the survey into HTML via
app/survey_utils.pysends the HTML email using
app/gmail_utils.pyupdates document status in PostgreSQL and MongoDB
Output and persistence
PDF text extraction, survey generation, emailing, and state updates are logged
uploads/stores downloaded email attachmentsoutputs/stores generated survey PDFs
Directory Structure
MCP/
├── .env # Local configuration values (private)
├── .env.example # Example environment variables
├── docker-compose.yml # Service orchestration template
├── otel-collector-config.yaml
├── requirements.txt # Python dependencies
├── app/
│ ├── config.py # dotenv loader
│ ├── gemini_utils.py # Gemini model invocation and text extraction
│ ├── gmail_utils.py # Gmail API helpers for download/send
│ ├── mongodb_db.py # MongoDB task status store
│ ├── pdf_utils.py # PDF text extraction via PyMuPDF
│ ├── postgres_db.py # PostgreSQL metadata store
│ ├── queue_manager.py# ActiveMQ STOMP connection, publish, subscribe
│ ├── server.py # Queue producer / FastMCP tool wrapper
│ ├── survey_utils.py # HTML/PDF generation from survey text
│ ├── telemetry.py # Logging and tracing helpers
│ ├── test_gmail.py # Gmail-related tests/examples
│ └── worker.py # Queue consumer and task processor
├── credentials/ # Gmail OAuth credentials
├── outputs/ # Generated survey output files
├── grafana/
│ ├── dashboards/
│ │ └── survey_dashboard.json
│ └── provisioning/
│ ├── dashboards/
│ │ └── dashboard.yml
│ └── datasources/
│ └── postgres.yml
└── uploads/ # Downloaded PDF attachmentsCore Components
app/server.py
Exposes FastMCP tools for document processing and inbox workflow
Primary workflow is
process_inbox()Reads unread Gmail messages
Downloads PDF attachments and stores them locally
Writes metadata to PostgreSQL
Writes pending task status to MongoDB
Publishes processing tasks to ActiveMQ
app/worker.py
Runs the background consumer
Connects to ActiveMQ, PostgreSQL, and MongoDB
Subscribes to the configured queue
Processes each message by:
extracting PDF text
generating survey text
producing HTML content
emailing the result
updating both databases with final status
app/queue_manager.py
Handles ActiveMQ connectivity via STOMP
Validates broker protocol on startup
Supports infinite connection timeout with
ACTIVEMQ_CONNECT_TIMEOUT=0Allows publish and subscribe operations
Disabled STOMP heartbeats for long-running worker tasks
app/gemini_utils.py
Uses
google.genaiwhen availableFalls back to
google.generativeaifor compatibilitySends a structured prompt to Gemini
Extracts text safely from the response
app/gmail_utils.py
Uses the Gmail API for:
fetching unread messages
downloading attachment payloads
parsing sender email addresses
sending HTML-rich emails
Stores attachments under
uploads/Builds clean email content with fallback text formatting
app/pdf_utils.py
Extracts text from PDF documents using PyMuPDF
Used as the first processing step in the worker
app/survey_utils.py
Generates PDF output from survey text via ReportLab
Converts survey text to styled HTML for email delivery
Includes a fallback HTML generator for plain text
app/postgres_db.py
Connects to PostgreSQL
Creates a
documentstable if missingStores sender, document UUID, file name, and final status
Tracks result status for each processed document
app/mongodb_db.py
Connects to MongoDB
Stores and updates task status documents
Supports index creation for
document_uuid,sender, and timestamps
app/config.py
Loads
.envvalues withpython-dotenvCentralizes environment configuration for the whole app
app/telemetry.py
Simple console logging helper
Provides OpenTelemetry span support for tracing operations
Grafana provisioning & dashboards
Dashboard JSON: grafana/dashboards/survey_dashboard.json contains pre-built panels for survey processing metrics and document status.
Provisioning files: grafana/provisioning/dashboards/dashboard.yml and grafana/provisioning/datasources/postgres.yml allow Grafana to auto-provision the dashboard and a PostgreSQL datasource on startup.
Ensure the datasource configuration matches your
POSTGRES_*settings so dashboard panels can query persisted metadata.
Setup
Create and activate your Python virtual environment
python -m venv venv
source venv/bin/activate
pip install -r requirements.txtCopy environment example
cp .env.example .envPopulate
.env
GEMINI_API_KEYorGOOGLE_API_KEYACTIVEMQ_HOST,ACTIVEMQ_PORT,ACTIVEMQ_USER,ACTIVEMQ_PASSWORDPOSTGRES_HOST,POSTGRES_PORT,POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DBMONGODB_URI,MONGODB_DB,MONGODB_COLLECTION
Provide Gmail OAuth credentials in
credentials/credentials.jsonStart ActiveMQ, PostgreSQL, and MongoDB services
Running the project
Start the worker
python app/worker.pyTrigger inbox processing
The inbox workflow is exposed via
app/server.pyas a FastMCP toolIn practice, run the tool path or call
process_inbox()from your FastMCP interfaceAlternatively, you can add a small script to invoke
process_inbox()directly
Start Grafana (optional)
To preview processing metrics and the included dashboard locally you can run Grafana and mount the provisioning files. Example using docker run:
docker run -d -p 3000:3000 \
-v "$(pwd)/grafana/provisioning:/etc/grafana/provisioning" \
-v "$(pwd)/grafana/dashboards:/var/lib/grafana/dashboards" \
--name grafana grafana/grafana:latestIf you use docker-compose, mount the grafana/ directory into your Grafana service under /etc/grafana/provisioning so Grafana will auto-provision the dashboard on startup.
Important Notes
uploads/stores downloaded PDF attachments from Gmailoutputs/stores generated survey PDF filesACTIVEMQ_CONNECT_TIMEOUT=0disables the STOMP connection timeout for long-running workersGmail credentials and API tokens must remain private and should not be committed
Extended Notes
The worker is designed to stay alive while processing long Gemini requests
The queue consumer logs disconnects and reconnects if the broker drops connection
PostgreSQL stores stable document metadata, while MongoDB stores live task status changes
The project is structured to separate email ingestion, queue orchestration, NLP generation, and output delivery cleanly
Future Improvements
Add a scheduler or webhook trigger for
process_inbox()Add retry logic for failed tasks and emails
Add unit tests around queue, DB, and Gemini flows
Add a health-check endpoint or monitoring integration
Grafana dashboard
A pre-built Grafana dashboard is included at grafana/dashboards/survey_dashboard.json.
Grafana provisioning files are available in grafana/provisioning/dashboards/dashboard.yml and grafana/provisioning/datasources/postgres.yml.
To enable the dashboard, mount the
grafana/directory into your Grafana container's provisioning path or copy the provisioning files into your Grafana server; Grafana will auto-provision the dashboard on startup when provisioning is enabled.Ensure the datasource configuration points to your PostgreSQL instance used by this project so panels can query the stored metadata and metrics.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/murali-ftw/SurveyMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server