back to posts
#12 Part 3 2025-10-07 15 min

Blog Post 001: The MCP Factory Comes Alive - Generating Blockchain Servers on Demand

*Prerequisites*

Part 3 of the Journey: The Automation Breakthrough - From Manual to Meta Previous: From Manual to Meta: The Complete MCP Factory Story | Next: MCP Factory Validation

Blog Post 001: The MCP Factory Comes Alive - Generating Blockchain Servers on Demand

Historical Context (November 2025): Built September 2025, after 17 manual servers revealed automation patterns. The Factory emerged during the MCP packaging ecosystem’s maturation—we were building meta-tooling in parallel with the broader community standardization efforts.

Hook

“What if creating a new blockchain integration was as simple as calling a single MCP tool? Today, we proved it’s possible.”

The Vision

Technical Journey

Act 1: The Factory Awakens

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | tsx src/index.ts

Act 2: The Bash Compatibility Saga

9 Critical Fixes Required:

  1. Path Resolution - Scripts in nested directories
  2. Interactive Prompts - Blocking in stdio context
  3. Bash 4+ Syntax - ${VAR^} fails on macOS bash 3.2
  4. Orphaned EOF - Template generation artifacts
  5. Variable Expansion - Heredoc quoting conflicts
  6. Template Literals - TypeScript vs Bash ${...}

The Solution:

# Bash 3.2 compatible capitalization
CAPITAL_NAME=$(echo "$BLOCKCHAIN_NAME" | sed 's/\b(.)/\u\1/g')

# Preserve TypeScript while expanding bash
`Tool ${name} not found`  # Escaped for literal output

Act 3: Birth of Fantom Testnet MCP Server

Generated in 8 seconds:

File Structure:

fantom-testnet-mcp-server/
├── src/
│   ├── index.ts (300 lines - MCP protocol handler)
│   ├── client.ts (Fantom ethers client)
│   ├── config/network.ts (RPC endpoints)
│   └── tools/ (25 modular tool files)
├── tests/ (3 test suites)
└── package.json (ethers + MCP SDK)

The Breakthrough Moment

Before: 2-3 weeks per blockchain server After: 8 seconds for complete MBSS-compliant structure

Factory Input:

{
  "blockchain_name": "fantom",
  "network_type": "testnet",
  "sdk_package": "ethers"
}

Factory Output: Production-ready MCP server scaffold

What This Enables

Immediate Impact

Future Possibilities

Technical Deep Dive

The Bash Compatibility Challenge

Problem: macOS ships bash 3.2 (from 2007), but modern scripts use bash 4+

Incompatible Patterns:

${VAR^}           # Capitalize first letter (bash 4+)
${VAR^^}          # Uppercase all (bash 4+)
<< 'EOF' vs EOF  # Variable expansion in heredocs

Portable Solutions:

# First letter uppercase (bash 3.2+)
CAPITAL=$(echo "$VAR" | sed 's/\b(.)/\u\1/g')

# All uppercase (bash 3.2+)
UPPER=$(echo "$VAR" | tr '[:lower:]' '[:upper:]')

# Heredoc with selective expansion
cat << EOF
  ${BASH_VAR}           # Expands
  `TypeScript ${var}`  # Literal output
EOF

The Heredoc Escape Dance

Challenge: Generate TypeScript code with template literals using bash heredocs

Failed Attempt:

cat << EOF
logger.info(`Starting ${SERVER_NAME}`);  # Bash interprets ${SERVER_NAME}
EOF

Working Solution:

cat << EOF
logger.info(\`Starting \\${SERVER_NAME}\");  # Escaped $ for literal output
EOF

Validation Results

Build Test

cd servers/testnet/fantom-testnet-mcp-server
npm install  # ✅ All dependencies installed
npm run build # Expected errors (TODO implementations)

Expected vs Unexpected Errors

Expected (Intentional TODOs):

Unexpected (Template Issues):

Lessons Learned

1. Shell Compatibility Matters

Cross-platform bash scripts require testing on lowest common denominator (bash 3.2)

2. Template Generation is Tricky

Mixing bash variable expansion with TypeScript template literals requires careful escaping

3. MCP Self-Bootstrapping Works

Using MCP protocol to generate MCP servers validates the architecture

4. Automation Compounds Value

8 seconds × 17 blockchains = 136 seconds vs 34-51 weeks of manual work

What’s Next

Immediate Tasks

  1. Fix template generation issues (help, NFT tools)
  2. Run complete smoke test suite
  3. Generate next blockchain server (Optimism? zkSync?)

Factory Enhancements

Ecosystem Vision

The Meta Achievement

We built:

This is MCP eating its own dogfood and thriving.

Code Artifacts

Key Files Modified

  1. /scripts/mcp-factory/mcp-factory.sh - Main orchestrator (bash 3.2 compatible)
  2. /scripts/create-mcp-server-factory.sh - Server structure generator
  3. /scripts/mcp-factory/generate-index-file.sh - MCP protocol handler
  4. /scripts/mcp-factory/generate-tests.sh - Test suite generator

Generated Output

Conclusion

The MCP Factory isn’t just a code generator—it’s proof that:

  1. MCP scales - Protocol handles meta-operations
  2. Standards work - MBSS v3.0 enables automation
  3. AI accelerates - Claude Code + Factory = multiplicative productivity
  4. Infrastructure bootstraps - Systems that build systems

From weeks to seconds. From manual to automated. From one to many.

The blockchain MCP ecosystem just went exponential.


Metrics

Update: The Factory Fix That Changed Everything (January 2025)

The TS1005 Crisis

After successfully generating Fantom and expanding to 4 new blockchains (Polkadot, Aptos, Celo, Flow), we discovered a critical bug: the factory was generating syntactically invalid TypeScript code.

The Symptom:

error TS1005: ',' expected.

The Root Cause (generate-tool-definitions.js:255-258):

// BROKEN: Array.join() doesn't add trailing comma to last item
export const TOOL_SCHEMAS = {
  ${toolDefs.map(tool => {
    return `'${prefix}_${tool.name}': z.object({
      ${schemaFields.join(',\n  ')}
    })`;  // ← Missing trailing comma
  }).join(',\n\n')}  // ← Only adds commas BETWEEN items
};

When add-missing-tools.js appended 12 additional tools, it created:

'plk_get_balance': z.object({...})  // ← No comma!
'plk_send_transaction': z.object({...}),  // ← Invalid syntax

The Factory-First Epiphany

Critical Lesson: Never manually patch generated servers. Always fix the factory, delete the output, and regenerate.

Workflow Established:

# 1. Fix factory generator
vim scripts/mcp-factory/generate-tool-definitions.js

# 2. Delete faulty servers
rm -rf servers/testnet/factory-generated/*

# 3. Regenerate with corrected factory
echo "y" | scripts/mcp-factory/mcp-factory.sh polkadot testnet @polkadot/api
echo "y" | scripts/mcp-factory/mcp-factory.sh aptos testnet aptos
echo "y" | scripts/mcp-factory/mcp-factory.sh celo testnet @celo/contractkit
echo "y" | scripts/mcp-factory/mcp-factory.sh flow testnet @onflow/fcl

# 4. Add missing tools
cd servers/testnet/factory-generated && node add-missing-tools.js

# 5. Verify builds
npm run build  # No TS1005 errors!

The Fix

File: scripts/mcp-factory/generate-tool-definitions.js Lines Modified: 255-258

// FIXED: Trailing comma on every schema entry
export const TOOL_SCHEMAS = {
${toolDefs.map(tool => {
  return `  '${prefix}_${tool.name}': z.object({
    ${schemaFields.join(',\n  ')}
  }),`;  // ← Added trailing comma
}).join('\n\n')}  // ← Removed comma from separator
};

Why This Works:

Validation Results

All 4 servers rebuilt with 37/37 MBSS v3.0 tools:

# Polkadot: ✅ No TS1005 errors
# Aptos:    ✅ No TS1005 errors
# Celo:     ✅ No TS1005 errors
# Flow:     ✅ No TS1005 errors

Only TS6133 warnings (unused variables in stub implementations - acceptable per CLAUDE.md).

The Meta Meta-Achievement

We now have:

The factory doesn’t just generate servers—it generates increasingly better servers.

New Metrics

Future Blog Posts


Prerequisites

Next Steps

Deep Dives