MCP won’t let me be…
Continuing our series on MCP, In this video John explains what MCP is and a birds eye view of how to deploy an MCP server with django-mcp-server
MCP Won’t Let Me Be
…or why your LLM needs a wrapper if you want it to ship real code, not just cute prose
Context: The video at the top of this post is John’s lightning-tour of Model-Context Protocol (MCP) and the quickest path to spinning up an MCP-enabled Django project with
django-mcp-server
.
Below is the long-form write-up—perfect for pausing, skimming, and copy-pasting at your own pace.
TL;DR for the terminally busy
- A raw LLM is not an agent; it lacks persistent memory and safe API access.
- MCP adds typed tool manifests, separate auth, and structured logging—turning the LLM into an orchestrator instead of a kamikaze script-kiddie.
- One MCP server → every client that speaks MCP (ChatGPT, Copilot, local LLaMA) can call your stuff.
- Scroll to the bottom for the business payoff and next steps.
1. Raw LLM ≠ Agent
LLMs are brilliant storytellers but amnesiac engineers.
Ask ChatGPT to “create a user” and then immediately “make a DB for that user.” It forgets the ID you just gave it—because every turn starts from zero. Agents need an external memory + tooling system. MCP provides both.
2. Context-Window Reality Check
“128 k tokens” sounds huge—until you remember that’s ~300 KB of text. Your smallest SaaS codebase is 10–100× bigger. The model will never “know” your whole system; it only needs to know how to call it. That’s the job of tool manifests.
3. Tools, Calls & Manifests
Free-hand JSON is the Wild West: fields drift, types change, hallucinations happen. An MCP manifest is a strict contract—names, params, enums, return types. Agents stop guessing and start doing.
4. Security & Compliance Layer
Giving an untrusted LLM direct API keys is like handing the intern root
. MCP splits:
- Auth server – verifies the bearer token / OAuth flow / whatever.
- Tool server(s) – do the work, gated by scopes & rate-limits.
That clean split lets you pass a SOC 2 audit without losing sleep.
5. Connector Explosion → One Bus
Without a standard you get M × N wrappers (every model × every API).
With MCP you write one server; every agent that speaks MCP plugs in. Think HTTP for agents.
6. Observability & Audit Trails
Every tool call is a structured log entry—great for debugging and governance: replay, rollbacks, blame, glory.
7. Live Code Drop: The Forwarding Pattern
Here’s an abridged version of the OSUser tool demoed in the video. Key idea: zero business logic in the tool—just forward to the classic API.
# osuser_example.py
from typing import Literal, Any, Dict
from modules.mcp.utils import MCPTransport
from mcp_server import MCPToolset
class OSUserAPI:
def __init__(self, token: str) -> None:
self.http = MCPTransport(bearer_token=token)
def list(self) -> list[dict]:
# This is where you would place logging for auditing,
# on each CRUD or whatever tooling you decide.
# You would have full context to "self.request" which is the same as django "request"
return self.http.get("/osuser/list/")
def read(self, data: Dict[str, Any]) -> dict:
return self.http.get(f"/osuser/read/{data['id']}")
def create(self, data: Dict[str, Any]) -> dict:
return self.http.post("/osuser/create/", [data])
def update(self, data: Dict[str, Any]) -> dict:
return self.http.post(f"/osuser/update/", [data])
def delete(self, data: Dict[str, Any]) -> str:
return self.http.post(f"/osuser/delete/", [data])
class OSUserTools(MCPToolset):
def osuser(self,
action: Literal["list","read","create","update","delete"],
payload: Any | None = None):
""" in python this would be a docstring and it is where the manifest in django-mcp-server lives. This is where you describe to the LLM how to use your API.
"""
return {
"list": lambda _: self._api().list(),
"read": self._api().read,
"create": self._api().create,
"update": self._api().update,
"delete": self._api().delete,
}[action](payload or {})
def _api(self):
return OSUserAPI(token=self.request.auth)
Flow in one breath: Copilot prompt → OSUserTools.osuser()
→ Django MCP server → classic REST → Celery worker/Ansible/whatever.
8. Real-World Magic: “Vibe Deploy WordPress”
When a user types:
chat: vibe deploy wordpress on opalstack
the agent:
- Creates an OS user & MySQL DB via two MCP tools
- Spins a containerless runtime
- Runs the WordPress installer
- Issues a Let’s Encrypt cert
- Returns a secure preview URL
The model never “learned DevOps.” It just chained typed tools together.
9. Business Payoff
- Speed – one protocol, less glue.
- Reliability – typed manifests curb hallucinations.
- Governance – audit trails make SecOps & Legal smile.
- Ecosystem – every new MCP-speaking service increases the pie.
10. Next Steps
Link | Pip |
---|---|
django-mcp-server on pypi | pip install django-mcp-server |
Questions? send us an email, sales@opalstack.com Ready to ship? Grab a PAT, push to Git, and let MCP handle the midnight shift.