Company Data MCP Server
Enables read-only access to company data across PostgreSQL, MongoDB Atlas, and flat files through MCP tools, allowing AI assistants to query and retrieve information via natural language.
README
Company Data MCP Demo
A multi-source Model Context Protocol (MCP) demo that connects a LangChain/OpenAI chatbot to four company data sources through one read-only MCP server:
- PostgreSQL
- MongoDB Atlas
- Local flat files
- A private GitHub repository
The chatbot can investigate business records, application logs, operational guidance, and source-code implementation in one workflow.
Architecture
User
|
v
chatbot.py
LangChain Agent + OpenAI
|
v
MCP Client
|
| Streamable HTTP
v
MCP Server
|
+------------------+------------------+------------------+------------------+
| | | |
v v v v
PostgreSQL MongoDB Atlas Flat Files GitHub
employees application_logs error_codes.csv payment-service-demo
payments
The MCP server is independent of the chatbot. Any compatible MCP client can connect to it.
Current MCP Tools
PostgreSQL
list_sql_tables
describe_sql_table
query_sql_table
MongoDB
list_mongo_collections
find_mongo_documents
Flat files
list_data_files
read_data_file
search_data_files
GitHub
list_github_repository_files
read_github_repository_file
search_github_repository
The tools are generic but constrained. The server does not expose unrestricted SQL, arbitrary MongoDB commands, unrestricted filesystem access, or GitHub write operations.
Project Structure
company-data-mcp-demo/
|
|-- .env
|-- .env.example
|-- .gitignore
|-- requirements.txt
|-- README.md
|-- chatbot.py
|
|-- data/
| |-- error_codes.csv
| |-- notes.txt
| `-- runbook.json
|
`-- mcp_server/
|-- __init__.py
|-- server.py
|
`-- connectors/
|-- __init__.py
|-- sql_connector.py
|-- mongo_connector.py
|-- file_connector.py
`-- github_connector.py
Prerequisites
Install or have access to:
- Python
- PostgreSQL
- Node.js
- MongoDB Atlas account
- OpenAI API key
- GitHub account
- VS Code or another editor
Useful checks:
python --version
node --version
npm --version
psql --version
Python Environment
Create a virtual environment:
python -m venv .venv
Activate on Windows CMD:
.venv\Scripts\activate
Activate on PowerShell:
.venv\Scripts\Activate.ps1
Install dependencies:
python -m pip install -r requirements.txt
Validate:
python -m pip check
Expected:
No broken requirements found.
requirements.txt
Use the pinned environment for the MCP/LangChain stack:
# MCP
mcp==1.29.0
langchain-mcp-adapters==0.3.2
# LLM / Agent
langchain==1.3.14
langchain-openai==1.4.0
openai==2.47.0
# Environment variables
python-dotenv==1.2.1
# PostgreSQL
psycopg[binary]==3.3.4
# MongoDB Atlas
pymongo==3.12.0
dnspython>=1.16.0
# GitHub REST API
httpx
This project intentionally remains on MCP 1.x because langchain-mcp-adapters==0.3.2 requires MCP below 2.
The MCP server uses:
from mcp.server.fastmcp import FastMCP
and starts with Streamable HTTP.
Environment Variables
Create .env in the project root:
OPENAI_API_KEY=your_openai_api_key
# PostgreSQL
DB_HOST=localhost
DB_PORT=5432
DB_NAME=company_demo
DB_USER=mcp_user
DB_PASSWORD=your_postgresql_password
# MongoDB Atlas
MONGODB_USER=mongo_mcp_user
MONGODB_PASSWORD=your_mongodb_password
MONGODB_HOST=your_cluster_host.mongodb.net
MONGODB_DB=company_demo
# GitHub
GITHUB_TOKEN=your_fine_grained_github_token
GITHUB_OWNER=your_github_username
GITHUB_REPO=payment-service-demo
GITHUB_BRANCH=main
Create .env.example with placeholders only:
OPENAI_API_KEY=your_openai_api_key_here
DB_HOST=localhost
DB_PORT=5432
DB_NAME=company_demo
DB_USER=mcp_user
DB_PASSWORD=your_postgres_password_here
MONGODB_USER=mongo_mcp_user
MONGODB_PASSWORD=your_mongodb_password_here
MONGODB_HOST=your_cluster_host.mongodb.net
MONGODB_DB=company_demo
GITHUB_TOKEN=your_github_token_here
GITHUB_OWNER=your_github_username
GITHUB_REPO=payment-service-demo
GITHUB_BRANCH=main
Recommended .gitignore:
.env
.venv/
venv/
__pycache__/
*.pyc
*.pyo
*.pyd
.vscode/
.DS_Store
Thumbs.db
Never commit .env.
PostgreSQL Setup
Create the database
Start PostgreSQL and connect as an administrator:
psql -U postgres
Create:
CREATE DATABASE company_demo;
Connect:
\c company_demo
Create the employees table
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
department VARCHAR(100),
role VARCHAR(100),
email VARCHAR(255)
);
Create the payments table
CREATE TABLE payments (
id SERIAL PRIMARY KEY,
employee_id INTEGER REFERENCES employees(id),
payment_id VARCHAR(100) UNIQUE NOT NULL,
amount NUMERIC(10,2),
status VARCHAR(50),
error_code VARCHAR(50)
);
Insert sample employee data
INSERT INTO employees (
name,
department,
role,
email
)
VALUES
(
'Alice',
'Engineering',
'Developer',
'alice@example.com'
),
(
'Bob',
'Finance',
'Analyst',
'bob@example.com'
),
(
'Charlie',
'Security',
'Security Engineer',
'charlie@example.com'
);
Verify:
SELECT * FROM employees;
Expected records include:
1 | Alice | Engineering | Developer
2 | Bob | Finance | Analyst
3 | Charlie | Security | Security Engineer
Insert sample payment data
INSERT INTO payments (
employee_id,
payment_id,
amount,
status,
error_code
)
VALUES
(
1,
'PAY-001',
5000.00,
'FAILED',
'E109'
),
(
2,
'PAY-002',
2500.00,
'SUCCESS',
NULL
),
(
1,
'PAY-003',
1200.00,
'SUCCESS',
NULL
);
Verify:
SELECT * FROM payments;
Important demo relationship:
Alice -> PAY-001 -> 5000.00 -> FAILED -> E109
Bob -> PAY-002 -> 2500.00 -> SUCCESS
Alice -> PAY-003 -> 1200.00 -> SUCCESS
Create a dedicated read-only PostgreSQL user
Do not use the postgres administrator account from the MCP server.
Create:
CREATE USER mcp_user WITH PASSWORD 'choose_a_strong_password';
Grant database access:
GRANT CONNECT ON DATABASE company_demo TO mcp_user;
Grant schema access:
GRANT USAGE ON SCHEMA public TO mcp_user;
Grant read-only table access:
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_user;
Ensure future tables also receive read access:
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO mcp_user;
Verify read-only behavior
Exit:
\q
Connect as the MCP user:
psql -U mcp_user -d company_demo -h localhost
Reading should work:
SELECT * FROM employees;
A write should fail:
DELETE FROM employees WHERE id = 1;
That failure is expected.
MongoDB Atlas Setup
Create or select a deployment
In MongoDB Atlas:
- Sign in
- Create or select a project
- Create or select a cluster/deployment
- Wait until it is ready
Configure Network Access
Open the Atlas Network Access area.
Add your current public IP address.
For production, avoid unnecessarily broad network rules such as:
0.0.0.0/0
unless that exposure is intentional.
Create the database and collection
In Atlas Data Explorer create:
Database:
company_demo
Collection:
application_logs
Insert sample application logs
PAY-001
{
"payment_id": "PAY-001",
"service": "payment-service",
"error_code": "E109",
"message": "Gateway timeout while contacting payment provider",
"retry_count": 0,
"severity": "ERROR"
}
PAY-002
{
"payment_id": "PAY-002",
"service": "payment-service",
"message": "Payment completed successfully",
"retry_count": 0,
"severity": "INFO"
}
PAY-003
{
"payment_id": "PAY-003",
"service": "payment-service",
"message": "Payment completed successfully",
"retry_count": 0,
"severity": "INFO"
}
The important correlation is:
PostgreSQL:
PAY-001 -> FAILED -> E109
MongoDB:
PAY-001 -> Gateway timeout -> retry_count 0
Create a read-only MongoDB database user
Do not use an Atlas admin/database setup account from the MCP application.
Create a new database user:
Username:
mongo_mcp_user
Use password/SCRAM authentication.
Assign:
Role:
read
Database:
company_demo
Avoid broad permissions such as:
atlasAdmin
readWriteAnyDatabase
Test the MongoDB read-only user
Connect using mongosh:
mongosh "mongodb+srv://YOUR_CLUSTER_HOST/" --username mongo_mcp_user
Select:
use company_demo
Reading should work:
db.application_logs.find()
A write should fail:
db.application_logs.insertOne({
test: "should fail"
})
MongoDB passwords with special characters
If the username or password contains reserved URI characters such as:
@
:
/
?
#
%
&
+
they must be URL encoded.
The connector handles this by encoding credentials before placing them into the MongoDB URI.
Flat-File Setup
Create:
data/
inside the project root.
error_codes.csv
Create:
data/error_codes.csv
Contents:
error_code,meaning,recommended_action
E109,Gateway timeout,Retry up to 3 times with exponential backoff
E201,Invalid account details,Verify account information before retrying
E305,Provider unavailable,Wait and retry later
This provides the documented operational guidance used in the demo.
The key relationship is:
PostgreSQL
PAY-001 -> FAILED -> E109
MongoDB
PAY-001 -> Gateway timeout
Flat file
E109 -> Retry up to 3 times with exponential backoff
notes.txt
Optional:
Payment failures must be investigated using transaction records,
application logs, and documented error handling guidance.
runbook.json
Optional:
{
"payment_service": {
"owner": "Payments Team",
"critical_severity": "ERROR"
}
}
Supported file types
The current connector supports:
.csv
.json
.txt
.log
.md
.yaml
.yml
The connector is sandboxed to the project's data/ directory and should reject attempts to leave that directory.
GitHub Repository Setup
The GitHub connector reads a separate repository representing the application implementation.
Recommended repository:
payment-service-demo
Keep this repository separate from the MCP server repository.
Example structure:
payment-service-demo/
|
|-- README.md
|
|-- app/
| |-- __init__.py
| |-- config.py
| |-- gateway.py
| `-- payment.py
|
`-- tests/
`-- test_payment.py
The demo repository intentionally implements three retry attempts but uses a fixed delay instead of exponential backoff.
That gives the MCP agent a meaningful implementation mismatch to detect.
Repository visibility
For this demo, use:
Private
A private repository proves that the GitHub connector is authenticating successfully rather than simply reading public files.
Create a fine-grained GitHub Personal Access Token
In GitHub:
Settings
-> Developer settings
-> Personal access tokens
-> Fine-grained tokens
-> Generate new token
Configure:
Repository access:
Only select repositories
Select:
payment-service-demo
Grant:
Repository permissions:
Contents -> Read-only
Do not give write permissions.
Copy the generated token and store it only in the MCP project's .env:
GITHUB_TOKEN=your_token_here
Do not place the real token in:
README.md
.env.example
source code
Git commits
chat prompts
GitHub environment configuration
Add:
GITHUB_TOKEN=your_fine_grained_github_token
GITHUB_OWNER=your_github_username
GITHUB_REPO=payment-service-demo
GITHUB_BRANCH=main
to .env.
The GitHub token is used by the MCP server to access the private repository. It is not passed to the LLM.
GitHub connector behavior
The connector:
- lists approved repository files
- reads approved source/text files
- searches approved files for text
- limits file extensions
- limits file sizes
- uses the configured repository and branch
- performs read-only GitHub operations
No GitHub write, commit, pull-request, merge, or delete functionality is exposed.
Test the GitHub connector directly
Run:
python -m mcp_server.connectors.github_connector
Expected output should include files such as:
README.md
app/__init__.py
app/config.py
app/gateway.py
app/payment.py
tests/test_payment.py
If this works, the following are confirmed:
GitHub PAT
->
private repository access
->
GitHub REST API
->
Python connector
Start the MCP Server
Activate the virtual environment:
.venv\Scripts\activate
Start:
python -m mcp_server.server
The endpoint is:
http://localhost:8000/mcp
Keep this terminal open.
MCP Inspector
Start Inspector in another terminal:
npx @modelcontextprotocol/inspector@latest
Choose:
Transport:
Streamable HTTP
Use:
http://localhost:8000/mcp
Expected tools:
list_sql_tables
describe_sql_table
query_sql_table
list_mongo_collections
find_mongo_documents
list_data_files
read_data_file
search_data_files
list_github_repository_files
read_github_repository_file
search_github_repository
Suggested Inspector Tests
PostgreSQL
List tables:
list_sql_tables
Query Alice:
{
"table_name": "employees",
"filter_column": "name",
"filter_value": "Alice",
"limit": 20
}
MongoDB
Find PAY-001:
{
"collection_name": "application_logs",
"field": "payment_id",
"value": "PAY-001",
"limit": 20
}
Flat files
Search:
{
"query": "E109",
"max_results": 50
}
Expected match:
E109,Gateway timeout,Retry up to 3 times with exponential backoff
GitHub
List repository files:
list_github_repository_files
Read:
{
"path": "app/payment.py"
}
Search:
{
"query": "retry",
"max_results": 50
}
Useful searches include:
retry
sleep
backoff
timeout
E109
Start the Chatbot
Keep the MCP server running.
In another terminal:
.venv\Scripts\activate
python chatbot.py
The chatbot should discover all 11 MCP tools.
The terminal trace shows:
[AGENT SELECTED TOOL]
Tool: ...
[TOOL RESULT]
Tool: ...
Result: ...
This provides observable tool-selection and tool-result logging.
Main End-to-End Demo
Ask:
Investigate Alice's failed payment,
explain why it failed,
tell me the documented recommended action,
and check whether our payment-service code implements that recommendation.
Expected investigation:
PostgreSQL
|
| Alice -> employee id 1
| PAY-001 -> FAILED -> E109
v
MongoDB
|
| Gateway timeout while contacting payment provider
| retry_count = 0
v
Flat files
|
| E109
| Retry up to 3 times with exponential backoff
v
GitHub
|
| Inspect payment-service-demo
| Three retry attempts implemented
| Fixed delay implemented
| Exponential backoff missing
v
Final grounded answer
Expected conclusion:
Alice's PAY-001 payment failed with error code E109.
The application log shows that the payment service encountered
a gateway timeout while contacting the payment provider.
The documented recommendation for E109 is to retry up to three
times with exponential backoff.
The payment-service implementation does retry up to three times,
but it uses a fixed retry delay instead of exponential backoff.
Therefore, the code only partially implements the documented
E109 remediation guidance.
Grounding Rules
The chatbot may say:
PAY-001 failed.
because PostgreSQL contains that fact.
It may say:
The application logged a gateway timeout.
because MongoDB contains that fact.
It may say:
The documented recommendation is to retry up to three times
with exponential backoff.
because error_codes.csv contains that guidance.
It may say:
The implementation retries three times using a fixed delay.
only after retrieving the relevant GitHub source.
The chatbot should not claim:
The external provider definitely had an outage.
The available evidence only establishes a gateway timeout.
It should not claim:
I retried the payment.
No write/retry tool exists.
It should not claim:
I changed the repository.
The GitHub connector is read-only.
Security Summary
PostgreSQL
Credential:
mcp_user
Database permissions:
read only
The connector also restricts allowed tables and columns.
MongoDB
Credential:
mongo_mcp_user
Role:
read on company_demo
The connector also restricts collections and fields.
Flat Files
Only the approved:
data/
directory is accessible.
GitHub
Credential:
Fine-grained PAT
Repository:
payment-service-demo
Permission:
Contents -> Read-only
No GitHub write operations are exposed.
Secrets
All real credentials belong only in:
.env
Never commit .env.
Rotate any secret immediately if it is accidentally exposed.
Recommended Testing Order
Direct connector test
|
v
MCP Inspector
|
v
Chatbot
This makes failures easy to isolate:
Connector fails
-> source / credentials / API problem
Connector works but Inspector fails
-> MCP server/tool registration problem
Inspector works but chatbot fails
-> MCP client / agent / prompt problem
Project Status
OpenAI chatbot DONE
LangChain agent DONE
MCP server DONE
MCP Inspector DONE
PostgreSQL connector DONE
MongoDB Atlas connector DONE
Flat-file connector DONE
GitHub repository connector DONE
Agent/tool trace logging DONE
Four-source investigation READY
The current demo supports:
Business records
+
application logs
+
documented remediation
+
source-code verification
through one MCP server.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。