MCP Fusion/Reference/Migration

Migration

Ask AI about Vinkius

Move an existing MCP server from the raw SDK to MCP Fusion incrementally: one tool domain at a time, from JSON.stringify responses to Presenters, redaction and rules.

MCP Fusion does not require a rewrite. The raw MCP SDK and MCP Fusion can coexist in one server, and most teams migrate one tool domain at a time, in the order of 15 to 30 minutes per domain. This page shows the shape of one such step.

Before: a raw SDK tool

typescript
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === 'get_invoice') {
    const invoice = await db.invoices.findUnique({
      where: { id: request.params.arguments.id },
    });
    return {
      content: [{ type: 'text', text: JSON.stringify(invoice) }],
    };
  }
});

The problems are structural. JSON.stringify(invoice) sends every column to the model, including the ones you forgot existed. Units live in tribal knowledge, so the model guesses. There is no place where redaction, validation or next actions could even happen.

After: the same tool in MVA

typescript
const InvoicePresenter = createPresenter('Invoice')
  .schema({
    id: t.string,
    customer: t.string,
    amount_cents: t.number.describe('CENTS, divide by 100'),
    status: t.enum('draft', 'paid', 'overdue'),
  })
  .redactPII(['customer.email', 'customer.ssn'])
  .rules(['amount_cents is in CENTS. Divide by 100.']);

export default f.query('billing.get_invoice')
  .describe('Retrieve an invoice by ID')
  .withString('id', 'Invoice ID')
  .returns(InvoicePresenter)
  .handle(async (input) => {
    return db.invoices.findUnique({ where: { id: input.id } });
  });

Same handler logic. What changed:

ConcernRaw SDKMCP Fusion
Output shapeJSON.stringify, every columnPresenter schema, declared fields only
PIIOn the wire.redactPII() before serialization
Units and meaningPrompt folklore.rules() as system lines
Next actionsNone.suggest() affordances
ValidationManualZod from the builder

The incremental path

  1. Install side by side. npm install @mcpfusion/core does not disturb the existing handlers.
  2. Pick one tool domain. Usually the one that touches the most sensitive data.
  3. Write the Presenter first. Declare the fields the task needs, redact the rest, write the rules the model keeps getting wrong.
  4. Move the handler. The query logic usually survives unchanged.
  5. Wire autoDiscover. New tools come from src/tools/, old handlers keep working during the transition.
  6. Lock and test. mcpfusion lock the new surface and add the egress assertions from Testing.

Coming from other frameworks

  • From plain HTTP APIs. @mcpfusion/openapi-gen generates Models, Views and Agents from an existing OpenAPI or Swagger spec, so wrapping an internal API starts mostly generated.
  • From a Prisma schema. @mcpfusion/prisma-gen generates tools and Presenters with field level security and tenant isolation from schema annotations.
  • From n8n. @mcpfusion/n8n turns n8n webhooks into tools with tag filtering.
  • From AWS internals. @mcpfusion/aws lifts Lambda functions and Step Functions into tools via resource tags.

Next steps