DEV Community

Cover image for Building Your First Model Context Protocol (MCP) Server: A Team Task Tracker with FastMCP and SQLite
ElzaJose
ElzaJose

Posted on

Building Your First Model Context Protocol (MCP) Server: A Team Task Tracker with FastMCP and SQLite

Model Context Protocol (MCP) has completely changed how we think about AI integration. Instead of copying and pasting context back and forth, MCP lets LLMs directly call local tools, interact with file systems, and query databases right from your code editor.

If you are looking to understand how MCP works under the hood by building something practical for your team, building a Team Task Tracker Assistant is one of the best weekend projects.

Here is how we built a lightweight, local-first MCP server using Python, FastMCP, SQLite, and GitHub Copilot in VS Code, complete with multi-user sync via OneDrive.


Why Build an MCP Task Tracker?

Most team task management tools either lock you into heavy SaaS platforms or require complex cloud deployments. But what if your team just wants to:

  1. Paste a raw Minutes of Meeting (MoM) block into chat and have an AI automatically parse, assign, and save action items.
  2. Filter tasks instantly by assignee, status (e.g., Blocked, In Progress), or sprints (Current Sprint, TBD).
  3. Run everything locally without central cloud overhead, keeping data secure and private.

MCP makes this effortless by turning standard Python functions into native LLM tools.


Step 1: The Foundation with FastMCP

Writing raw JSON-RPC servers for MCP can be tedious. Thankfully, FastMCP abstracts away all the transport setup and schema generation.

By defining simple Python functions with type hints and docstrings, FastMCP automatically builds the tool schemas that the LLM reads.

Here is a snippet of how clean tool registration looks using fastmcp:

from fastmcp import FastMCP

mcp = FastMCP("Team Task Tracker")

@mcp.tool()
def add_task(title: str, assignee: str = "Unassigned", due_date: str = "Current Sprint", status: str = "Pending", remarks: str = "") -> str:
    """Add a new task with an assignee, sprint timeline, status, and remarks."""
    # Database insertion logic here...
    return f"Task added successfully and assigned to {assignee}."

Enter fullscreen mode Exit fullscreen mode

Step 2: Scaling from JSON to SQLite for Team Sync

Initially, a local tasks.json file works great for single-user testing. However, if multiple team members need to access and update tasks, flat JSON files lead to race conditions and file overwrites.

Switching the backend to SQLite (team_tasks.db) solves this. SQLite handles concurrent reads and atomic writes efficiently, making it robust enough for small teams.

import sqlite3

DB_FILE = "team_tasks.db"

def get_db_connection():
    conn = sqlite3.connect(DB_FILE)
    conn.row_factory = sqlite3.Row
    return conn

def init_db():
    conn = get_db_connection()
    conn.execute('''
        CREATE TABLE IF NOT EXISTS tasks (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            title TEXT NOT NULL,
            assignee TEXT DEFAULT 'Unassigned',
            due_date TEXT DEFAULT 'Current Sprint',
            status TEXT DEFAULT 'Pending',
            remarks TEXT DEFAULT ''
        )
    ''')
    conn.commit()
    conn.close()

Enter fullscreen mode Exit fullscreen mode

Step 3: Wiring It Up to VS Code & GitHub Copilot

To let GitHub Copilot in VS Code talk to your server, you register it via an mcp.json configuration file. This tells VS Code to spin up your Python script in the background over standard input/output (stdio).

{
  "servers": {
    "team-todo-tracker": {
      "type": "stdio",
      "command": "python",
      "args": ["/path/to/your/team_tracker_server.py"]
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Making it Work Across the Team (OneDrive Sync)

To share this across your team without deploying a cloud server, place team_tracker_server.py and your SQLite database inside a shared OneDrive folder.

When configured on each team member's VS Code instance, everyone shares the exact same task database and interacts with it using natural language through Copilot Agent mode.


Step 4: Putting It into Action

Once configured, your workflow changes completely. You can open Copilot Chat in Agent mode and give commands like:

  • Parsing MoMs: > "Here are the notes from today's sync: Rahul is fixing the login bottleneck for next sprint, and Ananya is blocked on UI styling because we are waiting for brand guidelines. Update the tracker."

Behind the scenes, Copilot breaks this into sequential tool calls (add_task with remarks and statuses) and executes them instantly.

  • Filtering & Tracking: > "Show all tasks assigned to Rahul that are currently blocked."

Copilot calls list_tasks(assignee="Rahul", status="Blocked") and renders a clean summary right in your chat window.


Final Thoughts

Building this project is one of the fastest ways to grasp the core pillars of MCP: tool schemas, persistent state, and multi-step tool execution loops.

Whether you want to build a personal assistant, a DevOps tracker, or a team workflow manager, wrapping standard Python functions with FastMCP opens up endless possibilities for local automation. Give it a try on your next setup!

Get the complete source code and setup guide on GitHub here

Top comments (2)

Collapse
 
steven_mock_afbb801174fc3 profile image
Steven Mock •

Starting with a real task tracker instead of a toy example makes this land a lot better. The meeting-notes use case is the one I recognized right away — pasting in raw notes and getting actual assigned action items back would save a lot of copy-and-paste and follow-up messages.

Keeping it local with SQLite is also a sensible trade-off for a small team. One thing I would watch is the shared OneDrive setup: have you run into any conflicts when two people update the same database at the same time? That is usually where a simple shared-file approach starts to show its limits.

Collapse
 
elzajose profile image
ElzaJose •

Thank you, I appreciate it !

The warning about shared onedrive setup is fair. It works fine for a small team if people aren't hammering updates at the exact same second, but yes, once concurrency ramps up, you definitely start hitting locking issues. If a team scales or gets heavy usage, implementing a proper hosted DB is definitely the right next step.

Really appreciate you reading and calling that out!