How to Add a Custom Agent
Build a Docker container that speaks the filepath Agent Protocol (FAP) and integrate it into the platform.
What you'll build
A Docker container that:
- • Receives tasks via environment variables
- • Reads user messages from stdin (NDJSON)
- • Emits events to stdout (NDJSON)
- • Runs in an isolated Linux environment
Prerequisites
- • Docker installed locally
- • filepath account with API key configured
- • Basic understanding of NDJSON (one JSON object per line)
Step 1: Create the Dockerfile
Create a new directory for your agent:
mkdir my-custom-agent cd my-custom-agent
Create Dockerfile:
FROM node:20-alpine WORKDIR /workspace # Copy your agent code COPY package.json . COPY index.js . RUN npm install # The container starts here CMD ["node", "index.js"]
Step 2: Write the Agent Code
Create index.js:
const readline = require('readline');
// Read environment variables from filepath
const task = process.env.FILEPATH_TASK || '';
const apiKey = process.env.FILEPATH_API_KEY || '';
const model = process.env.FILEPATH_MODEL || '';
const agentId = process.env.FILEPATH_AGENT_ID || '';
// Startup message
console.log(JSON.stringify({
type: 'status',
state: 'running'
}));
console.log(JSON.stringify({
type: 'text',
content: `Starting task: ${task}`
}));
// Read user messages from stdin
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
rl.on('line', async (line) => {
try {
const msg = JSON.parse(line);
if (msg.type === 'message') {
// Echo back for demo purposes
console.log(JSON.stringify({
type: 'text',
content: `Received: ${msg.content}`
}));
// Simulate some work
console.log(JSON.stringify({
type: 'command',
command: 'echo "Processing..."'
}));
// Mark as done
console.log(JSON.stringify({
type: 'done'
}));
}
} catch (e) {
console.log(JSON.stringify({
type: 'text',
content: 'Error parsing input'
}));
}
});
// Handle graceful shutdown
process.on('SIGTERM', () => {
console.log(JSON.stringify({
type: 'status',
state: 'idle'
}));
process.exit(0);
});Create package.json:
{"name": "my-custom-agent", "version": "1.0.0", "main": "index.js"}Step 3: Test Locally
Build and test your container:
# Build
docker build -t my-custom-agent .
# Test locally
echo '{"type":"message","content":"hello"}' | docker run -i \
-e FILEPATH_TASK="Test task" \
-e FILEPATH_API_KEY="sk-test" \
my-custom-agentYou should see NDJSON output.
Step 4: Push to Registry
Push your image to a container registry:
# Tag for registry docker tag my-custom-agent:latest ghcr.io/YOURNAME/my-custom-agent:latest # Push docker push ghcr.io/YOURNAME/my-custom-agent:latest
Step 5: Register in filepath
Currently, custom agents are added via PR to the filepath repo. Submit a PR adding your agent to the catalog.
Event Reference
Your agent should emit these event types:
{"type":"text","content":"Hello from agent"} — Assistant message{"type":"tool","name":"git","status":"success"} — Tool execution{"type":"done"} — Task completeBest Practices
- • Flush stdout after each JSON line
- • Handle SIGTERM gracefully — save state and exit
- • Validate input — don't crash on malformed JSON
- • Emit status — let users know when you're working vs idle
- • Use /workspace — that's where files live
Next Steps
- • Read the Protocol Deep Dive for full details
- • Check Agent Catalog for reference implementations
- • Join discussions on GitHub