Model Context Protocol (MCP)
debt(d8/e7/b5/t5)
Closest to 'silent in production until users hit it' (d9), scored d8. The detection_hints flag automated:no and note only a code pattern observation: developers writing custom per-provider glue code instead of MCP. There are no static analysis tools, linters, or type checkers that catch this — a team can ship provider-specific integrations indefinitely without any tooling warning them they're duplicating effort. The misuse (missing auth, excessive permissions, unvalidated inputs) surfaces only in runtime behaviour or security incidents, not at build time.
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix says 'implement an MCP server to expose your PHP application's tools' — but doing so after the fact means replacing or wrapping all existing per-provider custom integrations (each provider's function-calling glue, auth, input validation) with a standardised MCP server. This is not a one-line patch; it's a cross-cutting rework touching every AI integration point, every tool handler, and potentially deployment configuration for HTTP-based servers.
Closest to 'persistent productivity tax' (b5). MCP applies to web and CLI contexts and sits at the AI integration layer. Once a team commits to MCP (or fails to), every future AI tool addition is shaped by that choice — either they continue paying the per-provider duplication tax, or they carry the structural weight of maintaining the MCP server. The common_mistakes (stateful servers, missing auth, no input validation) impose ongoing maintenance burden across every tool added to the server.
Closest to 'notable trap — a documented gotcha most devs eventually learn' (t5). The canonical misconception is explicit: 'MCP is only for Claude.' A competent developer encountering MCP through Claude documentation naturally but wrongly concludes it is Claude-proprietary, causing them to skip adopting an open standard that would save cross-provider effort. The common_mistakes (no auth on HTTP servers, treating LLM-generated args as trusted) are additional non-obvious traps that contradict intuition about internal tooling.
Also Known As
TL;DR
Explanation
MCP defines a client-server protocol where: MCP servers expose tools (functions the LLM can call), resources (data the LLM can read), and prompts (reusable prompt templates). MCP clients (Claude, IDE plugins, custom agents) connect to servers and make tools available to the LLM. The protocol uses JSON-RPC over stdio or HTTP/SSE. MCP servers can be written in any language — PHP can both consume MCP servers and act as an MCP server exposing PHP application data to AI agents.
Common Misconception
Why It Matters
Common Mistakes
- MCP servers with excessive permissions — an MCP server that can delete production data should require confirmation, not execute blindly.
- Not validating tool inputs — MCP server tools receive LLM-generated arguments; validate them as strictly as any user input.
- No authentication on HTTP-based MCP servers — anyone who can reach the server can invoke your tools.
- Stateful MCP servers — MCP servers should be stateless; state belongs in the resources they read.
Code Examples
// MCP tool with no input validation:
$tools = [[
'name' => 'run_sql',
'description' => 'Run a SQL query',
'inputSchema' => ['query' => 'string'],
]];
// Handler executes whatever SQL the LLM generates — SQL injection from AI
// MCP tool with restricted, validated operations:
$tools = [[
'name' => 'get_user_orders',
'description' => 'Get orders for a specific user ID',
'inputSchema' => [
'type' => 'object',
'properties' => ['user_id' => ['type' => 'integer', 'minimum' => 1]],
'required' => ['user_id'],
],
]];
// Handler uses parameterised query, read-only DB user:
$orders = $pdo->prepare('SELECT * FROM orders WHERE user_id = ?');
$orders->execute([$input['user_id']]);