Building Your First MCP Server for CI/CD
Agents stuck in the chat window are toys. Agents connected to your infrastructure are teammates. The Model Context Protocol (MCP) is the open standard for bridging this gap.
In this tutorial, we will build a simple MCP server that allows an agent (like Claude Desktop or Cursor) to safely check the status of your GitHub Actions pipelines and retry failed jobs.
1. Defining the Tool Interface
First, we define what the tool looks like to the LLM. It needs a clear name, description, and input schema.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer({
name: "ci-manager",
version: "1.0.0"
});
server.tool(
"list_recent_builds",
"Get the status of the last 5 builds for a repo",
{ repo: z.string().describe("The name of the repo, e.g. 'owner/project'") },
async ({ repo }) => {
// Implementation logic...
}
);2. Connecting to the API
Inside the tool handler, we make the actual fetch call to GitHub. Crucially, the Agent never sees the API Key. The key remains secure on the server side.
// ... inside the async handler
const response = await fetch(
`https://api.github.com/repos/${repo}/actions/runs?per_page=5`,
{ headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` } }
);
const data = await response.json();
return {
content: [{
type: "text",
text: JSON.stringify(data.workflow_runs.map(r => ({
id: r.id,
status: r.status,
conclusion: r.conclusion
})), null, 2)
}]
};3. Running the Server
We run this server over stdio, allowing local agents to connect instantly without network overhead.
Once connected, you can simply ask your agent: 'Why did the last build fail?' and it will autonomously query the tool, analyze the logs, and explain the root cause.