Your ColdFusion apps can now talk to AI. And AI can use your CF tools.
MCPCFC connects Adobe ColdFusion to Claude, ChatGPT, Cursor, VS Code, and any other AI assistant that supports the Model Context Protocol. It turns your existing CFML code into AI-callable tools — no rewrite required.
Got a ColdFusion function that generates invoices? That's an MCP tool now. One that queries your proprietary database? Tool. One that kicks off an internal workflow? Tool. If ColdFusion can do it, AI can call it.
┌─────────────┐ ┌──────────────┐ ┌──────────────────┐
│ Claude / │─────▶│ MCPCFC │─────▶│ Your CF App │
│ ChatGPT / │◀─────│ MCP Server │◀─────│ & Business Logic│
│ Cursor │ └──────────────┘ └──────────────────┘
└─────────────┘ JSON-RPC 2.0 PDF, Email, DB,
+ Stdio Bridge Files, HTTP, ...
Millions of lines of ColdFusion are still running in production — at government agencies, financial institutions, healthcare systems, and enterprises worldwide. That code works. But it's increasingly isolated from the AI-powered tools reshaping how people work.
MCPCFC bridges that gap. Instead of rewriting your CF business logic in Python or TypeScript, you wrap it as an MCP tool and let AI assistants call it directly. Your legacy codebase becomes an AI-connected asset overnight.
Who this is for:
MCPCFC ships with six proof-of-concept tools that demonstrate the pattern:
| Tool | What it does |
| --- | --- |
| hello | Simple greeting — useful for verifying connectivity |
| fileOperations | Sandboxed file I/O (read, write, list, delete, exists, info) |
| httpRequest | Outbound HTTP requests (blocks private/internal IPs) |
| pdf | Generate, extract text from, and merge PDFs using ColdFusion's built-in PDF engine |
| queryDatabase | Validated read-only SQL queries (SELECT only) |
| sendEmail | Send email via SendGrid (requires SENDGRID_API_KEY) |
These are intentionally simple. The real power is in adding your own tools — see Adding a custom tool below.
http://localhost:8500/mcpcfc/client-examples/test-client.cfmClaude Desktop talks to local MCP servers via stdio. MCPCFC is HTTP-based, so it ships with a bridge script that translates between the two.
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"coldfusion-mcp": {
"command": "/absolute/path/to/mcpcfc/bridge/cf-mcp-bridge.sh",
"env": {
"MCPCFC_URL": "http://localhost:8500/mcpcfc"
}
}
}
}
Then fully quit and relaunch Claude Desktop.
MCPCFC also supports direct HTTP connections from any MCP client at:
BASE_URL/endpoints/mcp.cfm
For copy-paste configs for Claude Code, ChatGPT, Codex, Cursor, VS Code, Zed, Kimi, and Antigravity, see CLIENTS.md.
This is where MCPCFC becomes yours. Every tool is a ColdFusion Component (.cfc) that extends AbstractTool. The base class gives you input validation, structured result helpers, and automatic registration with the MCP protocol. You write the business logic; MCPCFC handles the plumbing.
Every tool follows three steps:
.cfc file in core/tools/ that extends AbstractToolinit() — name, description, and input schemaMCPServer.cfcThat's it. Let's walk through a complete example.
WeatherToolSay you want to give your AI assistant the ability to check weather via an external API. Here's the complete tool:
Step 1 — Create core/tools/WeatherTool.cfc:
/**
* WeatherTool.cfc
* Returns current weather for a given city
*/
component extends="AbstractTool" output="false" {
public function init() {
// 1. Identity — how the tool appears in MCP
setName("getWeather");
setTitle("Get Weather");
setDescription("Returns current weather conditions for a given city name.");
// 2. Input schema — tells the AI what parameters to send
var inputSchema = structNew("ordered");
inputSchema["type"] = "object";
inputSchema["properties"] = structNew("ordered");
var citySchema = structNew("ordered");
citySchema["type"] = "string";
citySchema["description"] = "City name (e.g., 'Pittsburgh', 'New York')";
inputSchema.properties["city"] = citySchema;
inputSchema["required"] = ["city"];
setInputSchema(inputSchema);
return this;
}
public struct function execute(required struct toolArgs) {
// Validate the required parameter exists
validateRequired(arguments.toolArgs, ["city"]);
var city = trim(arguments.toolArgs.city);
logExecution("Weather requested", { city: city });
try {
// Call an external weather API
var apiUrl = "https://wttr.in/#encodeForURL(city)#?format=j1";
var httpService = new http(method="GET", url=apiUrl, timeout=10);
var response = httpService.send().getPrefix();
if (response.statusCode contains "200") {
var data = deserializeJson(response.fileContent);
var current = data.current_condition[1];
var result = {
"city": city,
"temperature_f": current.temp_F,
"temperature_c": current.temp_C,
"condition": current.weatherDesc[1].value,
"humidity": current.humidity & "%",
"wind_mph": current.windspeedMiles
};
// Return structured JSON — the AI will interpret it
return jsonResult(result);
} else {
return errorResult("Weather API returned status: #response.statusCode#");
}
} catch (any e) {
return errorResult("Failed to fetch weather: #e.message#");
}
}
}
Step 2 — Register it in core/MCPServer.cfc:
Open core/MCPServer.cfc and add your tool class to the toolClasses array in the registerDefaultTools() method:
var toolClasses = [
"core.tools.HelloTool",
"core.tools.PDFTool",
"core.tools.SendGridEmailTool",
"core.tools.DatabaseTool",
"core.tools.FileTool",
"core.tools.HttpClientTool",
"core.tools.WeatherTool" // <-- add your tool here
];
Step 3 — Restart and test:
Restart your ColdFusion application (visit restart-app.cfm or restart the CF service), then relaunch your MCP client. Your new tool will appear in the tool list and the AI can call it immediately.
AbstractTool.cfc provides helper methods so you can focus on business logic:
| Method | Purpose |
| --- | --- |
| textResult(string) | Return a plain text response |
| jsonResult(data) | Return structured JSON data |
| errorResult(message) | Return an error with isError flag |
| imageResult(base64Data, mimeType) | Return a base64-encoded image |
| resourceResult(uri, text, mimeType) | Return an embedded MCP resource |
| validateRequired(args, paramArray) | Throw if required params are missing |
| validateTypes(args, typeMap) | Validate parameter types (string, numeric, boolean, array, struct) |
| getParam(args, name, default) | Get a parameter with a fallback default |
| logExecution(message, data) | Log tool activity (if logger is configured) |
Once you understand the pattern, think about what ColdFusion already does well at your organization:
cfpdf report logicEach of these is a single .cfc file and one line of registration.
MCPCFC_URL="http://localhost:8500/mcpcfc" ./scripts/verify-stdio.sh
MCPCFC_URL="http://localhost:8500/mcpcfc" ./scripts/verify-http.sh
Edit config/settings.cfm to customize:
protocolVersion (default: 2025-06-18)defaultDatasource (default: mcpcfc_ds)The queryDatabase tool expects a ColdFusion datasource named mcpcfc_ds:
database-setup.cfm in your browser, or import mcpcfc_db.sql into MySQL/MariaDB~/Library/Logs/Claude/mcp-server-coldfusion-mcp.logMCPCFC_DEBUG=1 in the env block of your configMCPCFC_INSECURE=1 if using untrusted local certsMCPCFC is a powerful remote-control surface — it can access the filesystem, make HTTP requests, query databases, send email, and generate documents. Do not expose it publicly without:
Application.cfc
bridge/
cf-mcp-bridge.sh # Stdio ⇄ HTTP bridge for Claude Desktop
client-examples/
test-client.cfm # Browser-based test interface
config/
routes.cfm
settings.cfm # Server configuration
core/
CapabilityManager.cfc
JSONRPCHandler.cfc
MCPServer.cfc # Tool registration happens here
TransportManager.cfc
tools/
AbstractTool.cfc # Base class — extend this for custom tools
DatabaseTool.cfc
FileTool.cfc
HelloTool.cfc # Good reference for new tools
HttpClientTool.cfc
PDFTool.cfc
SendGridEmailTool.cfc
endpoints/
mcp.cfm # Unified MCP endpoint (JSON-RPC 2.0)
logging/
registry/
session/
scripts/
verify-stdio.sh
verify-http.sh
See CONTRIBUTING.md for guidelines.
MIT. See LICENSE.
Built with ColdFusion 2025 by @revsmoke. Contributions welcome.