GitHub announced on July 2, 2026 that Issue fields are generally available, including integration with GitHub's MCP server.
Primary source: GitHub Changelog, July 2, 2026.
That creates a useful beginner project: validate structured issue metadata before an MCP client—or any program—uses it. The schema below is invented for learning. It is not GitHub's API schema.
// schema.mjs
export const schema = {
priority: {
kind: "singleSelect",
required: true,
options: ["P0", "P1", "P2", "P3"]
},
estimate: { kind: "number", required: false, min: 0, max: 100 },
customerImpact: { kind: "text", required: false, maxLength: 120 }
};
A schema describes both type and domain rules. estimate
must be a number, but it also has to fit the range this project accepts.
// validate.mjs
import { schema } from "./schema.mjs";
export function validate(input) {
const errors = [];
if (!input || Array.isArray(input) || typeof input !== "object") {
return ["fields must be an object"];
}
for (const [name, rule] of Object.entries(schema)) {
if (rule.required && !(name in input)) errors.push(`${name}: missing`);
}
for (const [name, value] of Object.entries(input)) {
const rule = schema[name];
if (!rule) { errors.push(`${name}: unknown field`); continue; }
if (rule.kind === "singleSelect" &&
(typeof value !== "string" || !rule.options.includes(value))) {
errors.push(`${name}: expected ${rule.options.join(", ")}`);
}
if (rule.kind === "number" &&
(typeof value !== "number" || !Number.isFinite(value) ||
value < rule.min || value > rule.max)) {
errors.push(`${name}: expected ${rule.min}..${rule.max}`);
}
if (rule.kind === "text" &&
(typeof value !== "string" || value.length > rule.maxLength)) {
errors.push(`${name}: expected at most ${rule.maxLength} characters`);
}
}
return errors;
}
Try these fixtures in a local test harness:
{"priority":"P1","estimate":8,"customerImpact":"Checkout is blocked"}
{"priority":"urgent","estimate":-4,"mysteryField":true}
The second should produce three errors. These are expected outcomes from reading the unexecuted template, not recorded test results.
MCP client
-> tool input validation
-> authorization and repository policy
-> GitHub API call
Validation is not authorization. A perfectly shaped request can still target the wrong repository or issue. A production tool also needs authenticated identity, least privilege, field discovery from official interfaces, write confirmation, rate-limit handling, and audit records.
Common beginner mistakes are checking only JSON syntax, silently converting every value, ignoring unknown fields, and copying a teaching schema into production.
After this project, you should be able to explain parsing versus validation, type versus domain constraints, and why tool schemas do not replace authorization. Issue fields provide the current topic; the durable skill is making structured tools fail clearly at their boundary.