PCL integrates with the Model Context Protocol (MCP) to expose personas, teams, and workflows as tools and resources for IDE clients like Claude Code, Cursor, and VS Code.
- Quick Start
- Server Setup
- IDE Integration
- Available Tools
- Available Resources
- Examples
- Troubleshooting
npm install @pcl/sdkimport { PclMcpServer, StdioTransport, createRuntime } from '@pcl/sdk';
// Create PCL runtime
const runtime = createRuntime();
// Create MCP server
const server = new PclMcpServer({
name: 'pcl-server',
version: '1.0.0',
description: 'PCL MCP Server',
runtime,
});
// Connect with stdio transport (for CLI)
const transport = new StdioTransport();
server.connect(transport);
console.log('PCL MCP Server running...');node mcp-server.jsUse the generic PclMcpServer for full control:
import { PclMcpServer } from '@pcl/sdk';
const server = new PclMcpServer({
name: 'my-pcl-server',
version: '1.0.0',
description: 'Custom PCL MCP Server',
});
// Register custom tools
server.registerTool(
{
name: 'custom/greet',
description: 'Greet a user',
inputSchema: {
type: 'object',
properties: {
name: { type: 'string', description: 'User name' },
},
required: ['name'],
},
},
async (params) => {
return {
content: [
{
type: 'text',
text: `Hello, ${params.arguments.name}!`,
},
],
};
}
);Use PclServer for built-in persona/team/workflow tools:
import { PclServer, createRuntime } from '@pcl/sdk';
const runtime = createRuntime();
// Load PCL personas
runtime.load(myPclProgram);
const server = new PclServer({
name: 'pcl-server',
version: '1.0.0',
runtime,
});import { StdioTransport } from '@pcl/sdk';
const transport = new StdioTransport();
server.connect(transport);import { HttpSseTransport } from '@pcl/sdk';
const transport = new HttpSseTransport({
port: 3000,
path: '/mcp',
});
server.connect(transport);
console.log('MCP server available at http://localhost:3000/mcp');Create pcl-mcp-server.js:
import { PclServer, StdioTransport, createRuntime, compile } from '@pcl/sdk';
import { readFileSync } from 'fs';
// Load PCL program
const source = readFileSync('./my-personas.pcl', 'utf-8');
const compiled = compile(source);
if (!compiled.ok) {
console.error('PCL compilation failed:', compiled.value);
process.exit(1);
}
// Create runtime
const runtime = createRuntime();
runtime.load(compiled.value.program);
// Create server
const server = new PclServer({
name: 'pcl-server',
version: '1.0.0',
runtime,
});
// Connect stdio
const transport = new StdioTransport();
server.connect(transport);Add to .claude/mcp.json:
{
"mcpServers": {
"pcl": {
"command": "node",
"args": ["./pcl-mcp-server.js"],
"description": "PCL Persona Control Language"
}
}
}You: Can you list available PCL personas?
Claude Code will call the persona/list tool automatically.
Add to cursor-mcp.json:
{
"servers": {
"pcl": {
"command": "node",
"args": ["./pcl-mcp-server.js"]
}
}
}code --install-extension anthropic.mcpAdd to .vscode/settings.json:
{
"mcp.servers": {
"pcl": {
"command": "node",
"args": ["./pcl-mcp-server.js"]
}
}
}Execute a persona with input.
Input Schema:
{
"persona": "string (persona ID)",
"input": "string (input message)"
}Example:
{
"persona": "Analyst",
"input": "Analyze the Q4 sales data"
}List all available personas.
Input Schema: None
Returns:
{
"personas": [
{
"id": "Analyst",
"name": "Analyst",
"description": "Data analysis expert"
}
]
}Get persona definition.
Input Schema:
{
"persona": "string (persona ID)"
}Execute a team workflow.
Input Schema:
{
"team": "string (team ID)",
"input": "string (input message)"
}List all teams.
Get team definition.
Execute a workflow.
Input Schema:
{
"workflow": "string (workflow ID)",
"input": "any (workflow input)"
}List all workflows.
Get workflow definition.
URI Format: pcl://persona/{id}
Example:
pcl://persona/Analyst
Returns:
{
"uri": "pcl://persona/Analyst",
"mimeType": "application/json",
"json": {
"id": "Analyst",
"name": "Analyst",
"intent": "Perform data analysis...",
"skills": ["data-analysis", "statistics"],
"tags": ["analysis", "data"]
}
}URI Format: pcl://team/{id}
URI Format: pcl://workflow/{id}
URI Format: pcl://output/{execution_id}
Returns: The output of a specific execution.
// my-personas.pcl
persona Analyst {
intent: "Analyze data and provide insights"
skills: [
"Statistical analysis",
"Data interpretation",
"Trend identification"
]
constraints: [
"Provide data-driven conclusions",
"Show your work"
]
tags: [analysis, data, statistics]
}
MCP Server:
import { PclServer, StdioTransport, createRuntime, compile } from '@pcl/sdk';
import { readFileSync } from 'fs';
const source = readFileSync('./my-personas.pcl', 'utf-8');
const compiled = compile(source);
const runtime = createRuntime();
runtime.load(compiled.value.program);
const server = new PclServer({
name: 'pcl-server',
version: '1.0.0',
runtime,
});
const transport = new StdioTransport();
server.connect(transport);Usage in Claude Code:
You: Execute the Analyst persona to analyze this data: [1, 2, 3, 4, 5]
Claude Code calls:
- Tool: persona/execute
- Arguments: { persona: "Analyst", input: "Analyze this data: [1, 2, 3, 4, 5]" }
persona Researcher {
intent: "Research and gather information"
skills: ["research", "information-gathering"]
}
persona Critic {
intent: "Critique and find flaws"
skills: ["critical-thinking", "analysis"]
}
team Analysis {
members: [Researcher, Critic]
merge: debate
}
Usage:
You: Run the Analysis team on "Is AI beneficial?"
Claude Code calls:
- Tool: team/execute
- Arguments: { team: "Analysis", input: "Is AI beneficial?" }
import { PclMcpServer, StdioTransport } from '@pcl/sdk';
const server = new PclMcpServer({
name: 'custom-server',
version: '1.0.0',
});
// Register custom PCL tool
server.registerTool(
{
name: 'pcl/analyze',
description: 'Analyze PCL source code',
inputSchema: {
type: 'object',
properties: {
source: { type: 'string', description: 'PCL source code' },
},
required: ['source'],
},
},
async (params) => {
const { compile } = await import('@pcl/sdk');
const result = compile(params.arguments.source);
if (!result.ok) {
return {
content: [
{
type: 'text',
text: `Compilation failed: ${result.value.map((e) => e.message).join(', ')}`,
},
],
isError: true,
};
}
return {
content: [
{
type: 'text',
text: `✓ Valid PCL program with ${result.value.program.statements.length} statements`,
},
],
};
}
);
const transport = new StdioTransport();
server.connect(transport);Problem: MCP server fails to start
Solution:
- Check Node.js version (16+ required)
- Verify PCL installation:
npm list @pcl/sdk - Check for compilation errors in your PCL files
- Review server logs for error messages
Problem: IDE can't find PCL tools
Solution:
- Verify server is running: check process list
- Check MCP configuration file (
.claude/mcp.json, etc.) - Restart IDE after configuration changes
- Check server transport (stdio vs HTTP)
Problem: persona/execute tool returns errors
Solution:
- Verify persona exists: use
persona/listtool - Check persona is loaded in runtime
- Verify AI provider is configured
- Check runtime logs for errors
Problem: IDE can't connect to MCP server
Solution:
- stdio transport: Check command path and arguments
- HTTP transport: Verify port is not blocked
- Check firewall settings
- Review IDE MCP extension logs
Problem: MCP operations are slow
Solution:
- Use stdio transport for local tools (faster than HTTP)
- Limit persona complexity
- Enable caching in runtime
- Profile server performance
import { PclServer, createRuntime, AnthropicProvider } from '@pcl/sdk';
const runtime = createRuntime();
// Configure AI provider
const provider = new AnthropicProvider({
apiKey: process.env.ANTHROPIC_API_KEY,
model: 'claude-sonnet-4-20250514',
});
runtime.setDefaultProvider(provider);
const server = new PclServer({
name: 'pcl-server',
version: '1.0.0',
runtime,
});import { PclServer, StdioTransport, HttpSseTransport } from '@pcl/sdk';
const server = new PclServer({
/* config */
});
// Stdio for CLI
const stdioTransport = new StdioTransport();
server.connect(stdioTransport);
// HTTP for web
const httpTransport = new HttpSseTransport({ port: 3000 });
server.connect(httpTransport);runtime.on((event) => {
console.log('Runtime event:', event.type);
if (event.type === 'persona:response') {
console.log(
`Persona ${event.persona.name} responded:`,
event.response.content
);
}
});- PCL Language Guide - Learn PCL syntax
- Persona Building Guide - Create custom personas
- Skills Integration - Add skills to personas
- API Reference - Complete API documentation
Need Help?
- GitHub Issues: https://github.com/personalayer/pcl/issues
- Documentation: https://pcl-lang.org/docs
- Examples: https://github.com/personalayer/pcl/tree/main/examples