@crossdelta/pf-mcp
Model Context Protocol (MCP) server adapter for Platform SDK.
Overview
This package provides a thin adapter layer between the Model Context Protocol SDK and the Platform SDK, exposing plugin commands as MCP tools.
Architecture:
- Depends on Platform SDK facade (
@crossdelta/platform-sdk/facade) - Pins MCP SDK to exact version for stability
- Zero business logic - pure adapter pattern
- Plugin-agnostic: Works with any Platform SDK plugin
Installation
bun add @crossdelta/pf-mcp
Usage
Auto-Discovery (Recommended)
The easiest way to start the server - automatically discovers workspace configuration from package.json:
import { createMcpServerFromWorkspace } from '@crossdelta/pf-mcp'
await createMcpServerFromWorkspace({
name: 'platform-mcp-server',
version: '0.1.0',
plugins: ['@crossdelta/cloudevents']
})
This will:
- Auto-discover workspace root (walks up from cwd to find package.json with
pfconfig) - Read contracts package from
pf.contractsfield - Discover available services from filesystem
Manual Configuration
For more control, you can provide the workspace configuration explicitly:
import { createMcpServer } from '@crossdelta/pf-mcp'
await createMcpServer({
name: 'platform-mcp-server',
version: '0.1.0',
workspace: {
workspaceRoot: process.cwd(),
contracts: {
path: 'packages/contracts/src',
packageName: '@my-org/contracts'
},
availableServices: ['orders', 'notifications']
},
plugins: ['@crossdelta/cloudevents']
})
MCP SDK Version Strategy
Current Version: ^1.25.1 (v1.x - Latest Stable)
This package uses caret range for the MCP SDK to receive patch and minor updates automatically.
⚠️ SDK Status:
- v1.x (
@modelcontextprotocol/sdk): Current stable, published on npm, usesServerclass - v2.x (
@modelcontextprotocol/server): In development (main branch), not yet published, will useMcpServerclass
The Server class shows a deprecation warning pointing to McpServer, but this is a forward-looking notice for the unreleased v2 API. Our current usage is correct for v1.25.1.
Why Caret Range?
- Mature SDK: MCP SDK is at v1.x with stable APIs
- Automatic bugfixes: Security patches and fixes without manual intervention
- Semver compliance: SDK follows semantic versioning
- Facade isolation: Platform SDK facade provides stability layer
Version Policy
Updates allowed:
- ✅ Patch updates (1.25.1 → 1.25.2) - automatic
- ✅ Minor updates (1.25.x → 1.26.0) - automatic
- ❌ Major updates (1.x → 2.0) - manual upgrade required
When to upgrade manually:
- New MCP SDK major version with breaking changes
- New protocol features we want to use
- Critical security vulnerabilities
Migration to SDK v2.x (future):
When SDK v2 is published to npm (expected Q1 2026):
- Install:
bun add @modelcontextprotocol/server(replaces@modelcontextprotocol/sdk) - Update imports:
Server→McpServer, package path:@modelcontextprotocol/sdk/server→@modelcontextprotocol/server - Review v2 breaking changes in transport/handler APIs
- Test with v2 examples: server.md
- Update this README
How to upgrade:
- Review MCP SDK changelog for breaking changes
- Test in dev environment first
- Update adapter code if handler APIs changed
- Run integration tests
- Update version in
package.json - Document changes in this README
Version History
| MCP SDK | Date | Changes | Notes |
|---|---|---|---|
| ^1.25.1 | 2025-12-28 | Initial version | v1.x stable release, v2 in development |
Available Tools
The MCP server exposes these tools to AI assistants:
| Tool | Description |
|---|---|
scan_workspace | Scan workspace for services, contracts, and configuration |
generate_service | Generate a plan for a new microservice (dry-run by default) |
plan_review | Validate a generation plan before applying |
apply_changes | Apply changes from a generation plan |
MCP Flow (Architecture)
Key Principle: MCP = Planner (structure), AI = Code Generator (content)
1. AI delivers Intent + Inputs → mcp_pf_generate_service(prompt: "...")
2. pf generates Plan + Preview ← { files: [], changes: [], planHash }
3. AI generates code for files → AI fills content based on intent + inputs
4. Optional: plan_review → mcp_pf_plan_review(changes: [...])
5. User OK Gate → User confirms
6. Apply with expectedPlanHash → mcp_pf_apply_changes(changes: [...], expectedPlanHash: "...")
generate_service Response Structure
{
ok: true,
operation: 'generate_service',
summary: 'Planned notifications: 10 scaffold files + 3 files for AI to generate',
// Scaffold effects (ready to apply - have content)
changes: [
{ kind: 'file:write', path: 'services/notifications/package.json', content: '...' },
{ kind: 'file:write', path: 'services/notifications/src/index.ts', content: '...' },
// ...
],
// Files for AI to generate (NO content - AI fills based on intent + inputs)
files: [
{
path: 'services/notifications/src/events/order-created.handler.ts',
intent: 'Handle order.created event',
inputs: { eventType: 'order.created', contractName: 'OrdersCreatedContract' }
},
{
path: 'services/notifications/src/adapters/push.adapter.ts',
intent: 'Push notification adapter using pusher-beams',
inputs: { provider: 'pusher-beams', envVars: ['PUSHER_BEAMS_INSTANCE_ID', 'PUSHER_BEAMS_SECRET_KEY'] }
},
],
// Dependencies to add
dependencies: [
{ name: '@pusher/push-notifications-server', version: '^1.0.0' }
],
// Environment variables needed
envVars: [
{ key: 'PUSHER_BEAMS_INSTANCE_ID', description: 'Pusher Beams instance ID', required: true }
],
// Integrity hash
planHash: 'abc123...',
}
AI Workflow
- Call generate_service with prompt
- Read files array (path + intent + inputs)
- Generate code for each file based on intent + inputs
- Merge into changes with AI-generated content
- Call apply_changes with merged changes + expectedPlanHash
Effect Types
| Effect Kind | Description |
|---|---|
file:write | Write file to filesystem |
env:add | Add environment variable to .env.local |
infra:add | Create infrastructure config |
deps:add | Add dependency to package.json |
Tool Examples
scan_workspace
{
"name": "scan_workspace",
"arguments": {}
}
generate_service (dry-run)
{
"name": "generate_service",
"arguments": {
"template": "hono-bun",
"name": "order-processor",
"events": ["order.created", "order.updated"]
}
}
generate_service (apply)
{
"name": "generate_service",
"arguments": {
"template": "hono-bun",
"name": "order-processor",
"events": ["order.created"],
"dryRun": false
}
}
Testing
Manual Testing (CLI)
Test the MCP server directly via stdin/stdout:
# Build the package first
cd packages/pf-mcp && bun run build
# From workspace root - list available tools
cd /path/to/workspace
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | bun run packages/pf-mcp/bin/server.ts
# Scan workspace
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"scan_workspace","arguments":{}}}' | bun run packages/pf-mcp/bin/server.ts
# Generate service (dry-run)
echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"generate_service","arguments":{"template":"hono-bun","name":"test-service","events":["order.created"]}}}' | bun run packages/pf-mcp/bin/server.ts
VS Code Integration (Copilot Agent Mode)
Add to your VS Code settings.json:
{
"github.copilot.chat.mcpServers": {
"pf": {
"command": "bun",
"args": ["run", "${workspaceFolder}/packages/pf-mcp/bin/server.ts"],
"env": {}
}
}
}
Or for the built version (npm package):
{
"github.copilot.chat.mcpServers": {
"pf": {
"command": "node",
"args": ["${workspaceFolder}/node_modules/@crossdelta/pf-mcp/dist/cli.js", "--stdio"],
"env": {}
}
}
}
After configuration, restart VS Code. The tools will appear with mcp_pf_ prefix in Copilot Agent Mode.
Unit Tests
cd packages/pf-mcp
bun test
Development
# Build
bun run build
# Test
bun test
# Watch mode
bun run dev
Architecture
┌─────────────────┐
│ MCP Client │ (Claude Desktop, Zed, etc.)
└────────┬────────┘
│ stdio
┌────────▼────────┐
│ pf-mcp Server │ (this package - thin adapter)
└────────┬────────┘
│ facade API
┌────────▼────────┐
│ Platform SDK │ (plugin system, execution engine)
│ Facade │
└────────┬────────┘
│
┌────────▼────────┐
│ Plugins │ (@crossdelta/cloudevents, etc.)
└─────────────────┘
Design Principles
- Thin adapter: No business logic, pure protocol translation
- Facade dependency: Only imports from
@crossdelta/platform-sdk/facade - Plugin agnostic: Works with any plugin conforming to
PfPlugininterface - Exact SDK pin: MCP SDK version explicitly controlled for stability
Facade API Surface
This package depends on these stable facade exports:
import {
loadPlugins, // Load plugins from module names
createContext, // Create plugin context
collectToolSpecs, // Transform commands → tool specs
applyEffects, // Apply command effects
// Types
type PfPluginContext,
type PfWorkspaceContext,
type LoadedPlugin,
type ToolSpec,
} from '@crossdelta/platform-sdk/facade'
The facade provides version stability - Platform SDK can refactor internals without breaking this adapter.
Roadmap
Phase 1: Core Tools (Current)
- Server skeleton with stdio transport
tools/listhandlertools/callhandler with command execution- Effect application via facade
- Full integration tests with mock plugins
- Error handling and validation
- Logging and debugging support
Phase 2: Enhanced Capabilities
resources/list- workspace contracts as resourcesresources/read- contract content retrievalprompts/list- template-based promptsprompts/get- prompt resolution- Plan/apply separation for safety
Phase 3: Advanced Features
- Progress reporting via notifications
- Streaming responses for long operations
- Workspace change notifications
- Multi-workspace support
Contributing
This package is part of the Platform SDK monorepo. See the main repository for contribution guidelines.
License
MIT © crossdelta