OpenCode Background Processes Plugin (fork from zenobi-us/opencode-background)
The original npm package @zenobius/opencode-background from https://github.com/zenobi-us/opencode-background isn’t being maintained or updated, so I’ve stepped in with a maintained fork/version.
Until (or if) the original gets attention, use the @mbanucu version instead.
Demo: How to use @mbanucu/opencode-background
Here is the code for the echo_server.py:
import http.server
import socketserver
from datetime import datetime
import json
class EchoHandler(http.server.BaseHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
msg = post_data.decode('utf-8')
print(msg, flush=True)
now = datetime.now().astimezone().isoformat(timespec='seconds')
try:
server_ip, server_port = self.connection.getsockname()[:2]
server_info = f'{server_ip}:{server_port}'
except Exception:
server_info = 'unknown'
log_object = {
'timestamp': now,
'message': msg,
'client_ip': self.client_address[0],
'server': server_info
}
log_line = json.dumps(log_object, indent=2)
with open('echo_server.log', 'a') as f:
f.write(log_line + '\n')
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(log_line.encode('utf-8'))
if __name__ == '__main__':
with socketserver.TCPServer(("", 0), EchoHandler) as httpd:
port = httpd.server_address[1]
print(f"Server running on port {port}", flush=True)
httpd.serve_forever()
Links
- Fork/Maintained repo: https://github.com/MBanucu/opencode-background
- Original repo: https://github.com/zenobi-us/opencode-background
- npm package (recommended): https://www.npmjs.com/package/@mbanucu/opencode-background
- Original npm package: https://www.npmjs.com/package/@zenobius/opencode-background
- How to install plugins from npm in OpenCode: https://opencode.ai/docs/plugins/#from-npm
OpenCode session transcript
Testing echo_server manually with curl in background
Session ID: ses_47028381cffeUyoaJzJtLY2P6k Created: 1/5/2026, 9:27:21 PM Updated: 1/5/2026, 9:27:36 PM
User
test the echo_server manually by running it in background and sending some data with curl commands
Assistant (Build · grok-code · 2.9s)
Thinking:
The user wants to test the echo_server manually by running it in background and sending some data with curl commands.
Tool: glob
**Input:**
```json
{
"pattern": "*"
}
```
**Output:**
```
/home/michi/dev/opencode-background/demo/Running background processes/python server/demo.cast
/home/michi/dev/opencode-background/demo/Running background processes/python server/echo_server.py
```
Assistant (Build · grok-code · 1.1s)
Thinking:
There’s an echo_server.py file. Let me read it to understand what it does.
Tool: read
**Input:**
```json
{
"filePath": "/home/michi/dev/opencode-background/demo/Running background processes/python server/echo_server.py"
}
```
**Output:**
```
<file>
00001| import http.server
00002| import socketserver
00003| from datetime import datetime
00004| import json
00005|
00006| class EchoHandler(http.server.BaseHTTPRequestHandler):
00007| def do_POST(self):
00008| content_length = int(self.headers['Content-Length'])
00009| post_data = self.rfile.read(content_length)
00010| msg = post_data.decode('utf-8')
00011| print(msg, flush=True)
00012| now = datetime.now().astimezone().isoformat(timespec='seconds')
00013| try:
00014| server_ip, server_port = self.connection.getsockname()[:2]
00015| server_info = f'{server_ip}:{server_port}'
00016| except Exception:
00017| server_info = 'unknown'
00018| log_object = {
00019| 'timestamp': now,
00020| 'message': msg,
00021| 'client_ip': self.client_address[0],
00022| 'server': server_info
00023| }
00024| log_line = json.dumps(log_object, indent=2)
00025| with open('echo_server.log', 'a') as f:
00026| f.write(log_line + '\n')
00027| self.send_response(200)
00028| self.send_header('Content-Type', 'application/json')
00029| self.end_headers()
00030| self.wfile.write(log_line.encode('utf-8'))
00031|
00032| if __name__ == '__main__':
00033| with socketserver.TCPServer(("", 0), EchoHandler) as httpd:
00034| port = httpd.server_address[1]
00035| print(f"Server running on port {port}", flush=True)
00036| httpd.serve_forever()
(End of file - total 36 lines)
</file>
```
Assistant (Build · grok-code · 2.3s)
Thinking:
The echo_server.py is a Python HTTP server that listens on a random port (port 0 means it chooses an available port). It handles POST requests, echoes back the message with timestamp, client IP, and server info, and logs to a file.
Tool: createBackgroundProcess
**Input:**
```json
{
"command": "python3 echo_server.py",
"name": "echo_server"
}
```
**Output:**
```
task-y1i1772
```
Assistant (Build · grok-code · 1.1s)
Thinking:
The server is now running in background with task ID task-y1i1772.
Tool: getBackgroundProcess
**Input:**
```json
{
"taskId": "task-y1i1772"
}
```
**Output:**
```
{"id":"task-y1i1772","name":"echo_server","status":"running","command":"python3 echo_server.py","startedAt":"2026-01-05T20:27:28.168Z","completedAt":"","error":"","sessionId":"ses_47028381cffeUyoaJzJtLY2P6k","tags":[],"pid":597739,"global":false,"outputStream":["Server running on port 37427"]}
```
Assistant (Build · grok-code · 1.5s)
Thinking:
The server is running on port 37427.
Tool: bash
**Input:**
```json
{
"command": "curl -X POST -d \"Hello, World!\" http://localhost:37427",
"description": "Send POST request with message to echo server"
}
```
**Output:**
```
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 148 0 135 100 13 25802 2484 --:--:-- --:--:-- --:--:-- 29600
{
"timestamp": "2026-01-05T21:27:30+01:00",
"message": "Hello, World!",
"client_ip": "127.0.0.1",
"server": "127.0.0.1:37427"
}
```
Assistant (Build · grok-code · 1.1s)
Thinking:
Good! The server responded with the echoed data. Let me send another test with different data.
Tool: bash
**Input:**
```json
{
"command": "curl -X POST -d '{\"key\": \"value\", \"test\": true}' http://localhost:37427",
"description": "Send JSON POST request to test echo server"
}
```
**Output:**
```
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 188 0 158 100 30 68427 12992 --:--:-- --:--:-- --:--:-- 94000
{
"timestamp": "2026-01-05T21:27:31+01:00",
"message": "{\"key\": \"value\", \"test\": true}",
"client_ip": "127.0.0.1",
"server": "127.0.0.1:37427"
}
```
Assistant (Build · grok-code · 0.9s)
Thinking:
Excellent! Let me check the log file to see if it’s being written correctly.
Tool: read
**Input:**
```json
{
"filePath": "/home/michi/dev/opencode-background/demo/Running background processes/python server/echo_server.log"
}
```
**Output:**
```
<file>
00001| {
00002| "timestamp": "2026-01-05T21:27:30+01:00",
00003| "message": "Hello, World!",
00004| "client_ip": "127.0.0.1",
00005| "server": "127.0.0.1:37427"
00006| }
00007| {
00008| "timestamp": "2026-01-05T21:27:31+01:00",
00009| "message": "{\"key\": \"value\", \"test\": true}",
00010| "client_ip": "127.0.0.1",
00011| "server": "127.0.0.1:37427"
00012| }
00013|
(End of file - total 13 lines)
</file>
```
Assistant (Build · grok-code · 1.1s)
Thinking:
Perfect! The server is working correctly. It echoes back the data with timestamp, client/server info, and logs to the file.
Tool: bash
**Input:**
```json
{
"command": "curl -X POST -d \"Final test message\" http://localhost:37427",
"description": "Send final test POST request to echo server"
}
```
**Output:**
```
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 158 0 140 100 18 55183 7094 --:--:-- --:--:-- --:--:-- 79000
{
"timestamp": "2026-01-05T21:27:34+01:00",
"message": "Final test message",
"client_ip": "127.0.0.1",
"server": "127.0.0.1:37427"
}
```
Assistant (Build · grok-code · 0.8s)
Thinking:
Now let me stop the server.
Tool: killTasks
**Input:**
```json
{
"taskId": "task-y1i1772"
}
```
**Output:**
```
["task-y1i1772"]
```
Assistant (Build · grok-code · 1.0s)
Thinking:
The server has been stopped. The testing is complete. The echo server is working correctly.
Testing complete! The echo_server.py runs in the background and correctly echoes POST data with timestamps, client/server info, and logs to echo_server.log.