Workshop Assistant
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Workshop AssistantWhich jobs are blocked waiting on parts?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Workshop assistant
An MCP server that lets a language model answer questions about a garage's workshop — open jobs, vehicle history, parts stock, the day's bookings — by querying the workshop database directly instead of guessing.
Built as a learning project while working through Anthropic's Model Context Protocol material. The database is fictional; the point is the interface between the model and the business system, not the data behind it.
The problem
A service manager starts the day with a handful of questions that are boring to answer and expensive to get wrong:
Which jobs are stuck waiting on a part, and how long have they been stuck?
Has this car been in before for the same fault?
What does Tuesday look like — is there room to fit someone in?
Do we have front pads in stock, or does that job need ordering first?
Every one of these is a join across two or three tables. A person answers them by opening several screens and holding the result in their head. It is exactly the kind of repeated lookup that gets skipped when the workshop is busy, which is when getting it wrong costs the most.
An assistant that can read the workshop database answers them in one sentence.
Related MCP server: Jobber MCP Server
Why MCP rather than a chatbot with the data pasted in
A language model on its own knows nothing about this workshop, and pasting the database into a prompt does not scale past a few dozen rows — nor does it stay current for more than a minute.
MCP is the contract between the two. The server below advertises six named tools with typed arguments. The model chooses which to call and with what arguments; the server runs a reviewed SQL query and returns plain structured data. The model's job is to interpret the question and present the answer. The database's job is to be correct. Neither has to know how the other works.
Design decisions
Narrow tools, not a general run_sql. One tool that executes arbitrary SQL
would be far more flexible and much worse. It would make the model responsible
for correctness against a schema it has only been told about, and it would hand
a language model unrestricted write access to a live business system. Six
specific tools mean each query is written and reviewed once, by a person, and
the model only picks between them.
Read-only by default. The five read tools open the database with
mode=ro, so a bug in a query cannot modify anything. Only add_job_note
opens a writable connection. There is a test that asserts this.
One write tool, deliberately dull. add_job_note appends a note. It cannot
change a job's status, its parts or its price — those are decisions that need a
person, and an agent that can quietly re-price a job is a liability, not a
feature. Adding a note is genuinely useful (chasing a supplier, recording a
call) and safe to get wrong.
Empty results say so. Every tool returns an explicit message when nothing
matched. Handed a bare empty list, a model will often fill the silence with a
plausible-sounding job card that does not exist.
The interesting query is its own tool. jobs_blocked_on_parts could be
assembled by the model from search_jobs and parts_availability, but that
means three round trips and a join done in the model's head. It is the question
the workshop actually asks every morning, so it gets a tool.
The database path is resolved in one place. workshop.db.database_path()
reads the WORKSHOP_DB environment variable and falls back to garage.db in
the project root. That one indirection is what lets the test suite build a
fresh throwaway database for every single test, so no test can leak state into
another and any test can be run on its own.
The tools
Tool | What it answers |
| Job cards, filtered by status, registration plate or technician |
| Every visit for one vehicle, plus technician notes |
| Stock levels, with a low-stock filter |
| Open jobs where a required part is short |
| Bookings for a day, with bay, hours and job |
| (write) Append a note to a job card |
Layout
src/workshop/
db.py connection handling and where the database lives
seed.py the fictional workshop, and the script that builds it
server.py the six MCP tools
schema.sql eight tables, shipped inside the package
tests/
conftest.py a freshly seeded database per test
test_tools.py 38 tests
.mcp.json project-scoped MCP registration, no absolute paths
pyproject.toml dependencies, entry points, ruff, mypy, pytestRunning it
Requires Python 3.10+ and uv.
uv sync # creates .venv and installs everything, including dev tools
uv run workshop-seed # builds garage.db
uv run pytest # 38 testsThe MCP SDK is pinned to the 1.x line. Version 2.0 renamed FastMCP to
MCPServer and moved its import path with no deprecation period, so this
server does not run unmodified on 2.x.
From Claude Code
.mcp.json is committed, so from inside a clone of this repo there is nothing
to configure — Claude Code picks the server up automatically and asks once
whether to trust it. To register it by hand instead:
claude mcp add garage-workshop -- uv run --directory /absolute/path/to/workshop-mcp-server workshop-mcpFrom Claude Desktop
claude_desktop_config.json has no notion of a project directory, so this one
does need an absolute path:
{
"mcpServers": {
"garage-workshop": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/workshop-mcp-server", "workshop-mcp"]
}
}
}Development
uv run pytest # 38 tests
uv run ruff check . # lint and import order
uv run ruff format . # formatting
uv run mypy # types, with disallow_untyped_defsAll four are clean on main.
Example session
Which jobs are blocked waiting on parts?
Three jobs are held up:
1013 — MT66 ZXB (BMW 320d), MOT failure, catalytic converter. None in stock, on order from Driveline Components. Open 9 days.
1014 — GK17 OPL (Vauxhall Astra), clutch slipping, clutch kit. None in stock. Open 6 days.
1015 — BF15 NRV (Audi A4), timing belt kit. Needs 2, one in stock, so short by one. Open 4 days.
The BMW has been waiting longest, and Derek's note from the day it came in says the supplier quoted 7–10 days — that was nine days ago, so it is worth chasing today.
Has the BMW been in before for this?
Not for the emissions failure, but it has a repeat history worth knowing about. MT66 ZXB has been in three times. Seven months ago it came in for an intermittent starting fault and had a battery fitted; three months ago it came back with the same symptom and the alternator was replaced. Derek's note on the second visit says the charging voltage was low at idle — so the battery replacement had treated the symptom rather than the cause.
Add a note to 1013 saying I chased the supplier and it's due Thursday.
Added to job card 1013 (MT66 ZXB, MOT failure — catalytic converter): "Chased supplier, catalytic converter due Thursday." Note 6.
What I would add next
The parts data has a
suppliercolumn but nothing uses it. A tool that groups outstanding orders by supplier would turn three separate chase-up calls into one.technician_schedulereports booked hours but not free capacity, so it can tell you what Tuesday looks like but not whether a job fits.No authentication or audit trail. Fine for a local prototype, the first thing I would need for anything real — a note written by an agent should record that it was written by an agent.
A note on the data
Every customer, vehicle, registration plate, phone number and email address in
src/workshop/seed.py is invented for this project. The phone numbers use
Ofcom's reserved 07700 900xxx range and the email addresses use
example.com, both of which exist precisely so that test data cannot collide
with a real person.
Available Tools
6 toolsadd_job_noteA
Add a note to a job card.
The only tool here that changes anything. It is narrow on purpose: it can append a note and nothing else. It cannot alter a job's status, its parts or its price - those are decisions that need a person.
Args: job_card: The job card ID to attach the note to. note: The text of the note. author: Who the note is from.
| Name | Required | Description | Default |
|---|---|---|---|
| note | Yes | ||
| author | No | Workshop assistant | |
| job_card | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses that the tool is a mutating operation ('The only tool here that changes anything') and precisely defines the extent of mutation ('append a note and nothing else'). It does not mention any edge-case failures, but for a simple append operation this is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with a leading summary, a scope paragraph, and a simple args list. Every sentence serves a purpose; it is concise without being terse, and omits fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple append tool with an output schema, the description fully specifies what it does, its scope, and its parameters. The limitations are explicitly stated, so an agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description compensates with an Args section. It clarifies each parameter: job_card is the ID, note is the text, author is the source. This adds meaning beyond the schema's bare titles, making parameters clear.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Add a note to a job card', a clear verb+resource. It further distinguishes itself from siblings by stating 'The only tool here that changes anything' and lists what it cannot do, which disambiguates it from the other read-only tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly scopes usage: 'It is narrow on purpose: it can append a note and nothing else.' It also provides when-not guidance: 'It cannot alter a job's status, its parts or its price - those are decisions that need a person.' This tells the agent when not to use it, though it doesn't name alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_blocked_on_partsA
Open job cards that cannot proceed because a required part is short.
This is the question a service manager actually asks each morning, and it is the reason the assistant is worth having: answering it by hand means cross-referencing every open job against the stock list.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosure. It clearly states the tool returns job cards blocked by short parts, but does not add further behavioral context such as ordering, filtering, or potential performance characteristics. Since it is a read-only report, the core behavior is adequately conveyed, but additional depth is missing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence is excellent and front-loaded. However, the second paragraph is motivational filler ('this is the question... the reason the assistant is worth having') that does not aid tool invocation. It could be removed or condensed, making the description less concise than it could be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has zero parameters, an output schema, and a straightforward purpose, the description is largely complete. It explains what the tool does and the user scenario. The only minor gap is not specifying that it returns a list or any implicit limitations, but the output schema likely covers return details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the baseline is 4. The description adds no parameter-specific semantics because none exist, but it does clarify the tool's purpose which indirectly helps the agent understand no arguments are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence, 'Open job cards that cannot proceed because a required part is short,' uses a specific verb and resource with a clear condition. This distinctly differentiates it from siblings like search_jobs and parts_availability, which have more general or alternative purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context by framing it as the question a service manager asks each morning, implying this tool is for that regular check. It does not explicitly mention alternatives or exclusions, but the situational use case is clear enough to guide the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parts_availabilityA
Look up parts stock.
Args: query: Part name or SKU, full or partial. Omit to list everything. only_low_stock: If true, return only parts at or below reorder level.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | ||
| only_low_stock | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It explains the effect of each parameter (e.g., 'Omit to list everything', 'return only parts at or below reorder level'), which is useful. However, it stops short of disclosing other behaviors like response ordering or pagination, though an output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is minimal but complete, with a clear one-line purpose followed by an essential args list. Every sentence earns its place, and the format is front-loaded with the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (2 optional params, no nesting) and the presence of an output schema, the description provides sufficient context for typical lookups. It could be slightly richer on return behavior, but the output schema fills that gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does so effectively, explaining that `query` accepts full or partial part names/SKUs and can be omitted, and that `only_low_stock` filters to parts at or below reorder level. This adds meaning beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Look up parts stock,' which clearly identifies the tool's function with a specific verb and resource. While it doesn't explicitly distinguish from siblings like jobs_blocked_on_parts, the name and verb make the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It explains the parameters but fails to mention any scenario, prerequisites, or exclusion criteria that would help an agent choose this tool over siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_jobsA
Search job cards in the workshop.
Args: status: One of booked, in_progress, waiting_parts, completed, invoiced. Use "open" for anything not yet finished. reg: Registration plate, full or partial (e.g. "LM19" or "LM19 KTZ"). technician: Technician name, full or partial. limit: Maximum number of job cards to return.
| Name | Required | Description | Default |
|---|---|---|---|
| reg | No | ||
| limit | No | ||
| status | No | ||
| technician | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry behavioral transparency. It adds useful context such as partial matching for reg and technician and the 'open' status alias, but it does not disclose traits like sorting, pagination, or read-only guarantees. The search nature implies non-destructive behavior, but it is not explicitly stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a single opening sentence followed by a bulleted list of parameters. Every sentence adds value, and there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all parameters and includes helpful examples, making it functionally complete for most use cases. It does not mention result ordering or pagination behavior, but the presence of an output schema fills in return-value details, so this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description fully compensates for the 0% schema description coverage. Each parameter is explained with valid values, examples, and semantics (e.g., status accepts specific strings and 'open' as a shortcut for unfinished jobs; reg and technician support partial matches). This provides essential meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Search job cards in the workshop.' It uses a specific verb (search) and resource (job cards), and it distinguishes itself from sibling tools like vehicle_history and parts_availability, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide explicit guidance on when to use this tool versus alternatives. It lacks any mention of sibling tools, exclusions, or prerequisites, leaving the agent without clear direction for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
technician_scheduleA
Workshop bookings for a given day.
Args: day: ISO date (YYYY-MM-DD), or "today" / "tomorrow". Defaults to today. technician: Technician name, full or partial. Omit for the whole workshop.
| Name | Required | Description | Default |
|---|---|---|---|
| day | No | ||
| technician | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses key behaviors: day accepts ISO dates or 'today'/'tomorrow', defaults to today, technician allows partial matches, and omitting technician returns the whole workshop. This adds meaningful context beyond what annotations could provide, though it does not discuss output structure or edge cases (e.g., no bookings).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise summary followed by a bullet-like Args list. Every sentence provides useful information with no redundancy or filler. It is well-front-loaded and appropriately sized for a simple two-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (though not shown), the description need not explain return values. It covers all input options and defaults adequately. Minor omissions like timezone handling or error behavior are not critical for this simple query tool, but slightly more context about what constitutes a 'workshop booking' could improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must fully compensate. It explains both parameters in detail: 'day' format and accepted special values, and 'technician' partial matching and omission behavior. This goes well beyond the schema's bare property definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Workshop bookings for a given day,' which clearly identifies the tool's purpose as retrieving bookings for a specific day. It is specific enough to distinguish from sibling tools like search_jobs or vehicle_history, though it could be slightly more explicit by using a verb like 'Get' or 'List.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly communicates usage (to see bookings for a day, optionally filtered by technician), but it does not explicitly state when to use this tool versus alternatives, nor does it mention exclusions. Sibling tools are clearly different domains, so the context is adequate but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vehicle_historyA
Full service history for one vehicle, newest first.
Use this to answer questions like "has this car been in before for the same fault?" - repeat visits for one symptom are the useful signal.
Args: reg: Registration plate, full or partial.
| Name | Required | Description | Default |
|---|---|---|---|
| reg | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description must carry behavioral info. It discloses ordering ('newest first') but doesn't explicitly state it's read-only. The read-only nature is implied by 'history,' but not stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, with a clear one-sentence summary, a use-case example, and parameter explanation. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, has an output schema, and the description covers purpose, ordering, and parameter semantics. It's sufficiently complete for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides no description for 'reg.' The description compensates with 'Registration plate, full or partial,' clarifying the input format and matching flexibility. This adds meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it returns 'full service history for one vehicle, newest first,' specifying the action and resource. This distinguishes it from sibling tools like search_jobs or parts_availability.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says 'Use this to answer questions like...' giving a concrete scenario (repeat visits for the same fault). It doesn't name alternatives, but the context makes the intended use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
add_job_note - First observed
jobs_blocked_on_parts - First observed
parts_availability - First observed
search_jobs - First observed
technician_schedule - First observed
vehicle_history
TDQS
Scored across 6 tools
Each tool targets a distinct query: jobs, vehicle history, parts stock, blocked jobs, schedule, and notes. The overlap between search_jobs and jobs_blocked_on_parts is minimal because the latter is a specific cross-reference of open jobs against parts shortages, making their purposes clearly separable.
All tool names use snake_case and are descriptive, but they mix verb-noun (search_jobs, add_job_note) with noun-noun (vehicle_history, parts_availability) forms. The style is consistent and no naming is chaotic, though a stricter verb_noun pattern would make it fully predictable.
With 6 tools, the server is well-scoped for a workshop assistant. Each tool serves a clear purpose and there is no bloat or sense of missing essential tools for the intended read-heavy, note-taking workflow.
The surface covers the core informational needs: job search, vehicle history, parts availability, blocked jobs, and technician schedules, plus a narrow note-adding action. It intentionally excludes job creation or status changes, which is clearly stated, so only minor gaps exist for full lifecycle management.
Maintenance
Related MCP Connectors
No-code databases, forms, portals and AI sites. Manage records and automation via natural language.
No-code databases, forms, portals and AI sites. Manage records and automation via natural language.
No-code databases, forms, portals and AI sites. Manage records and automation via natural language.
- mcpOAuthcom.formester
Give AI agents access to form submissions — read, search, update, and process file attachments.
Related MCP Servers
- AlicenseBqualityAmaintenanceEnables AI agents to interact with the Shopmonkey REST API to manage shop management data including work orders, customers, vehicles, and inventory. It provides 33 tools across 9 resource groups with built-in support for rate limiting, concurrency control, and multi-location management.692MIT
- AlicenseAqualityFmaintenanceEnables AI assistants to access and manage Jobber field-service data including clients, jobs, invoices, and quotes through natural language interactions.633MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to query Tesla vehicle data and analytics from a TeslaMate PostgreSQL database, including battery health, driving statistics, charging sessions, and custom SQL queries.181MIT

Remapdb MCP Serverofficial
AlicenseNot gradedqualityAmaintenanceConnects AI tools to Remapdb vehicle tuning data, enabling search and retrieval of manufacturers, models, engines, and tuning information.10MIT