Skip to main content
Glama

MCP Server Blueprint

An end-to-end learning project for building an MCP server, connecting clients, and giving an AI agent access to persistent tools.

Python 3.12+ FastMCP LangChain HTTP SQLite License: MIT

This repository demonstrates a practical MCP pattern: expose ordinary Python functions as tools, connect to them over HTTP, and persist their data in SQLite. The example is a small task manager with tools to create, list, and update tasks. It also includes a Python MCP client and an optional LangChain agent that can use the same server.

Use it to learn how the pieces fit together, then adapt the server and tools to your own project. This is a local learning blueprint, not a production-ready service.

Contents

Related MCP server: TaskMCP

What you will build

  • An HTTP MCP server built with FastMCP.

  • Three discoverable tools for managing tasks.

  • A SQLite database that keeps tasks between server restarts.

  • A Python client that discovers and calls MCP tools.

  • An optional LangChain agent that receives the server's tools and can call them in response to a prompt.

Architecture

flowchart LR
    Host["MCP host or client"] <-->|"HTTP · /mcp"| Server["FastMCP server"]
    Server --> Tools["Task tools"]
    Tools --> DB[("SQLite · data/tasks.db")]
    PyClient["Python FastMCP client"] <-->|"HTTP · /mcp"| Server
    Codex["Codex"] <-->|"HTTP · /mcp"| Server
    Agent["Optional LangChain agent"] <-->|"HTTP · /mcp"| Server
    Agent --> Model["Configured language model"]

The server runs at http://127.0.0.1:8000/mcp. Both the bundled Python client and the optional LangChain agent connect to this endpoint. The server reads and writes tasks in data/tasks.db.

Screenshots

These examples show the same task server being used through different clients and backed by the SQLite database.

Codex using the MCP tools

Codex asks the MCP server to update a task and return the task list

Codex updates a task's status, then calls the server again to display the updated list.

LangChain client output

Task list returned by the LangChain MCP client in a terminal

The LangChain integration reads and updates tasks through the same MCP endpoint.

SQLite persistence

Task records stored in the SQLite database

The task records are persisted in data/tasks.db, so they remain available after the server stops.

Available tools

Tool

Inputs

Behavior

create_task

title (required), priority (defaults to medium), description (defaults to an empty string)

Creates a task with a UUID and the initial status todo, then saves it to SQLite.

list_tasks

None

Returns all tasks currently stored in the database.

update_task_status

task_id, status (todo, in_progress, or done)

Updates the matching task and returns it. If the ID does not exist, returns an error object.

The status is restricted to the three values shown above. Priority is currently an unrestricted string; the server does not validate a priority scale.

Quick start

Requirements

  • Python 3.12 or newer

  • uv for the locked project environment

  • An OpenAI API key only if you plan to run the optional LangChain agent

Clone the repository, open a terminal in its root directory, then install the project dependencies:

uv sync --locked

Initialize the SQLite schema. The helper creates the data directory and table if they are missing, and is safe to run again.

uv run python -c "from mcp_server_blueprint.database import init_db; init_db()"

Start the MCP server:

uv run python -m mcp_server_blueprint.server

Keep this terminal running. The server listens on port 8000 and serves MCP at http://127.0.0.1:8000/mcp.

Connect a client

Configure your MCP-compatible host to connect to http://127.0.0.1:8000/mcp using its HTTP transport option. Client configuration formats vary, so use the format required by your host.

The repository also includes src/mcp_server_blueprint/client.py, which shows how to discover tools and call them with FastMCP's Python client. For a compact example you can run yourself, save this as try_tools.py in the repository root while the server is running:

import asyncio

from fastmcp import Client


async def main() -> None:
    async with Client("http://127.0.0.1:8000/mcp") as client:
        tools = await client.list_tools()
        print("Available tools:", [tool.name for tool in tools])

        created = await client.call_tool(
            "create_task",
            {
                "title": "Explore MCP",
                "priority": "high",
                "description": "Call a task tool through the MCP client.",
            },
        )
        task_id = created.data["task_id"]
        print("Created:", created.data)

        updated = await client.call_tool(
            "update_task_status",
            {"task_id": task_id, "status": "in_progress"},
        )
        print("Updated:", updated.data)

        tasks = await client.call_tool("list_tasks")
        print("Tasks:", tasks.data)


asyncio.run(main())

Run it from the project root:

uv run python try_tools.py

This example writes a task to data/tasks.db; that change remains after the server stops.

Use with Codex

With the MCP server running, register its HTTP endpoint with the Codex CLI:

codex mcp add mcp_server_blueprint --url http://127.0.0.1:8000/mcp

Check that Codex has the server configured:

codex mcp list

Codex CLI and its IDE extension share this MCP configuration. The 127.0.0.1 address works when Codex and the MCP server run on the same machine. If you change the server port or URL, update the address registered with Codex.

Try a read-only request first:

List my tasks using the MCP server. Do not create or update anything.

Then try a task update and ask Codex to verify it:

Set "MCP server testing" to in_progress, then list the tasks to confirm the change.

The server exposes tools that create and update persistent task data. Codex tool calls can therefore change data/tasks.db; review the requested action before approving a write. The Codex screenshot shows an update followed by a fresh task list.

Optional: use the LangChain agent

The LangChain integration connects to the same MCP endpoint, adapts the discovered tools for a LangChain agent, and starts an interactive terminal loop. Model calls may incur API costs, and the agent can change task data by calling the server's tools.

Create a .env file in the repository root with your API key:

OPENAI_API_KEY=your_openai_api_key_here

Start the server in one terminal, then start the agent in another:

uv run python -m mcp_server_blueprint.langchain_client

The model name is configured in src/mcp_server_blueprint/langchain_client.py. Change it to a model available to your account if needed. Enter q in the interactive prompt to exit.

Project structure

Path

Purpose

src/mcp_server_blueprint/server.py

FastMCP server and task tool definitions

src/mcp_server_blueprint/database.py

SQLite initialization and task persistence functions

src/mcp_server_blueprint/client.py

FastMCP client examples for listing and calling tools

src/mcp_server_blueprint/langchain_client.py

Optional LangChain agent connected to the MCP server

data/tasks.db

SQLite database file, created in the project data directory

.env.example

Placeholder for the optional OPENAI_API_KEY setting

pyproject.toml

Project metadata, Python requirement, and dependencies

uv.lock

Resolved dependency versions used by uv sync --locked

Extend the blueprint

Try extending the project in small steps:

  1. Add a function decorated with @mcp.tool in server.py.

  2. Add the corresponding database operation in database.py.

  3. Call the new tool through client.py or the standalone client example above.

  4. Ask the LangChain agent to use it and inspect the tool calls printed by the client.

Keeping tool definitions and persistence logic in separate modules makes it easier to understand and change each part independently.

Practical notes

  • The server exposes task-changing tools and has no authentication or authorization configured. Keep it on a trusted local environment; do not expose it to an untrusted network as-is.

  • The SQLite file is persistent local state. Review its contents before publishing or sharing the repository, and avoid storing private task data in a public copy.

  • The database path is based on the project location, not the terminal's current working directory.

  • create_task accepts any string for priority; add validation if your application needs fixed priority values.

  • The console command declared in pyproject.toml is currently a placeholder. Use uv run python -m mcp_server_blueprint.server to launch the server.

  • The checked-in client scripts include demonstration calls that create or update tasks. Review their inputs before running them against data you want to preserve.

Troubleshooting

Symptom

What to check

no such table: tasks

Run the database initialization command from Quick start, then restart the server.

Connection refused

Confirm the server is running and the client uses http://127.0.0.1:8000/mcp.

The LangChain agent cannot authenticate

Confirm .env is in the repository root and contains a valid OPENAI_API_KEY.

The model name is unavailable

Change the configured model in langchain_client.py to one enabled for your API account.

Further reading

License

This project is licensed under the MIT License. You may use, modify, and redistribute it under the license terms; include the copyright and permission notice with copies or substantial portions. See LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    A local Model Context Protocol server providing backend tools for AI agents to manage projects and tasks with persistent storage in SQLite, enabling structured tracking of project tasks with dependencies, priorities, and statuses.
    12
    6 npm
    25
    GPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    A personal task management MCP server that allows LLM clients to create, read, update, and delete tasks with projects, labels, and comments, using a local SQLite database that can also be accessed via a web UI.
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    A project management MCP server that exposes create_task, list_tasks, and update_task tools backed by SQLite for task tracking.
    -