MCP workflows
The 5 workflows provided by the server. A single workflow call performs the work of several tools and returns one concise response, so an assistant needs one turn instead of several. Every workflow is verified nightly in the same way as every tool.
All workflows
Each workflow makes real API requests, up to the number shown, and each request counts against your plan. The last column shows the result of the most recent nightly verification.
| Workflow | Plan | Requests | Last verified |
|---|---|---|---|
gunspec_identify_firearmIdentify a firearm | Builder | Up to 4 | Not run yet |
gunspec_compare_by_nameCompare firearms by name | Builder | Up to 6 | Not run yet |
gunspec_what_fitsWhat fits a firearm | Studio | Up to 2 | Not run yet |
gunspec_cartridge_profileCartridge profile | Explorer | Up to 5 | Not run yet |
gunspec_load_compareCompare loads downrange | Builder | Up to 9 | Not run yet |
Identify a firearm
Workflow. Converts an informally written firearm name ("G19 gen 5", "M4A1") into one specification card in a single call. The card contains the matched record's key figures, calibers, variant count and first image. If the name matches more than one record, the tool returns the candidates instead of guessing. Ask the user which one they meant, then call the tool again with that id. Replaces the resolve, get, variants and media calls.
Example usage
- 1
A person asks
- Tell me everything about the Glock 17.
- What is a Glock 17, and which variants of it exist?
- 2
The assistant calls the tool
tools/calljson{ "name": "gunspec_identify_firearm", "arguments": { "name": "Glock 17" }} - 3
The server answers
Resultjson{ "resolved": true, "firearm": { "id": "glock-g17", "name": "Glock 17", "version": "1dc0085f469a3786f9cd4fce92845f4beffcb0494239e4419a17c3adf09b4749", "manufacturer": { "id": "glock", "name": "Glock Ges.m.b.H." }, "category": "Pistol", "actionType": "short_recoil", "status": "in_production", "countryOfOrigin": "AT", "yearIntroduced": 1982, "yearDiscontinued": null, "designer": "Gaston Glock", "calibers": [ { "id": "9x19mm-parabellum", "name": "9x19mm Parabellum", "isPrimary": 1 } ], "magazineCapacity": 17, "weightEmptyG": 625, "overallLengthMm": 204, "barrelLengthMm": 114, "muzzleVelocityMps": 375, "effectiveRangeM": 50, "dataConfidence": 0.9 }, "variants": { "count": 6, "sample": [ { "id": "glock-g18", "name": "Glock 18" }, { "id": "glock-g17-gen4", "name": "Glock G17 Gen4" }, { "id": "glock-g17-gen5", "name": "Glock G17 Gen5" } ] }, "media": { "count": 4, "first": { "kind": "silhouette", "url": "https://assets.gunspec.io/firearms/line/svg/glock-g17.svg" } }, "gaps": []}Captured from the live API on Sep 17, 2026. Lists and long text are shortened for display.
Steps
The requests this workflow makes, in order. If your plan does not include an optional step, that step is omitted and listed under gaps in the response, together with the plan it requires.
- 1
Resolve a name to one firearm
- 2
Get a firearm
- 3
List variants
Optional. If your plan does not include this request, it is skipped and listed under gaps in the response.
- 4
List every asset for a firearm
Optional. If your plan does not include this request, it is skipped and listed under gaps in the response.
One response
The workflow combines up to 4 requests into a single response for the assistant.
Arguments
| Name | Type | Description |
|---|---|---|
name (required) | string | The firearm name as the user wrote it, or a slug id. |
detail | string | The level of detail to return. `summary` (the default) keeps the response small. `full` adds descriptions and longer lists. One of: summary, full Default: summary |
Compare firearms by name
Workflow. Compares two to five firearms, named as the user wrote them ("G19", "P320 Compact"), in a single call. Each name is resolved to a record, and only the figures that differ are returned. The lightest, shortest and highest-capacity firearms are identified. Names that do not match a single record are listed under `unresolved` with their candidates and are never guessed. Replaces one resolve call per name plus one compare call.
Example usage
- 1
A person asks
- Compare the Glock 17 and the Beretta 92FS.
- 2
The assistant calls the tool
tools/calljson{ "name": "gunspec_compare_by_name", "arguments": { "names": [ "Glock 17", "Beretta 92FS" ] }} - 3
The server answers
Resultjson{ "compared": true, "firearms": [ { "id": "glock-g17", "name": "Glock 17", "version": "1dc0085f469a3786f9cd4fce92845f4beffcb0494239e4419a17c3adf09b4749", "manufacturer": "Glock Ges.m.b.H.", "primaryCaliber": "9x19mm Parabellum" }, { "id": "beretta-92fs", "name": "Beretta 92FS", "version": "37fc8cf70018f3668accdc9e458e617dd2f6b7271eb8c7f0d06e473f6c8892e9", "manufacturer": "Beretta", "primaryCaliber": "9x19mm Parabellum" } ], "differences": [ { "field": "weightEmptyG", "values": [ 625, 945 ], "min": 625, "max": 945, "percentDiff": 51.2 }, { "field": "weightLoadedG", "values": [ 905, 1100 ], "min": 905, "max": 1100, "percentDiff": 21.55 }, { "field": "barrelLengthMm", "values": [ 114, 125 ], "min": 114, "max": 125, "percentDiff": 9.65 } ], "leaders": { "lightest": { "id": "glock-g17", "name": "Glock 17", "value": 625 }, "shortest": { "id": "glock-g17", "name": "Glock 17", "value": 204 }, "highestCapacity": { "id": "glock-g17", "name": "Glock 17", "value": 17 } }, "unresolved": []}Captured from the live API on Sep 17, 2026. Lists and long text are shortened for display.
Steps
The requests this workflow makes, in order. If your plan does not include an optional step, that step is omitted and listed under gaps in the response, together with the plan it requires.
- 1
Resolve a name to one firearm
- 2
Compare firearms
One response
The workflow combines up to 6 requests into a single response for the assistant.
Arguments
| Name | Type | Description |
|---|---|---|
names (required) | string[] | Two to five firearm names or slug ids. Names beyond the fifth are ignored. |
What fits a firearm
Workflow. Returns the optics, muzzle devices, stocks, grips and magazines that attach to a firearm, computed from its mounting interfaces, in a single call. Where a seller lists a part, the response includes where to buy it. Provide the firearm as the user named it and, optionally, a category ("optic", "muzzle", "stock"). The response contains the firearm's mounts, followed by up to ten compatible parts per category. Each part states how it fits (direct or through an adapter) and lists its offers. If the name matches more than one firearm, the tool returns the candidates instead. Replaces the resolve call, the attachments call and one offers call per part.
Example usage
- 1
A person asks
- Which optics fit an AK-74M?
- 2
The assistant calls the tool
tools/calljson{ "name": "gunspec_what_fits", "arguments": { "firearm": "AK-74M", "category": "optic" }} - 3
The server answers
Resultjson{ "resolved": true, "firearm": { "id": "ak-74m", "name": "AK-74M" }, "platforms": [ { "id": "ak-100", "name": "AK-100 series (AK-74M pattern)" } ], "mounts": [ { "position": "mag_well", "standard": "AK 5.45x39 magazine well", "source": "curated", "confidence": 1 }, { "position": "muzzle", "standard": "M24x1.5 right hand (AK-74, AK-100 series)", "source": "curated", "confidence": 1 }, { "position": "grip", "standard": "AK pistol grip nut and screw", "source": "inherited:platform", "confidence": 1 } ], "total": 45, "categories": [ { "category": "optic", "count": 45, "items": [ { "id": "aimpoint-compm5", "name": "Aimpoint CompM5", "manufacturer": "Aimpoint AB", "fitType": "adapter", "via": "UFM KeyMod System for AKM Rifles, Long Version", "confidence": 1, "offers": [] }, { "id": "aimpoint-duty-rds", "name": "Aimpoint Duty RDS", "manufacturer": "Aimpoint AB", "fitType": "adapter", "via": "UFM KeyMod System for AKM Rifles, Long Version", "confidence": 1, "offers": [] }, { "id": "aimpoint-micro-t-2", "name": "Aimpoint Micro T-2", "manufacturer": "Aimpoint AB", "fitType": "adapter", "via": "UFM KeyMod System for AKM Rifles, Long Version", "confidence": 1, "offers": [] } ] } ]}Captured from the live API on Sep 17, 2026. Lists and long text are shortened for display.
Steps
The requests this workflow makes, in order. If your plan does not include an optional step, that step is omitted and listed under gaps in the response, together with the plan it requires.
- 1
Resolve a name to one firearm
- 2
List attachments that fit a firearm
One response
The workflow combines up to 2 requests into a single response for the assistant.
Arguments
| Name | Type | Description |
|---|---|---|
firearm (required) | string | The firearm name as the user wrote it, or a slug id. |
category | string | One attachment category, e.g. "optic", "muzzle", "stock", "grip" or "magazine". |
min_confidence | number | Hides fits derived from inferred data below this confidence (0 to 1). 0 to 1 |
Cartridge profile
Workflow. Returns a complete profile of one cartridge in a single call: its dimensions and pressure, its parent cartridge and the cartridges derived from it, its common loads, and the number of catalog firearms chambered for it. Provide the caliber as the user wrote it (".308", "9mm") or as a slug. If the name matches several cartridges, the tool returns the candidates. On plans below Builder, the lineage and loads are listed under `gaps` with the plan they require. Replaces the caliber lookup, family, ammunition and firearms calls.
Example usage
- 1
A person asks
- Give me a profile of the 7.62x51mm NATO cartridge.
- 2
The assistant calls the tool
tools/calljson{ "name": "gunspec_cartridge_profile", "arguments": { "caliber": "7-62x51mm-nato" }} - 3
The server answers
Resultjson{ "resolved": true, "caliber": { "id": "7-62x51mm-nato", "name": "7.62x51mm NATO", "version": "6c64ecb4a99cebfb937e367c4f1fd1adb1886e0ce4fb80aa3be84b36b9fa0741", "cartridgeType": "rimless", "natoDesignation": "7.62x51mm NATO", "yearIntroduced": 1954, "bulletDiameterMm": 7.82, "caseLengthMm": 51.18, "overallLengthMm": 71.12, "typicalBulletWeightG": 9.5, "typicalMuzzleVelocityMps": 838, "typicalMuzzleEnergyJ": 3457, "maxPressureMpa": 415 }, "firearmsChambered": 244, "lineage": { "ancestors": [ { "id": "300-savage", "name": ".300 Savage" } ], "descendants": [ { "id": "7-62x51mm-cetme", "name": "7.62x51mm CETME" } ] }, "commonLoads": { "total": 9, "sample": [ { "id": "adi-gameking-165", "name": "ADI World Class 165gr GameKing", "bulletType": "SBT", "bulletWeightG": 10.69 }, { "id": "fgmm-168", "name": "Federal Gold Medal Match 168gr", "bulletType": "OTM", "bulletWeightG": 10.89 }, { "id": "hornady-eldm-168", "name": "Hornady 168gr ELD Match", "bulletType": "Polymer Tip", "bulletWeightG": 10.89 } ] }, "gaps": []}Captured from the live API on Sep 17, 2026. Lists and long text are shortened for display.
Steps
The requests this workflow makes, in order. If your plan does not include an optional step, that step is omitted and listed under gaps in the response, together with the plan it requires.
- 1
Get a caliber
- 2
List calibers
- 3
List firearms in a caliber
- 4
Get the cartridge family
Optional. If your plan does not include this request, it is skipped and listed under gaps in the response.
- 5
List ammunition for a caliber
Optional. If your plan does not include this request, it is skipped and listed under gaps in the response.
One response
The workflow combines up to 5 requests into a single response for the assistant.
Arguments
| Name | Type | Description |
|---|---|---|
caliber (required) | string | The cartridge as the user wrote it, e.g. ".308 Winchester", or a slug id. |
Compare loads downrange
Workflow. Compares the ammunition loads for one cartridge fired from the same barrel, in a single call. Returns velocity, energy and drop at each distance for every load, ranked by energy at the farthest distance. The flattest and hardest-hitting loads are identified. Provide the caliber slug (use gunspec_cartridge_profile or gunspec_list_calibers to find it) and, optionally, a barrel length, distances, a bullet type and the number of loads. Replaces one ammunition list call plus one ballistics call per load.
Example usage
- 1
A person asks
- Compare three 9mm loads from a 114 mm barrel at 0, 25 and 50 metres.
- 2
The assistant calls the tool
tools/calljson{ "name": "gunspec_load_compare", "arguments": { "caliber_id": "9x19mm-parabellum", "barrel_length_mm": 114, "distances": [ 0, 25, 50 ], "limit": 3 }} - 3
The server answers
Resultjson{ "caliberId": "9x19mm-parabellum", "distancesM": [ 0, 25, 50 ], "loads": [ { "id": "federal-hst-124jhp", "name": "Federal Premium HST 124gr JHP", "bulletType": "JHP", "bulletWeightG": 8.04, "barrelLengthMm": 114, "muzzleVelocityMps": 359, "muzzleEnergyJ": 518, "effectiveRangeM": 185, "trajectory": [ { "distanceM": 0, "velocityMps": 359, "energyJ": 518, "dropCm": 0 }, { "distanceM": 25, "velocityMps": 333, "energyJ": 446, "dropCm": 2.6 }, { "distanceM": 50, "velocityMps": 313, "energyJ": 393, "dropCm": 11 } ], "energyAtFarthestJ": 393, "dropAtFarthestCm": 11 }, { "id": "hornady-critical-duty-135", "name": "Hornady Critical Duty 135gr FlexLock", "bulletType": "FlexLock", "bulletWeightG": 8.75, "barrelLengthMm": 114, "muzzleVelocityMps": 316, "muzzleEnergyJ": 438, "effectiveRangeM": 178, "trajectory": [ { "distanceM": 0, "velocityMps": 316, "energyJ": 438, "dropCm": 0 }, { "distanceM": 25, "velocityMps": 304, "energyJ": 404, "dropCm": 3.2 }, { "distanceM": 50, "velocityMps": 293, "energyJ": 377, "dropCm": 13.3 } ], "energyAtFarthestJ": 377, "dropAtFarthestCm": 13.3 }, { "id": "adi-world-class-124jhp", "name": "ADI World Class 124gr JHP", "bulletType": "JHP", "bulletWeightG": 8.04, "barrelLengthMm": 114, "muzzleVelocityMps": 347, "muzzleEnergyJ": 485, "effectiveRangeM": 181, "trajectory": [ { "distanceM": 0, "velocityMps": 347, "energyJ": 485, "dropCm": 0 }, { "distanceM": 25, "velocityMps": 322, "energyJ": 417, "dropCm": 2.8 }, { "distanceM": 50, "velocityMps": 304, "energyJ": 371, "dropCm": 11.8 } ], "energyAtFarthestJ": 371, "dropAtFarthestCm": 11.8 } ], "leaders": { "mostEnergyAtFarthest": { "id": "federal-hst-124jhp", "name": "Federal Premium HST 124gr JHP", "energyJ": 393 }, "flattest": { "id": "federal-hst-124jhp", "name": "Federal Premium HST 124gr JHP", "dropCm": 11 } }}Captured from the live API on Sep 17, 2026.
Steps
The requests this workflow makes, in order. If your plan does not include an optional step, that step is omitted and listed under gaps in the response, together with the plan it requires.
- 1
List ammunition loads
- 2
Compute a ballistic table
One response
The workflow combines up to 9 requests into a single response for the assistant.
Arguments
| Name | Type | Description |
|---|---|---|
caliber_id (required) | string | The caliber slug, e.g. "9x19mm-parabellum". |
barrel_length_mm | integer | Barrel length for every load, in mm (50 to 2000). Omit for each load's reference barrel. 50 to 2000 |
distances | integer[] | Distances in metres. Defaults to 0, 100, 200 and 300. |
bullet_type | string | Return only loads of this bullet type, e.g. "JHP" or "FMJ". |
limit | integer | Number of loads to compare, from 1 to 8. 1 to 8 Default: 5 |