MCP Server
An MCP server implements the Model Context Protocol and exposes a typed set of tools and data sources that an AI assistant can call over JSON-RPC 2.0.
An MCP server is a program that implements the Model Context Protocol and exposes a typed set of tools and data sources that an AI application can call over JSON-RPC 2.0 messages. The protocol is what makes the connection portable: any host that speaks MCP can attach to any server that speaks MCP, so the integration between an assistant and a system is written once on the server side instead of once per assistant.
The practical consequence is a change in who does the work. Instead of a person opening a dashboard, reading numbers off it, and pasting them into a chat window, the assistant asks the server for the same numbers in a structured form and reasons over the result.
Definition
The specification names three roles (Model Context Protocol specification, checked on 2026-08-13).
- Host. The application a person is actually using: an editor, a chat client, or an agent runtime. It owns the conversation and decides which servers are attached.
- Client. The connector inside the host. The host runs one client per server, and that client owns the connection and the message exchange.
- Server. The program that wraps a system and describes what it offers. A server is a local process the host launches, or a remote service addressed by URL.
A server offers any combination of three features. The names are fixed by the protocol, and each one has a different controller.
| Server feature | Who decides it is used | Example content for a GitHub Actions server |
|---|---|---|
| Tools | The model, during a turn | list_workflow_runs, get_job_logs, rerun_failed_jobs |
| Resources | The host application, by URI | A workflow file, a job log, a runner inventory |
| Prompts | The user, by picking one | A saved "triage the last failed run" template |
Tools are the feature most people mean when they say MCP server, because tools are the ones a model invokes on its own. Resources and prompts are pulled in by the application or the person.
What makes the surface typed
Discovery is a single request. The client sends tools/list and the server answers with every tool it currently offers. Each tool definition carries a name, an optional human readable title, a description, an inputSchema, and an optional outputSchema. Both schemas are JSON Schema, defaulting to draft 2020-12 when no $schema field is present (Tools, MCP specification, checked on 2026-08-13).
That schema is the contract. The model fills in arguments to match it, the server validates what arrives, and the response comes back as a content array with an isError flag rather than as a page of HTML. A tool list is also stable by design: the specification says the set must not vary per connection, though it may narrow according to the authorization presented on the request.
How a host reaches a server
Two transports are defined. A stdio server is launched by the host as a subprocess and exchanges messages over stdin and stdout, which suits anything reading local files or local tooling. A Streamable HTTP server lives at a URL, serves many users from one deployment, and is the usual shape for a server that fronts a hosted API.
A remote server needs its own answer to authentication, because the connection now crosses a network boundary. The specification builds authorization on OAuth 2.1 with server discovery and client registration, and many deployments accept a bearer token in an Authorization header as the simpler path. Either way the credential belongs to the host and the server. The model sees tool names, schemas, and results.
The specification also asks implementations to keep a person in the loop, showing which tools are exposed and offering a confirmation before a tool runs. A server that can restart infrastructure deserves that prompt.
Example
Take a question that comes up on any repository with a slow test suite: which runs of the integration workflow on main failed in the last day, and how long did each one take. The workflow itself is ordinary.
name: integration
on:
push:
branches: [main]
jobs:
api-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./scripts/integration-test.shAnswering that by hand means opening the Actions tab, filtering by branch and status, opening each failed run, and reading the timing off the job view. Answering it by scraping means writing code against page markup that changes without warning.
With an MCP server attached, the host holds a connection to a server that fronts the workflow run data. Configuration in the host is a URL plus a header.
{
"mcpServers": {
"actions": {
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer <api key>"
}
}
}
}On connect, the client asks what the server offers, and the reply describes the tool and its arguments.
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"tools": [
{
"name": "list_workflow_runs",
"title": "List workflow runs",
"description": "List recent runs of one workflow in a repository, newest first.",
"inputSchema": {
"type": "object",
"properties": {
"repository": { "type": "string", "description": "owner/repo" },
"workflow": { "type": "string", "description": "Workflow file name, such as integration.yml" },
"branch": { "type": "string" },
"status": { "type": "string", "enum": ["success", "failure", "cancelled"] },
"limit": { "type": "integer", "maximum": 100 }
},
"required": ["repository"]
}
}
]
}
}The model now has enough to answer the question without being told the argument names in advance. It emits one call, and the client sends it.
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "list_workflow_runs",
"arguments": {
"repository": "example-org/example-repo",
"workflow": "integration.yml",
"branch": "main",
"status": "failure",
"limit": 5
}
}
}The server authenticates to the upstream system with the credential it was configured with, queries it, and returns text the model can read.
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"resultType": "complete",
"content": [
{
"type": "text",
"text": "3 failed runs of integration.yml on main in the last 24 hours:\nrun 8421 started 03:11Z, api-tests failed after 12m41s\nrun 8419 started 01:52Z, api-tests failed after 12m08s\nrun 8412 started 22:40Z, api-tests failed after 11m55s"
}
],
"isError": false
}
}Underneath, a server like this one is calling a documented endpoint, usually list workflow runs for a repository in the GitHub REST API, checked on 2026-08-13. The protocol adds the discovery step and the argument schema on top of that endpoint, which is the part that lets a model use it correctly on the first try.
Two properties fall out of the exchange above. Results carry identifiers, so run 8421 is a link a person can open and verify, and a wrong answer is caught rather than believed. And several servers can be attached at once, so an assistant that holds one server for workflow runs and another for the runner fleet can join their results in a single turn without either server knowing the other exists.
Related Terms
- Querying GitHub Actions data through an MCP server: connecting a host to a runner fleet, the configuration block, and worked prompts.
- Can an AI agent query my GitHub Actions metrics: what an agent can read, what it can change, and the scopes involved.
- Running AI agents against GitHub Actions: the workload shape of agent driven jobs and how they are sized.
- WarpBuild MCP server documentation: the server URL and the host configuration steps.
- API key automation documentation: the API endpoints and scopes an MCP connected key reaches.
- WarpBuild pricing: per minute rates by runner type.
FAQ
What is an MCP server?
An MCP server is a program that implements the Model Context Protocol and offers three kinds of capability to an AI application: tools the model can call, resources the application can read, and prompt templates a user can pick. The application discovers what a server offers by asking it, so no integration code is written for that one pairing.
How is an MCP server different from a REST API?
An MCP server usually sits in front of an API rather than replacing it. The difference is discovery and shape. A client sends one tools/list request and gets back every operation with a JSON Schema for its arguments, in a format every MCP host already parses, so the same server works in any host that speaks the protocol.
Does the language model connect to the server itself?
No. The host application holds the connection through a client, sends the tools/call request, and returns the result to the model. Credentials stay with the host and the server, and the specification says implementations should keep a human able to deny a tool invocation.
Start with $10 in free credits
Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.