Meteor Wormhole — Connect Your Meteor Methods to AI Agents (MCP + REST + Swagger)

Hey everyone! :wave:

I’ve been working on a package called Meteor Wormhole and I’m excited to share it with the community. In short, it turns your existing Meteor.methods into tools that AI agents can discover and call — no rewriting required.

What Is It?

Meteor Wormhole is a server-only Meteor 3.4+ package that bridges your Meteor methods to the outside world through:

  • MCP (Model Context Protocol) — The open standard for connecting AI assistants to tools and data. Your methods become MCP tools that Claude, GPT, Cursor, VS Code Copilot, and any MCP-compatible client can discover and invoke.
  • REST API — Every exposed method also gets a POST /api/<method> endpoint.
  • OpenAPI 3.1 spec — Auto-generated from your method schemas.
  • Swagger UI — Built-in interactive API docs at /api/docs.

How It Works

Two lines to get started:

import { Wormhole } from 'meteor/wreiske:meteor-wormhole';

Wormhole.init(); // That's it — all your methods are now MCP tools

By default it runs in “all-in” mode, which automatically exposes every Meteor.methods() call (minus DDP internals, private _-prefixed methods, and Accounts methods). You can also run in “opt-in” mode for explicit control:

Wormhole.init({ mode: 'opt-in' });

Wormhole.expose('todos.add', {
  description: 'Add a new todo item',
  inputSchema: {
    type: 'object',
    properties: {
      title: { type: 'string', description: 'The todo title' },
      priority: { type: 'string', enum: ['low', 'medium', 'high'] }
    },
    required: ['title']
  }
});

Add richer schemas and descriptions, and AI agents get better context about what your tools do and how to call them.

Features at a Glance

  • Zero-config MCP server — Streamable HTTP transport at /mcp, session management, JSON-RPC 2.0
  • Optional REST bridge — Enable with rest: { enabled: true } for traditional HTTP clients
  • Auto-generated OpenAPI 3.1 spec with Swagger UI
  • Optional API key auth — Covers both MCP and REST endpoints
  • Smart exclusions — Automatically skips DDP internals, _private methods, and Accounts methods; add your own patterns
  • Input validation — JSON Schema → Zod conversion for parameter validation
  • Error propagationMeteor.Error details are properly passed through to clients
  • Enrich existing methods — Add descriptions and schemas to auto-registered methods with Wormhole.expose()

Configuration Options

Wormhole.init({
  mode: 'all',             // 'all' or 'opt-in'
  path: '/mcp',            // MCP endpoint path
  name: 'my-app',          // MCP server name
  apiKey: 'secret',        // Optional bearer token auth
  exclude: [/^admin\./],   // Additional exclusion patterns
  rest: {
    enabled: true,         // Enable REST API
    path: '/api',          // REST base path
    docs: true             // Swagger UI at /api/docs
  }
});

Live Demo & Chat App

I’ve deployed a live test app you can poke around with. It includes a dozen example methods (todos, math, string transforms, error handling, etc.) with Swagger UI so you can try the REST API directly in your browser.

There’s also a chat app included in the repo that demonstrates the other side of the coin — a Meteor app acting as an MCP client, connecting to external MCP servers, discovering their tools, and feeding them into an AI chat loop with multi-provider support (OpenAI, Anthropic, Google Gemini, Groq, Mistral, and more).

Point Your MCP Client at It

If you use Claude Desktop, Cursor, VS Code Copilot, or any other MCP-compatible client, you can connect to a Wormhole-enabled app and your AI assistant will immediately see all the exposed methods as callable tools. Just point it at your app’s /mcp endpoint.

Links

Get Involved

Contributions are very welcome! Whether it’s bug fixes, new features, documentation improvements, or just feedback — open an issue or PR on GitHub.

And if you build something with Meteor Wormhole, I’d love to hear about it. Drop a comment here and let me know what you’re using it for! :rocket:

12 Likes

Great work, @wreiske!

We’ll definitely share this with the community.

2 Likes

Hmh, why should I do that? After an extensive penhole research I’m rather making my Meteor methods more tight than opening them up to anyone with an AI tool to make it even easier to find loophole into my app.

What is the benefit that is greater than the added security flaw and attack front?

Create a PR to include it in the docs:

I will have to look how I can wire in my existing API keys, so that I can authenticate against multiple API keys. I think that is something that needs a bit more expansion. My use case is that users can create their own API keys and have limited access to the API.

I think the concern is fair, but the premise is slightly flipped.

Wormhole doesn’t introduce a new attack surface — it exposes the same server methods you already expose through DDP, just through a structured interface (MCP and optionally REST). If a Meteor method is insecure, it’s already insecure today. Wormhole just makes the interface more transparent.

In fact, I bet a lot of teams will find it pushes them toward better security practices, because:

  • You can run it in opt-in mode and only expose explicitly approved methods, like maybe a knowledge-base search or a open support ticket.
  • You can add schemas and validation so inputs are strictly defined. Not everyone does this with Meteor, and you’d be surprised how much code I’ve seen that doesn’t use check/match.
  • You can add API key authentication and make sure only authorized users can hit your MCP.
  • You can exclude patterns like admin.* or anything internal.

So the philosophy is basically: secure your methods properly once, and then they become reusable tools.

Where it becomes interesting is what that unlocks.

1. AI assistants operating your app

Instead of writing custom integrations, your app becomes a set of tools an AI assistant can use.

Example:

User: "Create a new support ticket for Acme Corp and assign it to Sarah."

AI calls:
tickets.create({ companyId, subject, description }) - > Meteor method "tickets.create"
tickets.assign({ ticketId, userId }) - > Meteor method "tickets.assign"

No separate AI API layer required — the assistant just uses your existing Meteor methods.


2. Internal automation

You can let automation agents interact with your backend directly.

Examples:

  • Nightly data cleanup
  • Auto-tagging uploaded documents
  • AI summarizing activity feeds
  • Intelligent retry of failed jobs

Instead of writing scripts that hit custom endpoints, the automation just calls methods as tools.


3. Instant REST API without writing controllers

A lot of Meteor apps eventually end up duplicating their logic:

Meteor method
↓
REST controller
↓
GraphQL resolver

Wormhole lets the method itself be the API, with generated OpenAPI docs and Swagger UI.

That means:

  • external services
  • microservices
  • Zapier / Make / n8n
  • backend jobs
  • and agents with skills files

can call your logic without rewriting it.


4. AI developer tooling

One of the more fun uses is developer productivity.

If your methods are exposed via MCP, tools like Cursor, Copilot, or Claude can discover them automatically and interact with your app.

Example:

"Show me the latest orders in production."

The assistant can call:

orders.listRecent()

This becomes a live interface to your backend during development or debugging.


5. Rapid prototyping for integrations

Want to integrate with Slack, Notion, or an internal tool?

Instead of building a full API layer first, you can expose a few methods and start experimenting immediately.

Later you can tighten things down or move to opt-in mode.


Security-wise

Personally I recommend:

Wormhole.init({
  mode: 'opt-in',
  apiKey: process.env.API_KEY,
  exclude: [/^admin\./]
});

That way nothing is exposed unless you deliberately publish it.


TL;DR

The real benefit isn’t “opening your app to AI.”
It’s turning your existing server logic into a reusable tool layer for:

  • AI agents
  • automation
  • integrations
  • developer tooling
  • external services

without rewriting your backend.

1 Like

Thanks for the explanation; you’ve certainly put a lot of thought into this.

A couple of comments from my side:

  1. Everyone should always secure their DDP as much as possible (rate limiting, encryption, and avoiding method abuse).
  2. I’m still trying to fully grasp the use case for creating an MCP server for your app. Since your users can already use the app directly, why would they need an AI agent to do it for them? For something like creating a CS ticket, that can usually be handled within the app’s own logic.

Generally, an AI agent needs access to another server or app via an MCP server (or even a CLI, which is much more token-efficient) when that app belongs to a different ecosystem (like TrendRadar or MindsDb) or provides a necessary third-party service (like Context7).

Which specific AI agent or workflow is the target group for your MCP server?

In the world of agentic coding, integrating an app with Slack or a payment gateway (Stripe, PayPal, etc.) is often a relatively quick task for an AI agent. I handle my own automations using BullMQ, and it works perfectly for integrations with tools like PayPal, Buy Me a Coffee, and Chargebee.

Ultimately, I prefer to stay in full control of my DDP connections, or the absence of them for my airtight on-prem servers, to manage exactly what my methods do. I might place extra emphasis on this because my own SaaS handles sensitive DNA data. Ensuring that user data is 100% safe is my top priority; a single breach can be devastating for a company in that space.

Anyway, this is just my personal PoV based on my specific situation. I’m sure others see it differently, and you clearly have a different perspective. Please don’t take this as a personal attack or me trying to talk down your idea, it’s just not the right fit for my current stack.

What I really appreciate about your post is the “food for thought.” Exploring how AI agents can be helpful and pushing these boundaries is exactly what makes these discussions valuable. Thank you for taking the time to explain your thoughts so clearly.

Keep us posted!