Coderift MCP Server

Coderift MCP Server

MCP server for managing customer feature requests with role-based approvals, elicitation for high-impact changes, and support for notifications, sampling, and progress tracking. Enables employees to review, prioritize, and approve requests without direct database access.

Category
Visit Server

README

Coderift MCP Project

Overview

Coderift Technologies is a B2B software company. Customers submit feature requests continuously, and internal employees need to review, prioritize, and approve them without touching the production database directly. This project is an MCP server sitting in front of that database, plus a client that talks to it through the protocol instead of raw SQL.

The Problem

Before this system, support agents queried the database directly (or asked an engineer to) whenever a customer asked about a request's status, and a product manager approved requests from a spreadsheet with no audit trail and no check on how many customers a change actually affected. Two things made this risky enough to justify a real protocol-aware server instead of a thin CRUD wrapper:

  1. Approvals are not all equal. Approving a request that affects 800 customers is a different decision than approving one that affects 40. The naive version either lets any agent approve anything, or hard-codes a blanket rule that ignores context. We wanted a manager to have to explicitly sign off on high-impact approvals, live, not just trust a role field the caller sends us.
  2. Roles change mid-session. A support agent gets promoted to product manager during their shift (or a manager is filling in). The tool set available to them should change the moment that happens, not after they reconnect.

Those two facts are what justify elicitation and notifications in this system, not a rule bolted on for the assignment. Report generation over the full pending-request backlog is also genuinely slow-ish and benefits from progress feedback instead of a blocking call.

Database & ERD

Engine: SQLite (db/coderift.db, built from db/schema.sql + db/seed.sql via db/create_db.py).

ERD

Tables: customers, employees, feature_requests (FK to customers), approvals (FK to feature_requests and employees, for a future audit trail). Seed data covers both roles, all three statuses (Pending, Approved, Rejected), and both sides of the 500-customer elicitation threshold (a 40-customer request, a 500-customer boundary case, and an 800-customer request).

Project Structure

coderift-mcp/
├── db/
│   ├── schema.sql
│   ├── seed.sql
│   ├── create_db.py
│   ├── ERD.png
│   └── coderift.db        (generated)
├── mcp_server/
│   ├── server.py
│   └── models.py
├── agent/
│   └── client.py
├── requirements.txt
└── README.md

Installation

python -m venv .venv
source .venv/bin/activate      # .venv\Scripts\activate on Windows
pip install -r requirements.txt
python db/create_db.py

Running

# server, local development
cd mcp_server
python server.py                              # stdio (default)
python server.py --transport streamable-http --port 8000   # remote

# agent, in a second terminal
cd agent
python client.py                # stdio, spawns server.py itself
python client.py --http http://127.0.0.1:8000/mcp   # against a running HTTP server

Set ANTHROPIC_API_KEY before running the agent to have the sampling callback use a real model; otherwise it uses a labeled stub response so the demo still runs end to end.

Where each protocol concern lives

Concern File / function
Capability negotiation server.py: CoderiftMCP._init_options declares tools.listChanged=True. client.py: run_demo reads init.capabilities.tools.listChanged before assuming notifications will arrive.
Notifications server.py: promote_to_manager calls ctx.session.send_tool_list_changed() after verifying the employee against the employees table. client.py: make_notification_handler reacts to ToolListChangedNotification.
Elicitation server.py: approve_feature_request calls ctx.elicit(...) when affected_customers > 500, gated behind has_capability(ctx, elicitation=True). client.py: elicitation_callback prompts a human and returns accept/decline.
Sampling server.py: generate_feature_analysis calls ctx.session.create_message(...) for the written risk recommendation, gated behind has_capability(ctx, sampling=True). client.py: sampling_callback answers using the client's own model.
Resources server.py: policy://feature-prioritization, policy://approval-guidelines, policy://release-guidelines, fetched via resources/read, never wrapped in a tool.
Prompts server.py: draft_feature_summary, draft_rejection_email, customer_feature_update.
Transport server.py __main__ accepts `--transport stdio
Progress tracking server.py: generate_impact_report calls ctx.report_progress(...) at five real milestones while it scans pending requests. client.py passes a progress_callback to call_tool.
Defensive tool design models.py: every write tool takes a single Pydantic model with extra="forbid", Field(gt=0), and Literal enums. server.py: change_priority and approve_feature_request re-validate server-side and check get_role(ctx) — a role read from server-held session state, never a client-supplied parameter.

Comparison note

Tool Read/Write Requires elicitation Notes
get_feature_request Read No
list_customer_requests Read No
search_knowledge_base Read No BM25 over titles/descriptions
approve_feature_request Write Conditional — only when affected_customers > 500 Falls back to an explanatory error if the client lacks elicitation support, instead of silently approving or hanging
change_priority Write No Role-gated only
generate_impact_report Read (long-running) No Progress-tracked
generate_feature_analysis Read No Uses sampling if available; deterministic rule-based fallback otherwise
promote_to_manager Write (session state) No Verified against employees table server-side

If a client connects without elicitation support, approve_feature_request refuses to silently approve a high-impact request — it returns a structured elicitation_unsupported error explaining that a manager needs to approve it out of band. If a client connects without sampling support, generate_feature_analysis still returns a usable (if less nuanced) rule-based risk rating instead of failing.

Transport choice, justified

Development happens over stdio — no server process to manage, easy to run from the agent script directly, matches how one developer iterates locally. server.py also runs over Streamable HTTP (--transport streamable-http), which is the right choice once Coderift's own product managers across multiple offices need to hit the same server concurrently instead of each spawning their own local process — a single deployed HTTP endpoint sits behind normal auth/network controls, which stdio can't do. Both paths share the same tool/resource/prompt code; only the transport layer changes.

Demonstration Workflow

agent/client.py runs, in order: initialize + capability check, list tools as a support_agent, an unauthorized change_priority attempt, promote_to_manager (real employee lookup + real notification), tool list re-fetch showing the unlocked write tools, generate_impact_report with live progress, approve_feature_request on an 800-customer request (elicitation fires) and a 40-customer request (it doesn't), sampling-backed generate_feature_analysis, change_priority, a resource read, and a prompt fetch.

Where it stands now

Session role state lives in a process-local dict keyed by session id, which is fine for the stdio demo and a single-process HTTP deployment but wouldn't survive a restart or a multi-instance deployment — a production version would move that to a signed session token or a real auth layer instead. The approvals table exists in the schema for an audit trail but isn't written to yet; that'd be the next addition, along with a director review tier for requests over 1000 affected customers as described in the approval-guidelines resource.

Technologies Used

Python, MCP Python SDK (mcp), SQLite, Pydantic, rank_bm25.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured