Server definition
- Hash
- sha256:67c26e9f2473361bdcc72ba5e5c2c2d615951e1c5d2a40ccfdfbebea8ea39aab
- What it is
- What a remote MCP server returned when asked what it offers: 11 tools
The blob, as servednamed by its sha256
{
"instructions": "Routing, packing, cutting and rostering over MCP (OR-Tools). Free: validate_problem, route_plan, distance_matrix_haversine, pack_bins, cutting_stock_1d, knapsack_select, explain_solution. Premium (license): route_plan_fleet, pack_bins_large, cutting_stock_2d, roster_shifts.",
"tools": [
{
"description": "Least-waste cut plan for bars, pipes or boards from stock lengths, with saw kerf. FREE.\n\nTypical input {\"stock\": [{\"length\": 6000, \"cost\": 30}], \"parts\":\n[{\"length\": 2200, \"qty\": 3}, {\"length\": 1500, \"qty\": 4}], \"kerf\": 3}\nreturns {\"bars\": [{\"stock_length\": 6000, \"cuts\": [2200, 2200, 1500],\n\"waste\": 94}], \"bars_used\": 3, \"waste_pct\": 4.2, \"solver_status\":\n\"OPTIMAL\"}. Minimises total stock cost (or count when no cost); CP-SAT\nproves optimality when it finishes inside the time limit and otherwise\nreturns the best plan found as FEASIBLE. Use for a cut list of up to 200\npieces. Not for sheets: use cutting_stock_2d. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"stock and parts must be non-empty lists (<value> and <value>)\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"kerf": {
"default": 0,
"description": "material lost per cut (same unit as lengths).",
"type": "number"
},
"parts": {
"description": "required pieces: {length, qty}.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"stock": {
"description": "stock lengths available: {length, cost, qty} (qty = how many of that length may be used; default unlimited).",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"time_limit_s": {
"default": 3,
"description": "solver time budget in seconds (default 3, max 15).",
"maximum": 15,
"minimum": 0,
"type": "number"
}
},
"required": [
"stock",
"parts"
],
"type": "object"
},
"name": "cutting_stock_1d",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Guillotine cut layouts for rectangular parts from sheets, with kerf and grain. PREMIUM (license).\n\nTypical input {\"sheets\": [{\"id\": \"ply\", \"l\": 2440, \"w\": 1220, \"qty\":\n5}], \"parts\": [{\"id\": \"side\", \"l\": 800, \"w\": 400, \"qty\": 6}], \"kerf\":\n3} returns {\"sheets_used\": 1, \"layouts\": [{\"sheet\": \"ply\", \"placements\":\n[{\"id\": \"side\", \"x\": 0, \"y\": 0, \"l\": 800, \"w\": 400, \"rotated\": false}],\n\"fill_pct\": 64.5, \"offcuts\": [...]}], \"unplaced\": []}. Every cut is a\nguillotine cut (edge to edge): the sheet is ripped into strips and each\nstrip cross-cut, which is what a panel saw does; grain true forbids\nrotating parts unless a part sets rotate true. Use for cabinet, sign\nand sheet-metal cut lists. Not proven optimal: a best-fit shelf\nheuristic, reported as such. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"sheets and parts must be non-empty lists (<value> and <value>)\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"grain": {
"default": false,
"description": "true when parts must keep their orientation (l along the sheet's l).",
"type": "boolean"
},
"kerf": {
"default": 0,
"description": "saw blade width lost per cut.",
"type": "number"
},
"parts": {
"description": "{id, l, w, qty, rotate}; rotate overrides the grain rule per part.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"sheets": {
"description": "{id, l, w, qty}; used in the order given.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"sheets",
"parts"
],
"type": "object"
},
"name": "cutting_stock_2d",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Straight-line (great-circle) distance matrix from coordinates. FREE.\n\nTypical input {\"points\": [{\"id\": \"depot\", \"lat\": 51.5, \"lon\": -0.12},\n{\"id\": \"A\", \"lat\": 51.52, \"lon\": -0.1}]} returns {\"matrix\": [[0,\n2.6], [2.6, 0]], \"unit\": \"km\", \"kind\": \"straight-line (haversine), not\nroad distance\"}. Use when you have no road matrix and a straight-line\napproximation is acceptable, or to sanity-check one. Not road routing:\nreal driving distances are longer and the difference is not uniform. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"points must be a list of at least two <value> objects\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"points": {
"description": "list of {id, lat, lon} (up to 200).",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"unit": {
"default": "km",
"description": "km (default) or mi.",
"type": "string"
}
},
"required": [
"points"
],
"type": "object"
},
"name": "distance_matrix_haversine",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Plain-language summary of a solution from this server and the constraints that bind. FREE.\n\nTypical input {\"solution\": <result of route_plan_fleet>} returns\n{\"summary\": \"2 vehicles serve 14 stops over 96.4 km; 1 stop unserved\",\n\"binding_constraints\": [\"van2 is at 100% of capacity\", \"stop C arrives\nat the end of its window\"], \"status\": \"FEASIBLE\"}. It recognises\nresults from route_plan, route_plan_fleet, pack_bins, cutting_stock_1d,\ncutting_stock_2d, roster_shifts and knapsack_select by their fields.\nUse to turn solver output into a message for a dispatcher or a shop\nfloor. Not a re-solve. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"solution must be the result object returned by a solve tool on this server\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"solution": {
"additionalProperties": true,
"description": "the result object returned by one of this server's solve tools.",
"type": "object"
}
},
"required": [
"solution"
],
"type": "object"
},
"name": "explain_solution",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Choose the items that maximise value under one or more capacity limits. FREE.\n\nTypical input {\"items\": [{\"id\": \"a\", \"value\": 60, \"weight\": 10, \"cost\":\n120}, {\"id\": \"b\", \"value\": 100, \"weight\": 20, \"cost\": 300}], \"limits\":\n{\"weight\": 25, \"cost\": 400}} returns {\"selected\": [\"a\"], \"value\": 60,\n\"used\": {\"weight\": 10, \"cost\": 120}, \"slack\": {\"weight\": 15, \"cost\":\n280}, \"solver_status\": \"OPTIMAL\"}. Any numeric item field named in\nlimits is a constrained resource; qty lets an item be taken several\ntimes. Use for budgets, cargo, campaign or feature selection. Not for\ndependencies between items. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"items must be a non-empty list of <value>\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"items": {
"description": "{id, value, qty, <resource fields>}: value to maximise plus one number per limited resource.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"limits": {
"additionalProperties": true,
"description": "{resource_name: capacity} for each constrained field.",
"type": "object"
},
"time_limit_s": {
"default": 3,
"description": "solver time budget in seconds (default 3, max 15).",
"maximum": 15,
"minimum": 0,
"type": "number"
}
},
"required": [
"items",
"limits"
],
"type": "object"
},
"name": "knapsack_select",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Place up to 20 boxes into containers or pallets with rotation, weight and support rules. FREE.\n\nTypical input {\"items\": [{\"id\": \"A\", \"l\": 60, \"w\": 40, \"h\": 30,\n\"weight\": 12, \"qty\": 4}], \"containers\": [{\"id\": \"pallet\", \"l\": 120,\n\"w\": 80, \"h\": 150, \"max_weight\": 500, \"qty\": 2}]} returns\n{\"containers_used\": 1, \"containers\": [{\"placements\": [{\"id\": \"A\",\n\"x\": 0, \"y\": 0, \"z\": 0, \"l\": 60, \"w\": 40, \"h\": 30}, ...],\n\"volume_fill_pct\": 20.0}], \"unplaced\": []}. rotation per item: any,\nupright (rotate around the vertical axis only) or fixed; fragile items\ncarry nothing; rules.min_support (default 0.6) is the share of a box's\nbase that must rest on the floor or on boxes below. Use to decide pallet\nor carton count before booking freight. Not proven optimal: it is a\nfirst-fit-decreasing heuristic, reported as such. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"}. Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"containers": {
"description": "list of {id, l, w, h, max_weight, qty}; used in the order given.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"items": {
"description": "list of {id, l, w, h, weight, qty, rotation, fragile}, all in one length unit.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"rules": {
"additionalProperties": true,
"default": {},
"description": "optional {min_support: 0-1, default_rotation: any|upright|fixed}.",
"type": "object"
}
},
"required": [
"items",
"containers"
],
"type": "object"
},
"name": "pack_bins",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Same packer as pack_bins for up to 300 item units and 200 containers. PREMIUM (license).\n\nTypical input {\"items\": [{\"id\": \"SKU1\", \"l\": 40, \"w\": 30, \"h\": 20,\n\"weight\": 5, \"qty\": 120}, ...], \"containers\": [{\"id\": \"euro-pallet\",\n\"l\": 120, \"w\": 80, \"h\": 180, \"max_weight\": 800, \"qty\": 10}]} returns\nthe same shape as pack_bins: containers with placements, fill\npercentages, weights and any unplaced units. Use for order\nconsolidation and load planning. Not proven optimal (first-fit\ndecreasing on extreme points, reported as such). Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"}. Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"containers": {
"description": "list of {id, l, w, h, max_weight, qty}.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"items": {
"description": "list of {id, l, w, h, weight, qty, rotation, fragile}.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"rules": {
"additionalProperties": true,
"default": {},
"description": "optional {min_support: 0-1, default_rotation: any|upright|fixed}.",
"type": "object"
}
},
"required": [
"items",
"containers"
],
"type": "object"
},
"name": "pack_bins_large",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Assign staff to shifts under availability, skills, hour caps and rest gaps. PREMIUM (license).\n\nTypical input {\"staff\": [{\"id\": \"ana\", \"skills\": [\"till\"],\n\"max_hours\": 40, \"unavailable\": [\"sat-am\"]}, ...], \"shifts\": [{\"id\":\n\"sat-am\", \"start\": \"2026-09-12T08:00\", \"end\": \"2026-09-12T14:00\",\n\"required\": 2, \"skill\": \"till\"}, ...], \"rules\": {\"min_rest_hours\": 11,\n\"max_consecutive_days\": 6}} returns {\"assignments\": [{\"shift\":\n\"sat-am\", \"staff\": [\"ana\", \"ben\"]}], \"unfilled\": [{\"shift\": \"sun-pm\",\n\"short\": 1}], \"hours\": {\"ana\": 30.0}, \"solver_status\": \"OPTIMAL\"}. The\nobjective fills as many required slots as possible, then spreads hours\nevenly, then honours preferences (staff.prefer / staff.avoid shift ids).\nUse for weekly rotas of up to 60 staff and 150 shifts. Not a\ndetermination of labour-law compliance: the rules are the ones you pass. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"staff and shifts must be non-empty lists\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"rules": {
"additionalProperties": true,
"default": {},
"description": "{min_rest_hours (default 0), max_consecutive_days (default 7), max_shifts_per_day (default 1)}.",
"type": "object"
},
"shifts": {
"description": "{id, start, end (ISO 8601 local), required, skill, weight}.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"staff": {
"description": "{id, skills[], max_hours, min_hours, unavailable[], prefer[], avoid[], max_shifts}.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"time_limit_s": {
"default": 10,
"description": "solver time budget in seconds (default 10, max 60).",
"maximum": 60,
"minimum": 0,
"type": "number"
}
},
"required": [
"staff",
"shifts"
],
"type": "object"
},
"name": "roster_shifts",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Order up to 12 stops into the shortest single-vehicle route on your distance matrix. FREE.\n\nTypical input {\"stops\": [{\"id\": \"depot\"}, {\"id\": \"A\"}, {\"id\": \"B\"}],\n\"matrix\": [[0, 5, 9], [5, 0, 4], [9, 4, 0]]} returns {\"routes\":\n[{\"vehicle\": 0, \"stops\": [...], \"distance\": 18.0}], \"total_distance\":\n18.0, \"solver_status\": \"FEASIBLE\", \"note\": \"...\"}. The matrix is in\nyour units (km, minutes, cost) and must be square with the depot at\nindex 0 unless depot says otherwise; optional demand per stop with\nvehicle_capacity turns it into a capacity check. Use for one driver's\nday or a courier's loop. Not for several vehicles or time windows: use\nroute_plan_fleet. Not a map service: bring your own distances or call\ndistance_matrix_haversine for straight-line values. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"stops must be a list of stop objects, depot first\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"depot": {
"default": 0,
"description": "index of the depot in stops (default 0).",
"type": "integer"
},
"matrix": {
"description": "square distance (or time) matrix, row i column j = cost from stop i to stop j.",
"items": {
"items": {
"type": "number"
},
"type": "array"
},
"type": "array"
},
"stops": {
"description": "list of stop objects, depot first: id, optional demand.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"time_limit_s": {
"default": 3,
"description": "solver time budget in seconds (default 3, max 15).",
"maximum": 15,
"minimum": 0,
"type": "number"
},
"vehicle_capacity": {
"default": 0,
"description": "optional capacity in the units of demand (0 = unlimited).",
"type": "number"
}
},
"required": [
"stops",
"matrix"
],
"type": "object"
},
"name": "route_plan",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Capacitated, time-windowed routing for a fleet over up to 200 stops. PREMIUM (license).\n\nTypical input {\"stops\": [{\"id\": \"depot\", \"window\": [480, 1080]},\n{\"id\": \"A\", \"demand\": 3, \"window\": [540, 720], \"service_min\": 10}, ...],\n\"matrix\": [[...]], \"vehicles\": [{\"id\": \"van1\", \"capacity\": 10},\n{\"id\": \"van2\", \"capacity\": 8, \"max_distance\": 120}]} returns {\"routes\":\n[{\"vehicle\": \"van1\", \"stops\": [{\"id\": \"A\", \"arrive_min\": 545, ...}],\n\"distance\": 42.5, \"load\": 9}], \"unserved\": [], \"solver_status\":\n\"FEASIBLE\"}. Windows and service times are minutes from the start of\nthe day; travel time comes from time_matrix (minutes) or, if absent, the\ndistance matrix read as minutes. Set drop_penalty to allow stops to be\nleft unserved at that cost instead of returning INFEASIBLE. Use for\ndaily dispatch. Not a map service; bring your own matrices. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"stops must be a list of stop objects, depot first\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"depot": {
"default": 0,
"description": "index of the depot in stops (default 0).",
"type": "integer"
},
"drop_penalty": {
"default": 0,
"description": "cost of leaving a stop unserved (0 = every stop must be served).",
"type": "number"
},
"matrix": {
"description": "square distance matrix in your units.",
"items": {
"items": {
"type": "number"
},
"type": "array"
},
"type": "array"
},
"stops": {
"description": "depot first; each: id, demand, window [earliest_min, latest_min], service_min.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
},
"time_limit_s": {
"default": 10,
"description": "solver time budget in seconds (default 10, max 60).",
"maximum": 60,
"minimum": 0,
"type": "number"
},
"time_matrix": {
"default": [],
"description": "optional square travel-time matrix in minutes (defaults to matrix).",
"items": {
"items": {
"type": "number"
},
"type": "array"
},
"type": "array"
},
"vehicles": {
"description": "list of {id, capacity, max_distance}; capacity in the units of demand.",
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array"
}
},
"required": [
"stops",
"matrix",
"vehicles"
],
"type": "object"
},
"name": "route_plan_fleet",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
},
{
"description": "Check a problem's shape and obvious feasibility before spending solver time. FREE.\n\nTypical input {\"type\": \"route\", \"problem\": {\"stops\": [...], \"matrix\":\n[[...]], \"vehicles\": [...]}} returns {\"ok\": false, \"issues\": [\"total\ndemand 34 exceeds total capacity 30\"], \"size\": {\"stops\": 14,\n\"vehicles\": 2}, \"tier_hint\": \"route_plan_fleet (licence) - more than 12\nstops\"}. Types: route, pack, cut1d, cut2d, roster, knapsack; the problem\nobject uses the same fields as the matching tool. Use first when an\nagent has assembled the problem from other data. Not a solve: it never\ncalls the solver. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {\"error\": \"<what is wrong and how to fix it>\"} (for example {\"error\": \"type must be one of <value>\"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.",
"inputSchema": {
"additionalProperties": false,
"properties": {
"problem": {
"additionalProperties": true,
"description": "the same object you would pass to the tool (stops/matrix/vehicles, items/containers, ...).",
"type": "object"
},
"type": {
"description": "route, pack, cut1d, cut2d, roster or knapsack.",
"type": "string"
}
},
"required": [
"type",
"problem"
],
"type": "object"
},
"name": "validate_problem",
"outputSchema": {
"additionalProperties": true,
"type": "object"
}
}
]
}Verify it yourself
curl -s https://api.teppi.xyz/v1/evidence/sha256:67c26e9f2473361bdcc72ba5e5c2c2d615951e1c5d2a40ccfdfbebea8ea39aab | sha256sum