Skip to main content
Glama

MCP Server

A Python MCP server built with the official MCP Python SDK / FastMCP 1.x.
The project exposes PostgreSQL, NLP/LLM, registry, and file capabilities as MCP tools.

Technology Stack

  • Python 3.13+

  • UV

  • MCP Python SDK 1.29.1

  • FastMCP

  • FastAPI / Uvicorn (REST API layer)

  • LangChain + OpenAI

  • PostgreSQL / Neon

  • YAML-based tool and prompt configuration

  • ngrok (optional public reverse proxy)


1. Installation

Related MCP server: pgEdge Postgres MCP Server

Prerequisites

Install:

  • Python 3.13+

  • UV

  • An OpenAI API key if using the NLP tools

  • A PostgreSQL/Neon connection string if using PostgreSQL tools

Verify UV:

uv --version

Create / sync the environment

From the project root:

uv sync

Run all Python commands through UV:

uv run python --version

The project is pinned to MCP 1.x because the code uses:

from mcp.server.fastmcp import FastMCP

The current verified MCP version is:

mcp 1.29.1

2. Environment Configuration

Create or update .env in the project root.

Typical variables used by the project include:

OPENAI_API_KEY=your_openai_api_key
NEON_DB_URL=your_postgresql_connection_string
API_KEY=your_rest_api_key
TOOLS_YAML_PATH=C:\Users\<username>\mcp_server\config\tools.yaml

Do not commit real credentials to source control.

env_loader.py loads .env before the server initializes.


3. Project Structure

mcp_server/
│
├── server.py
├── server_stdio.py
│
├── api.py
├── api_router.py
├── auto_router.py
├── auth.py
│
├── env_loader.py
├── logging_config.py
├── start_hidden.ps1
│
├── config/
│   ├── tools.yaml
│   ├── prompt_loader.py
│   └── prompts/
│       ├── agents.yaml
│       ├── core.yaml
│       ├── experiments.yaml
│       ├── nlp.yaml
│       ├── routing.yaml
│       ├── safety.yaml
│       └── tools.yaml
│
├── tools/
│   ├── __init__.py
│   ├── files.py
│   ├── nlp.py
│   ├── postgres.py
│   ├── registry.py
│   └── tool_registry.py
│
└── tests/
    └── test_prompts.py

The ZIP also contains runtime/logging artifacts and legacy Redis-related files. Those are not part of the intended active MCP architecture.


4. Purpose of Each File

MCP Server

server.py

Production MCP HTTP/SSE entry point.

Responsibilities:

  1. Load environment configuration.

  2. Create the FastMCP instance.

  3. Register PostgreSQL, NLP, registry, and file tools.

  4. Start FastMCP using SSE transport.

MCP Client
    ↓
SSE / HTTP
    ↓
server.py
    ↓
FastMCP
    ↓
tools/

Run it with:

uv run python server.py

The development server currently runs on:

http://127.0.0.1:9898

and the SSE endpoint is:

http://127.0.0.1:9898/sse

server_stdio.py

Development/debug MCP server for MCP Inspector.

It registers the same FastMCP tools as server.py, but uses the default stdio transport.

Run:

uv run python server_stdio.py

This is for local development/debugging, not the public HTTP deployment.


5. Tools

The tools/ directory contains the actual capabilities exposed through FastMCP.

tools/postgres.py

PostgreSQL capability.

MCP tools:

execute_sql
get_schema

Responsibilities:

  • Connect to PostgreSQL/Neon.

  • Execute SQL.

  • Retrieve public-schema metadata.

  • Apply the project's SQL validation before execution.

tools/nlp.py

NLP/LLM capability.

MCP tools:

classify_intent
generate_sql

Uses:

  • LangChain

  • OpenAI

  • YAML prompt configuration

The prompt and model policies are loaded through PromptRegistry.

tools/registry.py

Custom tool-intent resolution.

MCP tool:

resolve_tool_by_intent

It reads TOOLS_YAML_PATH and maps an intent/operation to a configured tool name.

This is a custom application registry. It is separate from MCP's native tools/list discovery mechanism.

tools/files.py

File-system capability.

MCP tool:

list_files

Lists files in a specified directory.

tools/tool_registry.py

Alternative/older registry implementation.

It overlaps with tools/registry.py. The active server.py imports registry.py, so this file is not part of the primary MCP registration path.

tools/__init__.py

Marks tools as a Python package and supports imports such as:

from tools import postgres, nlp, registry, files

6. FastAPI REST Layer

FastAPI is a separate HTTP/REST interface around selected Python tool functions.

api.py

Creates the FastAPI application:

api.py
  ↓
FastAPI()
  ↓
auto_router + api_router

Run with:

uv run uvicorn api:app --host 127.0.0.1 --port 5000

auto_router.py

Automatically generates REST endpoints for selected tool functions.

Current mappings include:

POST /postgres/execute
POST /postgres/schema
POST /nlp/classify
POST /nlp/generate_sql
POST /registry/resolve
POST /files/list

It uses Python introspection and Pydantic create_model() to derive request models from function signatures.

All routes in this router use the require_api_key dependency.

api_router.py

Contains additional manually defined FastAPI routes.

It is separate from the dynamically generated routes in auto_router.py.

auth.py

Provides REST API-key authentication through the X-API-Key HTTP header.

logging_config.py

Configures rotating audit logging.

The audit log is written to:

audit.log

7. Configuration

config/tools.yaml

Defines the application's custom operation/tool registry.

Example:

tools:
  postgres_select:
    operation: SELECT

This configuration is consumed by the registry code.

config/prompt_loader.py

Loads prompt definitions from the YAML prompt files.

config/prompts/*.yaml

Stores prompt templates and model/policy configuration for different application areas, including:

  • agents

  • core

  • experiments

  • NLP

  • routing

  • safety

  • tools

Keeping prompts in YAML allows prompt/configuration changes without embedding all prompt text directly in Python code.


8. Running the FastMCP Server

HTTP/SSE server

Start:

uv run python server.py

Expected output:

Uvicorn running on http://127.0.0.1:9898

MCP SSE endpoint:

http://127.0.0.1:9898/sse

This is the server intended for HTTP-based MCP clients and development through a reverse proxy such as ngrok.


9. Verify the MCP Server

First verify the HTTP/SSE endpoint:

uv run python -c "import requests; r=requests.get('http://127.0.0.1:9898/sse', stream=True); print(r.status_code); print(r.headers.get('content-type'))"

Expected:

200
text/event-stream; charset=utf-8

A request to / returning 404 Not Found is not a server failure; / is not the MCP SSE endpoint.


10. Verify MCP Tool Discovery

The server should expose:

execute_sql
get_schema
classify_intent
generate_sql
resolve_tool_by_intent
list_files

A simple MCP client test can connect to:

http://127.0.0.1:9898/sse

and call the MCP tools/list operation.

The important distinction is:

FastMCP
  ↓
MCP protocol
  ↓
tools/list
  ↓
registered MCP tools

No custom discovery mechanism is required for native MCP tool discovery.


11. MCP Inspector Development Server

For local MCP Inspector debugging:

uv run python server_stdio.py

server_stdio.py is intentionally a development/debug entry point.

It uses stdio rather than SSE.


12. ngrok

For exposing the HTTP server through ngrok:

  1. Start the FastMCP SSE server:

uv run python server.py
  1. In another terminal:

ngrok http 9898

Use the resulting public HTTPS URL together with the MCP SSE path:

https://<ngrok-domain>/sse

Do not expose an unauthenticated production MCP server publicly. Review authentication and authorization at the MCP HTTP boundary before public deployment.


13. Tests

Run the test suite with:

uv run pytest

Run the prompt tests specifically:

uv run pytest tests/test_prompts.py

14. Development Workflow

Recommended local workflow:

Terminal 1 --- FastMCP

uv run python server.py

Terminal 2 --- MCP/API testing

Use your MCP client or REST client against:

http://127.0.0.1:9898/sse

For REST testing, run:

uv run uvicorn api:app --host 127.0.0.1 --port 5000

Optional --- public tunnel

ngrok http 9898

15. Architecture Summary

                         MCP Client
                             │
                             │ MCP / SSE
                             ▼
                        server.py
                             │
                         FastMCP
                             │
              ┌──────────────┼──────────────┐
              ▼              ▼              ▼
         postgres.py      nlp.py       registry.py
              │              │              │
              └──────────────┼──────────────┘
                             ▼
                         files.py


                  Separate REST Interface
                             │
                             ▼
                           api.py
                             │
                 ┌───────────┴───────────┐
                 ▼                       ▼
           auto_router.py          api_router.py
                 │
                 ▼
          Python tool functions

Core Principle

server.py is the MCP composition and HTTP/SSE entry point.

server_stdio.py is the development/debug stdio entry point.

tools/ contains the actual capabilities.

api.py, api_router.py, and auto_router.py form a separate REST API layer.

config/ contains tool and prompt configuration.

ngrok is an optional external reverse proxy/tunnel, not part of FastMCP itself.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables querying and modifying PostgreSQL databases through MCP tools with read/write operations, schema inspection, and write-safety constraints that limit modifications to the mcp schema.
    1
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables SQL queries against PostgreSQL databases through MCP-compatible clients and includes a natural language agent for forming SQL queries from natural language.
    230
    PostgreSQL
  • A
    license
    A
    quality
    D
    maintenance
    Exposes PostgreSQL query execution, EXPLAIN, and schema inspection tools to MCP-compatible clients like Claude Desktop.
    3
    1
    MIT