Install
$ agentstack add skill-wfukatsu-nexus-architect-migrate-mysql ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Orchestrates the complete MySQL to ScalarDB migration workflow through an interactive chat interface. Collects database connection parameters from the user via questions, updates the configuration file, then runs the analysis and migration skills.
Execution Instructions
You MUST follow these steps exactly in order. Do NOT skip any step.
STEP 0: Discover Plugin Installation Directory (PLUGIN_ROOT)
Run the following Bash command to get the plugin installation directory:
echo "$CLAUDE_PLUGIN_ROOT"
- If the output is a non-empty path, set
PLUGIN_ROOTto that value. - If the output is empty, run this fallback to locate it:
find ~/.claude/plugins -name "plugin.json" -path "*/architect/*" 2>/dev/null | head -1 | xargs -I{} dirname {} | xargs -I{} dirname {}
Store the result as PLUGIN_ROOT. All subagent template paths in Steps 7–11 use this variable (e.g., PLUGIN_ROOT/skills/common/subagents/mysql/0-test-connection.md).
STEP 1: Read Current Configuration (or Detect First Run)
First, attempt to read the current configuration file:
Read file: .claude/configuration/databases.env
Two possible outcomes:
A) File EXISTS → Set CONFIG_EXISTS = true
- Note down the current MySQL values (MYSQLHOST, MYSQLPORT, MYSQLDATABASE, MYSQLUSER, MYSQLPASSWORD, MYSQLINCLUDESOURCE, MYSQLCHARSET, OUTPUT_DIR)
- These will be shown in "Keep current" option descriptions
B) File DOES NOT EXIST → Set CONFIG_EXISTS = false
- Inform the user: "No existing configuration found. This appears to be a first-time setup — I'll collect all connection parameters from you."
- Ensure the configuration directory exists using Bash:
mkdir -p .claude/configuration - All parameters will need to be collected fresh (no "Keep current" option available)
STEP 2: Collect Connection Parameters (Batch 1 of 2)
Build the questions based on CONFIG_EXISTS:
If CONFIG_EXISTS = true: Include "Keep current" options with actual values in descriptions (e.g., "Keep current" with description "Keep: localhost").
If CONFIG_EXISTS = false: Replace "Keep current" options with additional useful defaults instead. Do NOT offer "Keep current" since there is nothing to keep.
Use the AskUserQuestion tool:
{
"questions": [
{
"question": "What is the MySQL database host?",
"header": "Host",
"options": [
{"label": "localhost", "description": "Database running on local machine"},
CONFIG_EXISTS ? {"label": "Keep current", "description": "Keep: "}
: {"label": "127.0.0.1", "description": "Loopback IP address"}
],
"multiSelect": false
},
{
"question": "What is the MySQL port?",
"header": "Port",
"options": [
{"label": "3306 (Default)", "description": "Standard MySQL port"},
CONFIG_EXISTS ? {"label": "Keep current", "description": "Keep: "}
: {"label": "3307", "description": "Alternative MySQL port"}
],
"multiSelect": false
},
{
"question": "What is the MySQL database name to analyze?",
"header": "Database",
"options": [
{"label": "mysql", "description": "MySQL system database"},
{"label": "information_schema", "description": "MySQL metadata database"},
CONFIG_EXISTS ? {"label": "Keep current", "description": "Keep: "}
: {"label": "test", "description": "Common test database"}
],
"multiSelect": false
},
{
"question": "What is the MySQL username?",
"header": "Username",
"options": [
{"label": "root", "description": "MySQL root administrator"},
CONFIG_EXISTS ? {"label": "Keep current", "description": "Keep: "}
: {"label": "admin", "description": "Common admin username"}
],
"multiSelect": false
}
]
}
Note: The pseudo-code CONFIG_EXISTS ? ... : ... means you must construct the actual JSON dynamically based on whether the config file existed. Replace `` placeholders with actual values read from the file.
Save all responses. For "Keep current" responses, use the existing values from the config file. For "Other" responses, use the custom text the user typed.
STEP 3: Collect Authentication & Options (Batch 2 of 2)
Use the AskUserQuestion tool, again adapting based on CONFIG_EXISTS:
{
"questions": [
{
"question": "What is the database password? (Select 'Other' to type your password)",
"header": "Password",
"options": [
CONFIG_EXISTS ? {"label": "Keep current", "description": "Use the password already in config"}
: {"label": "No password", "description": "Connect without a password (empty)"},
CONFIG_EXISTS ? {"label": "No password", "description": "Connect without a password (empty)"}
: {"label": "Type below", "description": "Select 'Other' to enter your password"}
],
"multiSelect": false
},
{
"question": "Include stored procedure and function source code in the report?",
"header": "Source Code",
"options": [
{"label": "No (Recommended)", "description": "Skip source code - faster analysis, smaller report"},
{"label": "Yes", "description": "Include full stored procedure/function source code"}
],
"multiSelect": false
},
{
"question": "What character set should be used for the connection?",
"header": "Charset",
"options": [
{"label": "utf8mb4 (Recommended)", "description": "Full Unicode support including emojis"},
{"label": "utf8", "description": "Basic Unicode (3-byte, no emoji support)"}
],
"multiSelect": false
},
{
"question": "Where should output files be saved? (Must be an absolute path)",
"header": "Output Dir",
"options": [
{"label": "Default (.claude/output)", "description": "Use the project's .claude/output directory"},
CONFIG_EXISTS ? {"label": "Keep current", "description": "Keep: "}
: {"label": "Custom path", "description": "Select 'Other' to type a custom absolute path"}
],
"multiSelect": false
}
]
}
Save all responses.
STEP 4: Map Responses to Configuration Values
Process the collected answers into configuration values using these rules:
| Parameter | Response Mapping | |-----------|-----------------| | MYSQLHOST | "localhost" -> localhost, "127.0.0.1" -> 127.0.0.1, "Keep current" -> keep existing, "Other" -> user's typed value | | MYSQLPORT | "3306 (Default)" -> 3306, "3307" -> 3307, "Keep current" -> keep existing, "Other" -> user's typed value | | MYSQLDATABASE | "mysql" -> mysql, "informationschema" -> information_schema, "test" -> test, "Keep current" -> keep existing, "Other" -> user's typed value | | MYSQLUSER | "root" -> root, "admin" -> admin, "Keep current" -> keep existing, "Other" -> user's typed value | | MYSQLPASSWORD | "Keep current" -> keep existing, "No password" -> empty string, "Type below" -> user must use "Other", "Other" -> user's typed value | | MYSQLINCLUDESOURCE | "No (Recommended)" -> false, "Yes" -> true | | MYSQLCHARSET | "utf8mb4 (Recommended)" -> utf8mb4, "utf8" -> utf8 | | OUTPUTDIR | "Default (.claude/output)" -> absolute path to project's .claude/output directory, "Keep current" -> keep existing, "Custom path" -> user must use "Other", "Other" -> user's typed value |
Also set: ACTIVE_DATABASE=mysql
STEP 5: Write or Update Configuration File
If CONFIG_EXISTS = false (first run):
Use the Write tool to create .claude/configuration/databases.env with the complete template populated with collected values:
# =============================================================================
# CONSOLIDATED DATABASE CONFIGURATION
# =============================================================================
# Single configuration file for all database migration skills
# =============================================================================
# ACTIVE DATABASE SELECTION
ACTIVE_DATABASE=mysql
# SHARED OUTPUT CONFIGURATION (ABSOLUTE PATH REQUIRED)
OUTPUT_DIR=
# ScalarDB target version
SCALARDB_TARGET_VERSION=3.17
# =============================================================================
# POSTGRESQL CONFIGURATION (defaults - not yet configured)
# =============================================================================
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DATABASE=your_database
POSTGRES_USER=your_username
POSTGRES_PASSWORD=your_password
POSTGRES_SCHEMA=public
POSTGRES_REPORT_FILENAME=postgresql_schema_report.md
POSTGRES_SCALARDB_NAMESPACE=
POSTGRES_INCLUDE_PLPGSQL_SOURCE=true
POSTGRES_PSQL_PATH=
POSTGRES_CONNECTION_TIMEOUT=30
POSTGRES_QUERY_TIMEOUT=300
# =============================================================================
# MYSQL CONFIGURATION
# =============================================================================
MYSQL_HOST=
MYSQL_PORT=
MYSQL_DATABASE=
MYSQL_USER=
MYSQL_PASSWORD=
MYSQL_REPORT_FILENAME=mysql_schema_report.md
MYSQL_SCALARDB_NAMESPACE=
MYSQL_INCLUDE_SOURCE=
MYSQL_CHARSET=
MYSQL_CONNECTION_TIMEOUT=30
# =============================================================================
# ORACLE CONFIGURATION (defaults - not yet configured)
# =============================================================================
ORACLE_HOST=localhost
ORACLE_PORT=1521
ORACLE_SERVICE=ORCL
ORACLE_USER=your_username
ORACLE_PASSWORD=your_password
ORACLE_SCHEMA=
ORACLE_REPORT_FILENAME=oracle_schema_report.md
ORACLE_SCALARDB_NAMESPACE=
ORACLE_INCLUDE_PLSQL_SOURCE=false
ORACLE_SQLPLUS_PATH=
ORACLE_HOME=
ORACLE_TNS_ADMIN=
# =============================================================================
# END OF CONFIGURATION
# =============================================================================
If CONFIG_EXISTS = true (updating existing):
Use the Edit tool to update .claude/configuration/databases.env with the collected values:
- Set
ACTIVE_DATABASE=mysql - Update
OUTPUT_DIRif changed - Update all
MYSQL_*parameters with the mapped values from Step 4 - Do NOT modify the PostgreSQL or Oracle sections
After writing/updating, display a confirmation summary to the user:
Configuration :
Host:
Port:
Database:
User:
Password: ******** (hidden)
Source:
Charset:
Output:
STEP 6: Ensure Output Directory Exists
Use Bash to create the output directory if it doesn't exist:
mkdir -p
STEP 7: Subagent 0 — Connection Test via API (Bash)
Spawn a Bash subagent using the Task tool to test the MySQL database connection via the external API.
- Read the prompt template at:
${PLUGIN_ROOT}/skills/common/subagents/mysql/0-test-connection.md - Substitute the runtime variables: replace `
,,,,, and` with the actual values from Steps 4-5 - Call the Task tool with
subagent_type: "Bash",description: "Test MySQL connection", and the substituted prompt
After the subagent completes:
- Extract
DURATION_SECONDSfrom the subagent's response → store asS0_DURATION - Extract
total_tokensfrom the `block in the Task result (if present) → store asS0_TOKENS`
Check the subagent result:
- If STATUS is FAILURE → Display the error to the user with resolution hints (check host/port/database name, verify credentials, ensure MySQL server is running and accepting connections). STOP HERE — do NOT proceed to Step 8, 9, or 10.
- If STATUS is SUCCESS → Note the database product and version, then proceed to Step 8.
STEP 8: Subagent 1 — Schema Extraction (Bash)
Spawn a Bash subagent using the Task tool to run the Python extractor script.
- Read the prompt template at:
${PLUGIN_ROOT}/skills/common/subagents/mysql/1-extract-schema.md - Substitute the runtime variables as documented in the template (replace `` based on MYSQLINCLUDESOURCE from Step 4)
- Call the Task tool with
subagent_type: "Bash",description: "Extract MySQL schema", and the substituted prompt
After the subagent completes:
- Extract
DURATION_SECONDSfrom the subagent's response → store asS1_DURATION - Extract
total_tokensfrom the `block in the Task result (if present) → store asS1_TOKENS`
Check the subagent result:
- If STATUS is FAILURE → Display the error to the user with resolution hints (check host/port, verify credentials, ensure MySQL server is running). STOP HERE — do NOT proceed to Step 9 or Step 10.
- If STATUS is SUCCESS → Note the OUTPUT_FILE path and proceed to Step 9.
STEP 9: Subagent 2 — Schema Report Generation (general-purpose)
Spawn a general-purpose subagent using the Task tool to generate the schema report from the extracted JSON.
- Read the prompt template at:
${PLUGIN_ROOT}/skills/common/subagents/mysql/2-generate-report.md - Substitute the runtime variables as documented in the template (replace all `` with the actual absolute output directory path from Step 4)
- Call the Task tool with
subagent_type: "general-purpose",description: "Generate MySQL schema report", and the substituted prompt
After the subagent completes:
- Extract
DURATION_SECONDSfrom the subagent's response → store asS2_DURATION - Extract
total_tokensfrom the `block in the Task result (if present) → store asS2_TOKENS`
Check the subagent result:
- If STATUS is FAILURE → Display the error to the user. Note that
raw_mysql_schema_data.jsonis still available for manual inspection. STOP HERE — do NOT proceed to Step 10. - If STATUS is SUCCESS → Note the summary and proceed to Step 10.
STEP 10: Subagents 3 & 4 — Migration Analysis + SP & Trigger Migration (Parallel)
Both subagents run simultaneously in a single message — send both Task tool calls together in one response. They share the same inputs (mysql_schema_report.md and raw_mysql_schema_data.json) and have no dependency on each other's output.
Preparation:
- Read the prompt template at:
${PLUGIN_ROOT}/skills/common/subagents/mysql/3-migration-analysis.md
- Substitute all `` with the actual absolute output directory path from Step 4
- Read the prompt template at:
${PLUGIN_ROOT}/skills/common/subagents/mysql/4-sp-trigger-migration.md
- Substitute all `` with the actual absolute output directory path from Step 4
Spawn both in one message:
- Task call A:
subagent_type: "general-purpose",description: "Generate MySQL migration docs", substituted prompt from3-migration-analysis.md - Task call B:
subagent_type: "general-purpose",description: "Generate SP & trigger migration code", substituted prompt from4-sp-trigger-migration.md
After both subagents complete:
- From Subagent 3 result: extract
DURATION_SECONDS→ store asS3_DURATION; extracttotal_tokensfrom `block → store asS3_TOKENS` - From Subagent 4 result: extract
DURATION_SECONDS→ store asS4_DURATION; extracttotal_tokensfrom `block → store asS4_TOKENS` - Compute parallel wall-clock:
S34_WALL = max(S3_DURATION, S4_DURATION)
Error cascading rules:
- Subagent 2 (Step 9) failed → do NOT spawn either Subagent 3 or 4 (both need mysqlschemareport.md)
- Subagent 3 fails while Subagent 4 succeeds → capture both results, report Subagent 3 error, proceed with Subagent 4 output
- Subagent 4 fails while Subagent 3 succeeds → capture both results, report Subagent 4 error, proceed with Subagent 3 output
- Both fail → display both errors; all prior outputs (schema report, raw JSON) remain on disk
Check results and proceed to Step 11.
STEP 11: Display Final Summary with Metrics
Display the combined result
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: wfukatsu
- Source: wfukatsu/nexus-architect
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.