DEV Community

Kin Lane
Kin Lane

Posted on

Deploy a Real MCP Server in Two Minutes — Naftiko Shipyard on Cloudflare Containers

The Naftiko Framework's Shipyard tutorial walks through eleven capability YAMLs — mock MCP at one end, a fully wired domain-driven aggregate at the other. Step 1 is what you run to prove the engine reads YAML. Step 11 is what you run to feel what the framework actually produces.

This post is about deploying step 11 with a single click.

Run in Cloudflare

What gets deployed

Three protocol adapters from one capability YAML:

Adapter Path Tools / resources
MCP POST /mcp list-ships, get-ship, list-legacy-vessels, create-voyage, get-ship-with-crew, get-voyage-manifest
REST /api/... Same domain as REST resources
SKILL /skill Skill groups for structured agent discovery

Backed by two consumed APIs:

  • Maritime Registry at mocks.naftiko.net/rest/naftiko-shipyard-maritime-registry-api/1.0.0-alpha2 — bearer auth
  • Legacy Dockyard at mocks.naftiko.net/rest/naftiko-shipyard-legacy-dockyard-api/1.0.0-alpha2 — API key auth

Both are public Naftiko mocks. The deploy ships dummy tokens that work against them — no upstream credentials needed.

The MCP server itself requires a bearer token (dummy sk-mcp-YYYYYYYYYYYY ships in the deploy).

The Cloudflare shape

The Naftiko Framework engine ships as ghcr.io/naftiko/framework:latest. Cloudflare Containers runs Docker images behind a Worker, brokered by a Durable Object. Five files in the deploy repo do the work — the capability YAML, three shared imports, a Dockerfile, a wrangler config, and a small Worker that proxies traffic to the right port (/mcp → 3001, /skill → 3003, everything else → REST 3002).

The same shape powers manage-companies in production today. The Shipyard end-to-end deploy is the production pattern, sized to the canonical tutorial example.

Click → live URL

Click the button. Cloudflare authenticates you, forks the repo, provisions a Worker plus a Container, builds the Dockerfile, and assigns you a *.workers.dev hostname. Two to three minutes from click to running.

When it finishes you have:

  • https://<your-worker>.workers.dev/ — landing page
  • https://<your-worker>.workers.dev/mcp — MCP server
  • https://<your-worker>.workers.dev/api/... — REST adapter
  • https://<your-worker>.workers.dev/skill — Skill server

That MCP URL is what you give to your AI tools.

Wiring the MCP endpoint into your AI tools

Substitute your worker URL where you see <your-worker> below. Bearer token defaults to sk-mcp-YYYYYYYYYYYY unless you've changed it.

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (Mac) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "naftiko-shipyard": {
      "type": "streamable-http",
      "url": "https://<your-worker>.workers.dev/mcp",
      "headers": {
        "Authorization": "Bearer sk-mcp-YYYYYYYYYYYY"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart Claude Desktop. Tools appear in the picker.

Claude Code

claude mcp add --transport http naftiko-shipyard https://<your-worker>.workers.dev/mcp \
  --header "Authorization: Bearer sk-mcp-YYYYYYYYYYYY"
Enter fullscreen mode Exit fullscreen mode

Confirm with claude mcp list.

ChatGPT

ChatGPT supports remote MCP servers through Custom Connectors (Pro and Enterprise plans). Settings → Connectors → Custom → Add custom connector. Server URL: https://<your-worker>.workers.dev/mcp. Authentication: Custom header — name Authorization, value Bearer sk-mcp-YYYYYYYYYYYY.

Gemini CLI

Edit ~/.gemini/settings.json:

{
  "mcpServers": {
    "naftiko-shipyard": {
      "httpUrl": "https://<your-worker>.workers.dev/mcp",
      "headers": {
        "Authorization": "Bearer sk-mcp-YYYYYYYYYYYY"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Restart gemini. Confirm with /mcp list.

Why this matters past the demo

The Shipyard end-to-end is a sample. The interesting thing is that it isn't shaped any differently from a real Naftiko capability. Same one-click pattern — capability YAML in a folder, Dockerfile pulling the framework image, Worker proxying ports, Durable Object brokering a container — runs manage-companies in production. Replace the YAML in your fork, redeploy, and you have a different MCP server at the same URL.

That is the actual unlock. A public MCP endpoint that you control, callable from Claude, Claude Code, ChatGPT, and Gemini.

Top comments (0)