Skip to main content
Glama
simeptk

mcp-migration-tools

by simeptk

mcp-migration-tools

A small, public-safe FastMCP server that exposes practical legacy-to-modern migration helpers as AI-callable tools — the same "thin tool wrapper over tested, pure logic" pattern I use on a larger production MCP server, distilled into a clean, fully generic example.


Why this exists

Modernizing 100+ legacy apps means doing the same analysis over and over: what stack is this? what endpoints does it expose? how do I port this DDL? how big is the job? These are perfect MCP tools — small, deterministic, and callable by an AI agent (or a human) on demand.

Related MCP server: legacy-web-mcp

The tools

Tool

What it does

detect_stack

Infers the dominant tech stack from a file listing (weights manifests over single files)

extract_api_contract

Pulls {method, path} REST endpoints from Spring controller source

sql_to_flyway

Converts SQL Server DDL into a portable Flyway migration (identity cols, MONEY, NVARCHAR, GETDATE(), brackets, GO, dbo.)

estimate_migration_effort

Transparent person-day estimate from coarse inventory counts, with a risk band

Design: pure logic + thin MCP layer

tools/*.py         ← pure, dependency-free functions (100% unit-tested)
   ▲
server.py          ← FastMCP wrappers: @mcp.tool() delegating to the pure logic

Keeping the logic free of the MCP runtime means every tool is fast to test and reusable outside MCP — the tests don't even import fastmcp.

Quick start

# install
pip install .[dev]

# run the tests (17 passing)
pytest -q

# run the MCP server (stdio transport)
mcp-migration-tools

Use the tools directly (no MCP needed)

from mcp_migration_tools.tools import detect_stack, sql_to_flyway

detect_stack(["ProductList.asp", "web.config"])
# {'stack': 'aspnet', 'confidence': 0.75, ...}

sql_to_flyway("CREATE TABLE [dbo].[Product]([Id] INT IDENTITY(1,1))", version=1,
              description="create product")
# {'filename': 'V1__create_product.sql', 'body': 'CREATE TABLE Product(Id INT GENERATED BY DEFAULT AS IDENTITY)\n'}

Register with an MCP client

Example client config (e.g. for an MCP-capable IDE/agent):

{
  "mcpServers": {
    "migration-tools": {
      "command": "mcp-migration-tools"
    }
  }
}

Project structure

mcp-migration-tools/
├── src/mcp_migration_tools/
│   ├── server.py                 # FastMCP server (tool registration)
│   └── tools/                    # pure, tested logic
│       ├── stack_detector.py
│       ├── api_extractor.py
│       ├── sql_translator.py
│       └── effort_estimator.py
├── tests/                        # pytest suite (one file per tool)
├── .github/workflows/ci.yml      # test on Python 3.11 & 3.12
└── pyproject.toml

Part of my modernization portfolio · simeptk.github.io · companion to legacy-to-modern-demo

Available Tools

4 tools
detect_stackB

Infer the dominant technology stack from a list of file paths.

ParametersJSON Schema
NameRequiredDescriptionDefault
filesYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It does not explain how the stack is inferred, what the output format is (beyond an output schema existing), or any edge cases like empty file lists. The description is generic and lacks insight into the tool's behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence that is front-loaded with the core action. It contains no extraneous information and is appropriately sized for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having one parameter and an output schema, the description provides minimal context. It lacks any guidance on when to use the tool relative to siblings, what constitutes 'dominant,' or any limitations. For an Agent, this is insufficient for confident tool selection, especially with no annotations to fill gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema defines 'files' as an array of strings with no description, and the overall schema coverage is 0%. The description adds the semantic that these strings are 'file paths,' which clarifies the parameter's purpose. However, it does not specify path types, constraints (e.g., non-empty), or how the array is interpreted, leaving some ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool infers the dominant technology stack from file paths, using a specific verb ('infer') and resource ('technology stack'). It distinguishes itself from siblings like extract_api_contract and sql_to_flyway by focusing on stack detection rather than contract extraction or migration conversion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives, nor are any exclusions or prerequisites mentioned. The single-sentence description implies usage only through its function, leaving the agent to infer context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

estimate_migration_effortA

Estimate migration effort in person-days from coarse inventory counts.

ParametersJSON Schema
NameRequiredDescriptionDefault
klocNo
pagesNo
tablesNo
integrationsNo
stored_procsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It states the tool estimates effort, but does not disclose the model, assumptions, accuracy, or nature of the output. There is no mention of whether the estimate is deterministic, what formula is used, or what the result contains. This is a significant gap for a tool that produces a derived value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with zero wasted words. It perfectly balances brevity with conveying the core purpose and input characteristics.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is relatively simple with five optional numeric parameters and an output schema present. The description conveys the main purpose, but lacks context about the output format, assumptions, or how to interpret the result. Since no annotations exist, the description alone is slightly too minimal for full completeness, but the output schema mitigates some gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 adds the collective meaning 'coarse inventory counts' to the numeric parameters, indicating they are approximate inputs rather than precise figures. This adds some value beyond the raw schema, but it does not explain individual parameters or their units in detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Estimate') and a clear resource ('migration effort') with a unit ('person-days'). It clearly distinguishes from sibling tools like extract_api_contract and sql_to_flyway, which are about code transformation and contract extraction, not effort estimation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'from coarse inventory counts' implies when to use: when you have approximate counts of code, pages, etc., and need an effort estimate. However, it does not explicitly state when not to use it or mention alternatives. It provides an implied usage context but lacks explicit exclusion or alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

extract_api_contractA

Extract REST endpoints ({method, path}) from Spring controller source.

ParametersJSON Schema
NameRequiredDescriptionDefault
sourceYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It states the action ('extract') but does not explicitly mention whether the operation is read-only, how errors are handled, or any side effects. This leaves the agent without important context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that is front-loaded with the verb 'Extract'. It contains no unnecessary words and is easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has one parameter and an output schema, simplifying the description's job. However, the description is still incomplete because it omits input format specifics (path vs content) and the exact scanning behavior. It meets the minimum bar but lacks depth.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema lists a single 'source' string with 0% description coverage. The description adds meaning by specifying the source is 'Spring controller source', which clarifies the parameter's purpose. However, it does not clarify whether 'source' is a file path or inline code, leaving ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Extract' and defines the exact output format ({method, path}) and input type ('Spring controller source'). This clearly distinguishes it from siblings like 'detect_stack' or 'sql_to_flyway', which have different purposes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'from Spring controller source' implies it is meant for analyzing Spring controllers, giving a clear use case. However, no explicit guidance is provided on when to use this tool versus alternatives, nor any exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sql_to_flywayB

Convert SQL Server DDL into a portable Flyway migration file.

ParametersJSON Schema
NameRequiredDescriptionDefault
ddlYes
versionNo
descriptionNomigration

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It mentions 'portable' and 'Flyway migration' but does not disclose whether DML is supported, how output is returned, or any limitations with unsupported SQL Server syntax. Minimal behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence of nine words, front-loaded with the action and outcome. No filler or redundant content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite an output schema existing, the description provides no guidance on expected outputs or usage scenarios. With three parameters and no annotations, this short description is under-specified for an agent to confidently invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description needed to compensate. It only hints at the 'ddl' parameter via 'SQL Server DDL', but says nothing about 'version' or 'description' parameters, leaving their semantics unexplained.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Convert' with a clear resource 'SQL Server DDL' and target 'portable Flyway migration file'. It clearly distinguishes itself from sibling tools that handle API contracts, stack detection, and migration effort estimation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the description: when you have SQL Server DDL and want a Flyway migration. However, there is no explicit statement of when to use this tool versus alternatives, nor any exclusions or prerequisites.

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.

  1. 4 tool updatesv1.0.0
    • First observeddetect_stack
    • First observedestimate_migration_effort
    • First observedextract_api_contract
    • First observedsql_to_flyway

TDQS

A3.5/5.0

Scored across 4 tools

Disambiguation5/5

Each tool targets a unique aspect of migration: API extraction, SQL conversion, stack detection, and effort estimation. No two tools perform similar or overlapping functions, making selection unambiguous.

Naming Consistency4/5

The naming style is consistent with lowercase snake_case and mostly follows a verb_noun pattern (extract_api_contract, detect_stack, estimate_migration_effort). One tool (sql_to_flyway) uses a noun_to_noun pattern, which is a minor deviation but still clear and readable.

Tool Count4/5

With 4 tools, the set is within the ideal 3-15 range and feels appropriately scoped for a focused migration utility. It is slightly sparse but each tool serves a distinct purpose.

Completeness3/5

The tools cover analysis, conversion, and estimation, but lack any migration execution or validation operations. There are notable gaps in the end-to-end migration workflow, though the existing tools are sound.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A universal bridge that turns legacy backend services and modern APIs into AI-accessible tools without requiring code rewrites. It dynamically generates tool definitions from WSDL, OpenAPI, or custom JSON specs to enable AI assistants to interact with systems like SAP, IBMi, and SOAP services.
    -
  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    Connects legacy COBOL mainframe systems to modern AI governance via MCP, with tools for parsing copybooks, assessing CICS, scanning JCL, mapping VSAM, and translating EBCDIC.
    1
    MIT