BlackBox-MCP
# BlackBox-MCP
A [FastMCP](https://github.com/modelcontextprotocol/python-sdk) server for local project
context **and** a configurable Agent Assistants / delegation system. Everything is
local-first: state lives in plain JSON under `~/.blackbox/` — no database, no cloud
service, no remote BlackBox. API keys are never stored in configuration; only the name
of an environment variable that supplies them.
## Tools
### Project context (original)
| Tool | Purpose |
| --- | --- |
| `project_scan` | Inventory a local project (file counts, languages, tree) and cache the result. |
| `project_memory` | Small key/value facts scoped to a project (`set` / `get` / `list` / `delete`). |
| `agent_handoff` | Leave, read, and resolve notes between agents. |
### Agent Assistants (v0.1)
| Tool | Purpose |
| --- | --- |
| `list_providers` | List configured providers (public config only — never keys). |
| `create_provider` / `update_provider` / `delete_provider` | Manage provider configurations. |
| `list_assistants` | List configured assistants. |
| `get_assistant` | Full configuration of one assistant. |
| `create_assistant` / `update_assistant` / `delete_assistant` | Manage assistant profiles. |
| `enable_assistant` / `disable_assistant` | Toggle an assistant on/off. |
| `list_capabilities` | All capability terms in use across enabled assistants. |
| `find_assistants` | Discover assistants by capability (all-of or any-of). |
| `delegate_task` | Send a task to an assistant; returns a persistent task id. |
| `get_task` / `list_tasks` | Inspect task state/result. |
| `cancel_task` | Cancel a queued or running task when possible. |
## Install
```bash
cd ~/BlackBox-MCP
python3 -m venv .venv
.venv/bin/pip install "mcp>=1.10,<2" "httpx>=0.27"
```
`server.py` runs with the stdio transport, which is what Zed (and most MCP clients) expect.
> Note: `mcp` 2.x replaced the `FastMCP` class with `MCPServer`, so BlackBox pins the
> latest 1.x release, which still ships the FastMCP API used here.
## Run
```bash
~/BlackBox-MCP/.venv/bin/python ~/BlackBox-MCP/server.py
```
## Zed configuration
Add this to `~/.config/zed/settings.json`:
```json
{
"context_servers": {
"blackbox": {
"command": "/Users/michaelshingara/BlackBox-MCP/.venv/bin/python",
"args": ["/Users/michaelshingara/BlackBox-MCP/server.py"],
"env": {}
}
}
}
```
Then run the **zed: restart server** action for the BlackBox server (or restart Zed).
> Note: `args` is required for stdio servers in Zed — an entry without it fails to load.
> The legacy `"mcp"` settings key has been replaced by `"context_servers"`.
> Zed only resolves settings-based context servers when at least one project folder is
> open — extension servers are the exception.
## Agent Assistants: concepts
Two separate, independently configurable concepts:
- **Providers** describe *how a model is reached* (endpoint, provider type, optional env-var
key). They contain no assistant identity and no prompt.
- **Assistants** are user-defined agent profiles: identity, provider reference, model,
system prompt, temperature, max tokens, capabilities, permissions, metadata.
Changing an assistant's `provider` or `model` never touches its name, description,
system prompt, or capabilities.
## Configuration
Configuration is human-readable JSON stored in `~/.blackbox/`. You can edit the files
directly or manage everything through the MCP tools.
### Providers — `~/.blackbox/providers.json`
```json
{
"provider::ollama": {
"name": "ollama",
"type": "ollama",
"endpoint": "http://localhost:11434",
"api_key_env": "",
"options": {}
},
"provider::mistral": {
"name": "mistral",
"type": "openai_compatible",
"endpoint": "https://api.mistral.ai/v1",
"api_key_env": "MISTRAL_API_KEY",
"options": {}
}
}
```
Built-in provider types: `stub` (offline/test), `openai_compatible` (any
`/chat/completions` endpoint: Mistral, OpenRouter, Gemini, custom), `ollama`.
### Assistants — `~/.blackbox/assistants.json`
```json
{
"assistant::swift_expert": {
"id": "swift_expert",
"name": "Swift Expert",
"description": "Senior Swift/iOS engineer",
"provider": "ollama",
"model": "qwen2.5-coder",
"system_prompt": "You are an expert Swift and iOS engineer. Answer concisely.",
"temperature": 0.2,
"max_tokens": 2048,
"enabled": true,
"capabilities": ["swift", "swiftui", "ios"],
"permissions": ["read_files"],
"metadata": {}
}
}
```
### Secrets
API keys are **not** stored in configuration. Providers reference an environment
variable name via `api_key_env`; the value is resolved at request time. `list_providers`
and `create_provider` only ever report the env-var name, never the key value.
## Delegation
```text
Lead Agent → BlackBox MCP → select assistant → resolve provider+model → execute → structured result
```
- `delegate_task(assistant_id, task, context=..., timeout=...)` enqueues a task and returns
a persistent `task_id` immediately. Execution is asynchronous.
- Poll `get_task(task_id)` or `list_tasks(...)` for status.
- Task statuses: `queued`, `running`, `completed`, `failed`, `cancelled`.
- Task metadata: `task_id`, `assistant_id`, `status`, `created_at`, `started_at`,
`completed_at`, `task`, `context`, `result`, `error`.
### Safeguards (safe defaults)
- `max concurrent tasks`: 4
- `per-task timeout`: 600s (override per task)
- `maximum delegation depth`: 3 (prevents uncontrolled recursive delegation)
Safeguards are module constants in `blackbox/assistants/tasks.py` and can be tuned there.
## Capability-based discovery
You don't need to know every assistant's id:
```text
Need: swift + ios + code_review
→ find_assistants(capabilities='["swift", "ios", "code_review"]')
```
Returns every enabled assistant whose capabilities contain all requested terms
(or any, with `any_of=true`). `list_capabilities()` shows which terms exist.
## Permissions
Assistants carry a simple, explicit `permissions` list (e.g. `read_files`, `run_commands`,
`git`, `web`, `build`, `test`). Default is an empty list — nothing is granted implicitly.
Permissions are currently descriptive metadata; enforcement hooks are designed into the
model so they can be expanded later. BlackBox never executes arbitrary commands simply
because a delegated assistant requests them.
## Agent Orchestration coexistence
BlackBox-MCP does not duplicate Agent Orchestration:
- **Agent Orchestration** → coordination, shared work state, handoffs, team coordination
- **BlackBox-MCP** → project intelligence, memory, configurable assistants, delegation
infrastructure
The existing `agent_handoff` tool is the bridge: assistants can record notes that
Agent Orchestration reads.
## Storage
All data lives locally in `~/.blackbox/`:
- `projects.json` — cached `project_scan` summaries
- `memory.json` — `project_memory` facts
- `handoffs.json` — `agent_handoff` notes
- `providers.json` — provider configurations
- `assistants.json` — assistant profiles
- `tasks.json` — delegated task state
Stop the server and delete a file to wipe that store.
## Tests
```bash
cd ~/BlackBox-MCP
.venv/bin/python -m unittest discover -s tests -v
```
Tests cover the assistant registry (CRUD, validation, capability matching) and the
delegation/task lifecycle (submit, completion, cancellation, timeouts, depth guard).
They run against temporary directories and never touch `~/.blackbox`.
## Assistant/Provider Configuration Format
### Provider
```json
{
"name": "openai",
"type": "openai_compatible",
"endpoint": "https://api.openai.com/v1",
"api_key_env": "OPENAI_API_KEY",
"options": {
"model": "gpt-4o"
}
}
```
Supported types: `stub`, `openai_compatible`, `ollama`, `mistral`, `stepfun`.
### Assistant
```json
{
"name": "Pickle",
"provider": "openai",
"model": "gpt-4o",
"role": "implementation",
"description": "General-purpose implementation assistant",
"system_prompt": "You are Pickle, an expert implementation assistant.",
"temperature": 0.2,
"capabilities": ["swift", "ios", "python"],
"filesystem_permissions": ["read", "write"],
"command_execution_permissions": ["bash"],
"max_delegation_depth": 3,
"timeout": 600.0,
"memory_access": ["project_facts", "discoveries"]
}
```
## Delegation Modes
- `delegate` — single assistant
- `parallel` — same task to multiple assistants
- `review` — one produces, another reviews
- `debate` — competing analyses
- `pipeline` — chained output-to-input
## Memory Categories
- `project_facts`
- `architectural_decisions`
- `discoveries`
- `bugs`
- `failed_approaches`
- `recommendations`
- `agent_observations`
- `user_instructions`
## Security
- API keys are referenced by env-var name only
- Keys are never exposed via tools, logs, or memory
- Configurable delegation depth and max spawned agents
- Optional approval gates for command/file-write/destructive operations
## First Delegation Example
1. Create provider: `create_provider(name="openai", type="openai_compatible", endpoint="https://api.openai.com/v1", api_key_env="OPENAI_API_KEY")`
2. Create assistant: `create_assistant(name="Pickle", provider="openai", model="gpt-4o", role="implementation")`
3. Delegate: `delegate_task(assistant_id="pickle", task="Implement this feature")`
4. Check result: `get_task(task_id)`
TDQS
Scored across 35 tools
Tools are generally distinct: assistant CRUD, task delegation, memory, provider management all have clear boundaries. Some potential overlap exists between task delegation modes (delegate_task vs parallel_task vs debate_task vs pipeline_task), but descriptions clarify their distinct purposes. The enable/disable_assistant pair could be confused with update_assistant(enabled=...), but not severely.
Mostly consistent verb_noun pattern (list_assistants, create_assistant, delegate_task, save_memory). A few deviations exist: blackbox_status and blackbox_help use a prefix instead of verb_noun, and agent_handoff is a noun without a clear verb. However, the vast majority follow the expected convention.
35 tools is on the heavy side for a single server, though the domain is broad (assistants, tasks, memory, providers, approvals, project scanning). Some functions could be merged (e.g., enable/disable_assistant could be handled by update_assistant), and the task delegation variants might be consolidated. It's borderline but not egregious.
Coverage is comprehensive: full CRUD for assistants, providers, and memory; task lifecycle includes delegation, listing, retrieval, cancellation, and multiple modes (parallel, review, debate, pipeline); approvals and configuration are included. No obvious gaps for the stated purpose of coordinating AI assistants.