refactor: move the coder tools

This commit is contained in:
Richard Tang
2026-03-06 14:56:19 -08:00
parent 207a0a0ca5
commit 5ce230b0a6
31 changed files with 306 additions and 660 deletions
+2 -20
View File
@@ -1,34 +1,16 @@
{
"permissions": {
"allow": [
"mcp__agent-builder__create_session",
"mcp__agent-builder__set_goal",
"mcp__agent-builder__add_node",
"mcp__agent-builder__add_edge",
"mcp__agent-builder__configure_loop",
"mcp__agent-builder__add_mcp_server",
"mcp__agent-builder__validate_graph",
"mcp__agent-builder__export_graph",
"mcp__agent-builder__load_session_by_id",
"Bash(git status:*)",
"Bash(gh run view:*)",
"Bash(uv run:*)",
"Bash(env:*)",
"mcp__agent-builder__test_node",
"mcp__agent-builder__list_mcp_tools",
"Bash(python -m py_compile:*)",
"Bash(python -m pytest:*)",
"Bash(source:*)",
"mcp__agent-builder__update_node",
"mcp__agent-builder__check_missing_credentials",
"mcp__agent-builder__list_stored_credentials",
"Bash(find:*)",
"mcp__agent-builder__run_tests",
"Bash(PYTHONPATH=core:exports:tools/src uv run pytest:*)",
"mcp__agent-builder__list_agent_sessions",
"mcp__agent-builder__generate_constraint_tests",
"mcp__agent-builder__generate_success_tests"
"Bash(PYTHONPATH=core:exports:tools/src uv run pytest:*)"
]
},
"enabledMcpjsonServers": ["agent-builder", "tools"]
"enabledMcpjsonServers": ["tools"]
}
-2
View File
@@ -67,8 +67,6 @@ temp/
exports/*
.agent-builder-sessions/*
.claude/settings.local.json
.claude/skills/ship-it/
+1 -7
View File
@@ -1,9 +1,3 @@
{
"mcpServers": {
"agent-builder": {
"command": "uv",
"args": ["run", "-m", "framework.mcp.agent_builder_server"],
"cwd": "core"
}
}
"mcpServers": {}
}
-1
View File
@@ -1,5 +1,4 @@
exports/
docs/
.agent-builder-sessions/
.pytest_cache/
**/__pycache__/
-5
View File
@@ -1,10 +1,5 @@
{
"mcpServers": {
"agent-builder": {
"command": "python",
"args": ["-m", "framework.mcp.agent_builder_server"],
"cwd": "core"
},
"tools": {
"command": "python",
"args": ["-m", "aden_tools.mcp_server", "--stdio"],
+10 -11
View File
@@ -1,17 +1,16 @@
# MCP Server Guide - Agent Builder
# MCP Server Guide - Agent Building Tools
This guide covers the MCP (Model Context Protocol) server for building goal-driven agents.
> **Note:** The standalone `agent-builder` MCP server (`framework.mcp.agent_builder_server`) has been replaced. Agent building is now done via the `coder-tools` server's `initialize_agent_package` tool, with underlying logic in `framework.builder.package_generator`.
This guide covers the MCP tools available for building goal-driven agents.
## Setup
### Quick Setup
```bash
# Using the setup script (recommended)
python setup_mcp.py
# Or using bash
./setup_mcp.sh
# Run the quickstart script (recommended)
./quickstart.sh
```
### Manual Configuration
@@ -21,10 +20,10 @@ Add to your MCP client configuration (e.g., Claude Desktop):
```json
{
"mcpServers": {
"agent-builder": {
"command": "python",
"args": ["-m", "framework.mcp.agent_builder_server"],
"cwd": "/path/to/goal-agent"
"coder-tools": {
"command": "uv",
"args": ["run", "coder_tools_server.py", "--stdio"],
"cwd": "/path/to/hive/tools"
}
}
}
+3 -58
View File
@@ -17,66 +17,11 @@ Framework provides a runtime framework that captures **decisions**, not just act
uv pip install -e .
```
## MCP Server Setup
## Agent Building
The framework includes an MCP (Model Context Protocol) server for building agents. To set up the MCP server:
Agent scaffolding is handled by the `coder-tools` MCP server (in `tools/coder_tools_server.py`), which provides the `initialize_agent_package` tool and related utilities. The underlying package generation logic lives in `framework.builder.package_generator`.
### Automated Setup
**Using bash (Linux/macOS):**
```bash
./setup_mcp.sh
```
**Using Python (cross-platform):**
```bash
python setup_mcp.py
```
The setup script will:
1. Install the framework package
2. Install MCP dependencies (mcp, fastmcp)
3. Create/verify `.mcp.json` configuration
4. Test the MCP server module
### Manual Setup
If you prefer manual setup:
```bash
# Install framework
uv pip install -e .
# Install MCP dependencies
uv pip install mcp fastmcp
# Test the server
uv run python -m framework.mcp.agent_builder_server
```
### Using with MCP Clients
To use the agent builder with Claude Desktop or other MCP clients, add this to your MCP client configuration:
```json
{
"mcpServers": {
"agent-builder": {
"command": "python",
"args": ["-m", "framework.mcp.agent_builder_server"],
"cwd": "/path/to/hive/core"
}
}
}
```
The MCP server provides tools for:
- Creating agent building sessions
- Defining goals with success criteria
- Adding nodes (event_loop only)
- Connecting nodes with edges
- Validating and exporting agent graphs
- Testing nodes and full agent graphs
See the [Getting Started Guide](../docs/getting-started.md) for building agents.
## Quick Start
+1 -1
View File
@@ -7,7 +7,7 @@ from .nodes import coder_node, queen_node
# Goal definition
goal = Goal(
id="agent-builder",
id="hive-coder",
name="Hive Agent Builder",
description=(
"Build complete, validated Hive agent packages from natural language "
@@ -113,7 +113,7 @@ _QUEEN_RUNNING_TOOLS = [
# additions.
# ---------------------------------------------------------------------------
_agent_builder_knowledge = """\
_package_builder_knowledge = """\
**A responsible engineer doesn't jump into building. First, \
understand the problem and be transparent about what the framework can and cannot do.**
@@ -880,7 +880,7 @@ coder_node = NodeSpec(
system_prompt=(
"You are Hive Coder, the best agent-building coding agent. You build "
"production-ready Hive agent packages from natural language.\n"
+ _agent_builder_knowledge
+ _package_builder_knowledge
+ _coder_completion
+ _appendices
),
@@ -962,7 +962,7 @@ queen_node = NodeSpec(
system_prompt=(
_queen_identity_building
+ _queen_style
+ _agent_builder_knowledge
+ _package_builder_knowledge
+ _gcu_building_section # GCU as first-class citizen (not appendix)
+ _queen_tools_docs
+ _queen_behavior
@@ -995,7 +995,7 @@ __all__ = [
"_queen_behavior_running",
"_queen_phase_7",
"_queen_style",
"_agent_builder_knowledge",
"_package_builder_knowledge",
"_appendices",
"_gcu_building_section",
]
@@ -1,10 +1,11 @@
"""
MCP Server for Agent Building Tools
Package Generator for Agent Building Tools
Exposes tools for building goal-driven agents via the Model Context Protocol.
Generates agent packages from build sessions. Extracted from the MCP server
so it can be used as a standalone CLI or imported as a library.
Usage:
uv run python -m framework.mcp.agent_builder_server
uv run python -m framework.builder.package_generator <agent_name> <agent_json_path>
"""
import json
@@ -14,9 +15,8 @@ import shutil
import sys
from datetime import datetime
from pathlib import Path
from typing import Annotated
# Project root resolution. This file lives at core/framework/mcp/agent_builder_server.py,
# Project root resolution. This file lives at core/framework/builder/package_generator.py,
# so the project root (where exports/ lives) is four parents up.
_PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent.parent
@@ -26,7 +26,6 @@ if _exports_dir.is_dir() and str(_exports_dir) not in sys.path:
sys.path.insert(0, str(_exports_dir))
del _exports_dir
from mcp.server import FastMCP # noqa: E402
from pydantic import ValidationError # noqa: E402
from framework.graph import ( # noqa: E402
@@ -44,9 +43,6 @@ from framework.testing.prompts import ( # noqa: E402
)
from framework.utils.io import atomic_write # noqa: E402
# Initialize MCP server
mcp = FastMCP("agent-builder")
# Session persistence directory
SESSIONS_DIR = Path(".agent-builder-sessions")
@@ -199,12 +195,11 @@ def get_session() -> BuildSession:
# =============================================================================
# MCP TOOLS
# TOOLS
# =============================================================================
@mcp.tool()
def create_session(name: Annotated[str, "Name for the agent being built"]) -> str:
def create_session(name: str) -> str:
"""Create a new agent building session. Call this first before building an agent."""
global _session
_session = BuildSession(name)
@@ -219,7 +214,6 @@ def create_session(name: Annotated[str, "Name for the agent being built"]) -> st
)
@mcp.tool()
def list_sessions() -> str:
"""List all saved agent building sessions."""
_ensure_sessions_dir()
@@ -263,8 +257,7 @@ def list_sessions() -> str:
)
@mcp.tool()
def load_session_by_id(session_id: Annotated[str, "ID of the session to load"]) -> str:
def load_session_by_id(session_id: str) -> str:
"""Load a previously saved agent building session by its ID."""
global _session
@@ -292,8 +285,7 @@ def load_session_by_id(session_id: Annotated[str, "ID of the session to load"])
return json.dumps({"success": False, "error": str(e)})
@mcp.tool()
def delete_session(session_id: Annotated[str, "ID of the session to delete"]) -> str:
def delete_session(session_id: str) -> str:
"""Delete a saved agent building session."""
global _session
@@ -326,17 +318,12 @@ def delete_session(session_id: Annotated[str, "ID of the session to delete"]) ->
return json.dumps({"success": False, "error": str(e)})
@mcp.tool()
def set_goal(
goal_id: Annotated[str, "Unique identifier for the goal"],
name: Annotated[str, "Human-readable name"],
description: Annotated[str, "What the agent should accomplish"],
success_criteria: Annotated[
str, "JSON array of success criteria objects with id, description, metric, target, weight"
],
constraints: Annotated[
str, "JSON array of constraint objects with id, description, constraint_type, category"
] = "[]",
goal_id: str,
name: str,
description: str,
success_criteria: str,
constraints: str = "[]",
) -> str:
"""Define the goal for the agent. Goals define what success looks like."""
session = get_session()
@@ -593,35 +580,19 @@ def _validate_agent_path(agent_path: str) -> tuple[Path | None, str | None]:
return path, None
@mcp.tool()
def add_node(
node_id: Annotated[str, "Unique identifier for the node"],
name: Annotated[str, "Human-readable name"],
description: Annotated[str, "What this node does"],
node_type: Annotated[
str,
"Type: event_loop (recommended), gcu (browser automation), router.",
],
input_keys: Annotated[str, "JSON array of keys this node reads from shared memory"],
output_keys: Annotated[str, "JSON array of keys this node writes to shared memory"],
system_prompt: Annotated[str, "Instructions for LLM nodes"] = "",
tools: Annotated[str, "JSON array of tool names for event_loop nodes"] = "[]",
routes: Annotated[
str, "JSON object mapping conditions to target node IDs for router nodes"
] = "{}",
client_facing: Annotated[
bool,
"Workers should be autonomous: set False. client_facing=True routes user-facing "
"conversation to the node; this architecture requires worker->queen handoff "
"instead via escalate when blocked.",
] = False,
nullable_output_keys: Annotated[
str, "JSON array of output keys that may remain unset (for mutually exclusive outputs)"
] = "[]",
max_node_visits: Annotated[
int,
"Max times this node executes per graph run. Set >1 for feedback loop targets. 0=unlimited",
] = 1,
node_id: str,
name: str,
description: str,
node_type: str,
input_keys: str,
output_keys: str,
system_prompt: str = "",
tools: str = "[]",
routes: str = "{}",
client_facing: bool = False,
nullable_output_keys: str = "[]",
max_node_visits: int = 1,
) -> str:
"""Add a node to the agent graph. Nodes process inputs and produce outputs."""
session = get_session()
@@ -754,16 +725,13 @@ def add_node(
)
@mcp.tool()
def add_edge(
edge_id: Annotated[str, "Unique identifier for the edge"],
source: Annotated[str, "Source node ID"],
target: Annotated[str, "Target node ID"],
condition: Annotated[
str, "When to traverse: always, on_success, on_failure, conditional"
] = "on_success",
condition_expr: Annotated[str, "Python expression for conditional edges"] = "",
priority: Annotated[int, "Priority when multiple edges match (higher = first)"] = 0,
edge_id: str,
source: str,
target: str,
condition: str = "on_success",
condition_expr: str = "",
priority: int = 0,
) -> str:
"""Connect two nodes with an edge. Edges define how execution flows between nodes."""
session = get_session()
@@ -850,27 +818,19 @@ def add_edge(
)
@mcp.tool()
def update_node(
node_id: Annotated[str, "ID of the node to update"],
name: Annotated[str, "Updated human-readable name"] = "",
description: Annotated[str, "Updated description"] = "",
node_type: Annotated[
str,
"Updated type: event_loop (recommended), router.",
] = "",
input_keys: Annotated[str, "Updated JSON array of input keys"] = "",
output_keys: Annotated[str, "Updated JSON array of output keys"] = "",
system_prompt: Annotated[str, "Updated instructions for LLM nodes"] = "",
tools: Annotated[str, "Updated JSON array of tool names"] = "",
routes: Annotated[str, "Updated JSON object mapping conditions to target node IDs"] = "",
client_facing: Annotated[
str, "Updated client-facing flag ('true'/'false', empty=no change)"
] = "",
nullable_output_keys: Annotated[
str, "Updated JSON array of nullable output keys (empty=no change)"
] = "",
max_node_visits: Annotated[int, "Updated max node visits per graph run. 0=no change"] = 0,
node_id: str,
name: str = "",
description: str = "",
node_type: str = "",
input_keys: str = "",
output_keys: str = "",
system_prompt: str = "",
tools: str = "",
routes: str = "",
client_facing: str = "",
nullable_output_keys: str = "",
max_node_visits: int = 0,
) -> str:
"""Update an existing node in the agent graph. Only provided fields will be updated."""
session = get_session()
@@ -994,9 +954,8 @@ def update_node(
)
@mcp.tool()
def delete_node(
node_id: Annotated[str, "ID of the node to delete"],
node_id: str,
) -> str:
"""Delete a node from the agent graph. Also removes all edges connected to this node."""
session = get_session()
@@ -1033,9 +992,8 @@ def delete_node(
)
@mcp.tool()
def delete_edge(
edge_id: Annotated[str, "ID of the edge to delete"],
edge_id: str,
) -> str:
"""Delete an edge from the agent graph."""
session = get_session()
@@ -1066,7 +1024,6 @@ def delete_edge(
)
@mcp.tool()
def validate_graph() -> str:
"""Validate the graph. Checks for unreachable nodes and context flow."""
session = get_session()
@@ -1654,7 +1611,6 @@ Terminal nodes: {", ".join(f"`{t}`" for t in export_data["graph"]["terminal_node
return readme
@mcp.tool()
def export_graph() -> str:
"""
Export the validated graph as a GraphSpec for GraphExecutor.
@@ -2581,11 +2537,8 @@ def _generate_mcp_servers_json(session: BuildSession) -> str | None:
return json.dumps(flat, indent=2)
@mcp.tool()
def initialize_agent_package(
agent_name: Annotated[
str, "Name for the agent package. Must be snake_case (e.g., 'my_research_agent')."
],
agent_name: str,
) -> str:
"""
Generate the full Python agent package from the current build session.
@@ -2837,9 +2790,8 @@ def initialize_agent_package(
)
@mcp.tool()
def import_from_export(
agent_json_path: Annotated[str, "Path to the agent.json file to import"],
agent_json_path: str,
) -> str:
"""
Import an agent definition from an exported agent.json file into the current build session.
@@ -2916,7 +2868,6 @@ def import_from_export(
)
@mcp.tool()
def get_session_status() -> str:
"""Get the current status of the build session."""
session = get_session()
@@ -2939,22 +2890,12 @@ def get_session_status() -> str:
)
@mcp.tool()
def configure_loop(
max_iterations: Annotated[int, "Maximum loop iterations per node execution (default 50)"] = 50,
max_tool_calls_per_turn: Annotated[int, "Maximum tool calls per LLM turn (default 30)"] = 30,
stall_detection_threshold: Annotated[
int, "Consecutive identical responses before stall detection triggers (default 3)"
] = 3,
max_history_tokens: Annotated[
int, "Maximum conversation history tokens before compaction (default 32000)"
] = 32000,
tool_call_overflow_margin: Annotated[
float,
"Overflow margin for max_tool_calls_per_turn. "
"Tool calls are only discarded when count exceeds "
"max_tool_calls_per_turn * (1 + margin). Default 0.5 (50% wiggle room)",
] = 0.5,
max_iterations: int = 50,
max_tool_calls_per_turn: int = 30,
stall_detection_threshold: int = 3,
max_history_tokens: int = 32000,
tool_call_overflow_margin: float = 0.5,
) -> str:
"""Configure event loop parameters for EventLoopNode execution.
@@ -2985,17 +2926,16 @@ def configure_loop(
)
@mcp.tool()
def add_mcp_server(
name: Annotated[str, "Unique name for the MCP server"],
transport: Annotated[str, "Transport type: 'stdio' or 'http'"],
command: Annotated[str, "Command to run (for stdio transport)"] = "",
args: Annotated[str, "JSON array of command arguments (for stdio)"] = "[]",
cwd: Annotated[str, "Working directory (for stdio)"] = "",
env: Annotated[str, "JSON object of environment variables (for stdio)"] = "{}",
url: Annotated[str, "Server URL (for http transport)"] = "",
headers: Annotated[str, "JSON object of HTTP headers (for http)"] = "{}",
description: Annotated[str, "Description of the MCP server"] = "",
name: str,
transport: str,
command: str = "",
args: str = "[]",
cwd: str = "",
env: str = "{}",
url: str = "",
headers: str = "{}",
description: str = "",
) -> str:
"""
Register an MCP server as a tool source for this agent.
@@ -3120,7 +3060,6 @@ def add_mcp_server(
)
@mcp.tool()
def list_mcp_servers() -> str:
"""List all registered MCP servers for this agent."""
session = get_session()
@@ -3143,9 +3082,8 @@ def list_mcp_servers() -> str:
)
@mcp.tool()
def list_mcp_tools(
server_name: Annotated[str, "Name of the MCP server to list tools from"] = "",
server_name: str = "",
) -> str:
"""
List tools available from registered MCP servers.
@@ -3211,9 +3149,8 @@ def list_mcp_tools(
)
@mcp.tool()
def remove_mcp_server(
name: Annotated[str, "Name of the MCP server to remove"],
name: str,
) -> str:
"""Remove a registered MCP server."""
session = get_session()
@@ -3229,13 +3166,10 @@ def remove_mcp_server(
return json.dumps({"success": False, "error": f"MCP server '{name}' not found"})
@mcp.tool()
def test_node(
node_id: Annotated[str, "ID of the node to test"],
test_input: Annotated[str, "JSON object with test input data for the node"],
mock_llm_response: Annotated[
str, "Mock LLM response to simulate (for testing without API calls)"
] = "",
node_id: str,
test_input: str,
mock_llm_response: str = "",
) -> str:
"""
Test a single node with sample inputs. Use this during HITL approval to show
@@ -3323,11 +3257,10 @@ def test_node(
)
@mcp.tool()
def test_graph(
test_input: Annotated[str, "JSON object with initial input data for the graph"],
max_steps: Annotated[int, "Maximum steps to execute (default 10)"] = 10,
dry_run: Annotated[bool, "If true, simulate without actual LLM calls"] = True,
test_input: str,
max_steps: int = 10,
dry_run: bool = True,
) -> str:
"""
Test the complete agent graph with sample inputs. Use this during final approval
@@ -3551,19 +3484,10 @@ async def test_success_{criteria_id}_{scenario}(runner, auto_responder, mock_mod
'''
@mcp.tool()
def generate_constraint_tests(
goal_id: Annotated[str, "ID of the goal to generate tests for"],
goal_json: Annotated[
str,
"""JSON string of the Goal object. Constraint fields:
- id: string (required)
- description: string (required)
- constraint_type: "hard" or "soft" (required)
- category: string (optional, default: "general")
- check: string (optional, how to validate: "llm_judge", expression, or function name)""",
],
agent_path: Annotated[str, "Path to agent export folder (e.g., 'exports/my_agent')"] = "",
goal_id: str,
goal_json: str,
agent_path: str = "",
) -> str:
"""
Get constraint test guidelines for a goal.
@@ -3645,13 +3569,12 @@ def generate_constraint_tests(
)
@mcp.tool()
def generate_success_tests(
goal_id: Annotated[str, "ID of the goal to generate tests for"],
goal_json: Annotated[str, "JSON string of the Goal object"],
node_names: Annotated[str, "Comma-separated list of agent node names"] = "",
tool_names: Annotated[str, "Comma-separated list of available tool names"] = "",
agent_path: Annotated[str, "Path to agent export folder (e.g., 'exports/my_agent')"] = "",
goal_id: str,
goal_json: str,
node_names: str = "",
tool_names: str = "",
agent_path: str = "",
) -> str:
"""
Get success criteria test guidelines for a goal.
@@ -3745,18 +3668,13 @@ def generate_success_tests(
)
@mcp.tool()
def run_tests(
goal_id: Annotated[str, "ID of the goal to test"],
agent_path: Annotated[str, "Path to the agent export folder"],
test_types: Annotated[
str, 'JSON array of test types: ["constraint", "success", "edge_case", "all"]'
] = '["all"]',
parallel: Annotated[
int, "Number of parallel workers (-1 for auto/CPU count, 0 to disable)"
] = -1,
fail_fast: Annotated[bool, "Stop on first failure (-x flag)"] = False,
verbose: Annotated[bool, "Verbose output (-v flag)"] = True,
goal_id: str,
agent_path: str,
test_types: str = '["all"]',
parallel: int = -1,
fail_fast: bool = False,
verbose: bool = True,
) -> str:
"""
Run pytest on agent test files.
@@ -3963,11 +3881,10 @@ def run_tests(
)
@mcp.tool()
def debug_test(
goal_id: Annotated[str, "ID of the goal"],
test_name: Annotated[str, "Name of the test function (e.g., test_constraint_foo)"],
agent_path: Annotated[str, "Path to agent export folder (e.g., 'exports/my_agent')"] = "",
goal_id: str,
test_name: str,
agent_path: str = "",
) -> str:
"""
Run a specific test with verbose output for debugging.
@@ -4129,10 +4046,9 @@ def debug_test(
)
@mcp.tool()
def list_tests(
goal_id: Annotated[str, "ID of the goal"],
agent_path: Annotated[str, "Path to agent export folder (e.g., 'exports/my_agent')"] = "",
goal_id: str,
agent_path: str = "",
) -> str:
"""
List tests for an agent by scanning Python test files.
@@ -4269,9 +4185,8 @@ def _get_credential_store():
return CredentialStore(storage=storage)
@mcp.tool()
def check_missing_credentials(
agent_path: Annotated[str, "Path to the exported agent directory (e.g., 'exports/my-agent')"],
agent_path: str,
) -> str:
"""
Detect missing credentials for an agent by inspecting its tools and node types.
@@ -4363,21 +4278,12 @@ def check_missing_credentials(
return json.dumps({"error": str(e)})
@mcp.tool()
def store_credential(
credential_name: Annotated[
str, "Logical credential name (e.g., 'hubspot', 'brave_search', 'anthropic')"
],
credential_value: Annotated[str, "The secret value to store (API key, token, etc.)"],
alias: Annotated[
str,
"Named alias for this account (e.g., 'work', 'personal'). Defaults to 'default'. "
"Use aliases to store multiple accounts for the same service.",
] = "default",
key_name: Annotated[
str, "Key name within the credential (e.g., 'api_key', 'access_token')"
] = "api_key",
display_name: Annotated[str, "Human-readable name (e.g., 'HubSpot Access Token')"] = "",
credential_name: str,
credential_value: str,
alias: str = "default",
key_name: str = "api_key",
display_name: str = "",
) -> str:
"""
Store a credential securely in the local encrypted store at ~/.hive/credentials.
@@ -4423,7 +4329,6 @@ def store_credential(
return json.dumps({"success": False, "error": str(e)})
@mcp.tool()
def list_stored_credentials() -> str:
"""
List all credentials currently stored in the local encrypted store.
@@ -4463,13 +4368,9 @@ def list_stored_credentials() -> str:
return json.dumps({"error": str(e)})
@mcp.tool()
def delete_stored_credential(
credential_name: Annotated[str, "Logical credential name to delete (e.g., 'hubspot')"],
alias: Annotated[
str,
"Alias of the account to delete (e.g., 'work', 'personal'). Defaults to 'default'.",
] = "default",
credential_name: str,
alias: str = "default",
) -> str:
"""
Delete a credential from the local encrypted store.
@@ -4495,15 +4396,9 @@ def delete_stored_credential(
return json.dumps({"success": False, "error": str(e)})
@mcp.tool()
def validate_credential(
credential_name: Annotated[
str, "Logical credential name to validate (e.g., 'brave_search', 'github')"
],
alias: Annotated[
str,
"Alias of the account to validate (e.g., 'work', 'personal'). Defaults to 'default'.",
] = "default",
credential_name: str,
alias: str = "default",
) -> str:
"""
Re-run health check for a stored credential and update its status.
@@ -4535,9 +4430,8 @@ def validate_credential(
return json.dumps({"success": False, "error": str(e)})
@mcp.tool()
def verify_credentials(
agent_path: Annotated[str, "Path to the exported agent directory (e.g., 'exports/my-agent')"],
agent_path: str,
) -> str:
"""
Verify that all required credentials are configured for an agent.
@@ -4609,18 +4503,11 @@ def _truncate_value(value: object, max_len: int = _MAX_DIFF_VALUE_LEN) -> object
return {"_truncated": True, "_preview": s[:max_len] + "...", "_length": len(s)}
@mcp.tool()
def list_agent_sessions(
agent_work_dir: Annotated[
str,
"Path to the agent's working directory (e.g., ~/.hive/agents/my_agent)",
],
status: Annotated[
str,
"Filter by status: 'active', 'paused', 'completed', 'failed', 'cancelled'. Empty for all.",
] = "",
limit: Annotated[int, "Maximum number of results (default 20)"] = 20,
offset: Annotated[int, "Number of sessions to skip for pagination"] = 0,
agent_work_dir: str,
status: str = "",
limit: int = 20,
offset: int = 0,
) -> str:
"""
List sessions for an agent with optional status filter.
@@ -4675,15 +4562,11 @@ def list_agent_sessions(
)
@mcp.tool()
def list_agent_checkpoints(
agent_work_dir: Annotated[str, "Path to the agent's working directory"],
session_id: Annotated[str, "The session ID to list checkpoints for"],
checkpoint_type: Annotated[
str,
"Filter by type: 'node_start', 'node_complete', 'loop_iteration'. Empty for all.",
] = "",
is_clean: Annotated[str, "Filter by clean status: 'true', 'false', or empty for all."] = "",
agent_work_dir: str,
session_id: str,
checkpoint_type: str = "",
is_clean: str = "",
) -> str:
"""
List checkpoints for a specific session.
@@ -4754,11 +4637,10 @@ def list_agent_checkpoints(
)
@mcp.tool()
def get_agent_checkpoint(
agent_work_dir: Annotated[str, "Path to the agent's working directory"],
session_id: Annotated[str, "The session ID"],
checkpoint_id: Annotated[str, "Specific checkpoint ID, or empty for latest"] = "",
agent_work_dir: str,
session_id: str,
checkpoint_id: str = "",
) -> str:
"""
Load a specific checkpoint with full state data.
@@ -4791,12 +4673,11 @@ def get_agent_checkpoint(
return json.dumps(data, indent=2, default=str)
@mcp.tool()
def compare_agent_checkpoints(
agent_work_dir: Annotated[str, "Path to the agent's working directory"],
session_id: Annotated[str, "The session ID"],
checkpoint_id_before: Annotated[str, "The earlier checkpoint ID"],
checkpoint_id_after: Annotated[str, "The later checkpoint ID"],
agent_work_dir: str,
session_id: str,
checkpoint_id_before: str,
checkpoint_id_after: str,
) -> str:
"""
Compare memory state between two checkpoints.
@@ -4874,4 +4755,19 @@ def compare_agent_checkpoints(
# =============================================================================
if __name__ == "__main__":
mcp.run(transport="stdio")
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("agent_name")
parser.add_argument("agent_json_path")
args = parser.parse_args()
# Import from export to load session
result = import_from_export(args.agent_json_path)
import_data = json.loads(result)
if not import_data.get("success"):
print(result)
sys.exit(1)
# Generate package
result = initialize_agent_package(args.agent_name)
print(result)
+1 -1
View File
@@ -19,7 +19,7 @@ then run with pytest and debugged with LLM assistance.
## MCP Tools
Testing tools are integrated into the main agent_builder_server.py:
Testing tools are available via the package generator:
- generate_constraint_tests, generate_success_tests (return guidelines)
- run_tests, debug_test, list_tests
+10 -46
View File
@@ -7,7 +7,6 @@ This script installs the framework and configures the MCP server.
import json
import logging
import os
import subprocess
import sys
from pathlib import Path
@@ -75,12 +74,12 @@ def main():
# Get script directory
script_dir = Path(__file__).parent.absolute()
os.chdir(script_dir)
# Step 1: Install framework package
log_step("Step 1: Installing framework package...")
if not run_command(
[sys.executable, "-m", "pip", "install", "-e", "."], "Failed to install framework package"
[sys.executable, "-m", "pip", "install", "-e", str(script_dir)],
"Failed to install framework package",
):
sys.exit(1)
log_success("Framework package installed")
@@ -96,7 +95,7 @@ def main():
log_success("MCP dependencies installed")
logger.info("")
# Step 3: Verify/create MCP configuration
# Step 3: Verify MCP configuration
log_step("Step 3: Verifying MCP server configuration...")
mcp_config_path = script_dir / ".mcp.json"
@@ -107,39 +106,22 @@ def main():
config = json.load(f)
logger.info(json.dumps(config, indent=2))
else:
log_error("No .mcp.json found")
logger.info("Creating default MCP configuration...")
config = {
"mcpServers": {
"agent-builder": {
"command": "python",
"args": ["-m", "framework.mcp.agent_builder_server"],
"cwd": str(script_dir),
}
}
}
with open(mcp_config_path, "w", encoding="utf-8") as f:
json.dump(config, f, indent=2)
log_success("Created .mcp.json")
log_success("No .mcp.json needed (MCP servers configured at repo root)")
logger.info("")
# Step 4: Test MCP server
log_step("Step 4: Testing MCP server...")
# Step 4: Test framework import
log_step("Step 4: Testing framework import...")
try:
# Try importing the MCP server module
subprocess.run(
[sys.executable, "-c", "from framework.mcp import agent_builder_server"],
[sys.executable, "-c", "import framework; print('OK')"],
check=True,
capture_output=True,
text=True,
encoding="utf-8",
)
log_success("MCP server module verified")
log_success("Framework module verified")
except subprocess.CalledProcessError as e:
log_error("Failed to import MCP server module")
log_error("Failed to import framework module")
logger.error(f"Error: {e.stderr}")
sys.exit(1)
logger.info("")
@@ -147,29 +129,11 @@ def main():
# Success summary
logger.info(f"{Colors.GREEN}=== Setup Complete ==={Colors.NC}")
logger.info("")
logger.info("The MCP server is now ready to use!")
logger.info("")
logger.info(f"{Colors.BLUE}To start the MCP server manually:{Colors.NC}")
logger.info(" uv run python -m framework.mcp.agent_builder_server")
logger.info("The framework is now ready to use!")
logger.info("")
logger.info(f"{Colors.BLUE}MCP Configuration location:{Colors.NC}")
logger.info(f" {mcp_config_path}")
logger.info("")
logger.info(f"{Colors.BLUE}To use with Claude Desktop or other MCP clients,{Colors.NC}")
logger.info(f"{Colors.BLUE}add the following to your MCP client configuration:{Colors.NC}")
logger.info("")
example_config = {
"mcpServers": {
"agent-builder": {
"command": "python",
"args": ["-m", "framework.mcp.agent_builder_server"],
"cwd": str(script_dir),
}
}
}
logger.info(json.dumps(example_config, indent=2))
logger.info("")
if __name__ == "__main__":
+6 -36
View File
@@ -40,52 +40,22 @@ if [ -f ".mcp.json" ]; then
echo "Configuration:"
cat .mcp.json
else
echo -e "${RED} No .mcp.json found${NC}"
echo "Creating default MCP configuration..."
cat > .mcp.json <<EOF
{
"mcpServers": {
"agent-builder": {
"command": "python",
"args": ["-m", "framework.mcp.agent_builder_server"],
"cwd": "$SCRIPT_DIR"
}
}
}
EOF
echo -e "${GREEN}✓ Created .mcp.json${NC}"
echo -e "${GREEN} No .mcp.json needed (MCP servers configured at repo root)${NC}"
fi
echo ""
echo -e "${YELLOW}Step 4: Testing MCP server...${NC}"
uv run python -c "from framework.mcp import agent_builder_server; print('✓ MCP server module loads successfully')" || {
echo -e "${RED}Failed to import MCP server module${NC}"
echo -e "${YELLOW}Step 4: Testing framework import...${NC}"
uv run python -c "import framework; print('✓ Framework module loads successfully')" || {
echo -e "${RED}Failed to import framework module${NC}"
exit 1
}
echo -e "${GREEN}MCP server module verified${NC}"
echo -e "${GREEN}Framework module verified${NC}"
echo ""
echo -e "${GREEN}=== Setup Complete ===${NC}"
echo ""
echo "The MCP server is now ready to use!"
echo ""
echo "To start the MCP server manually:"
echo " uv run python -m framework.mcp.agent_builder_server"
echo "The framework is now ready to use!"
echo ""
echo "MCP Configuration location:"
echo " $SCRIPT_DIR/.mcp.json"
echo ""
echo "To use with Claude Desktop or other MCP clients,"
echo "add the following to your MCP client configuration:"
echo ""
echo "{
\"mcpServers\": {
\"agent-builder\": {
\"command\": \"python\",
\"args\": [\"-m\", \"framework.mcp.agent_builder_server\"],
\"cwd\": \"$SCRIPT_DIR\"
}
}
}"
echo ""
@@ -1,61 +0,0 @@
"""Worker-autonomy guardrails for agent_builder_server."""
import json
from framework.graph import Goal, NodeSpec
from framework.mcp import agent_builder_server as builder
def _make_session(name: str = "autonomy_test"):
session = builder.BuildSession(name=name)
session.goal = Goal(
id="g1",
name="Autonomy Goal",
description="Workers stay autonomous.",
success_criteria=[],
constraints=[],
)
return session
def test_add_node_rejects_client_facing_event_loop(monkeypatch):
session = _make_session()
monkeypatch.setattr(builder, "_session", session)
monkeypatch.setattr(builder, "_save_session", lambda _: None)
raw = builder.add_node(
node_id="worker",
name="Worker",
description="Autonomous worker node",
node_type="event_loop",
input_keys='["task"]',
output_keys='["result"]',
system_prompt="Do work.",
client_facing=True,
)
data = json.loads(raw)
assert data["valid"] is False
assert any("client_facing=True" in err for err in data["errors"])
def test_validate_graph_rejects_client_facing_event_loop(monkeypatch):
session = _make_session()
session.nodes = [
NodeSpec(
id="worker",
name="Worker",
description="Autonomous worker node",
node_type="event_loop",
client_facing=True,
input_keys=[],
output_keys=[],
system_prompt="Do work.",
)
]
monkeypatch.setattr(builder, "_session", session)
data = json.loads(builder.validate_graph())
assert data["valid"] is False
assert any("must not be client_facing" in err for err in data["errors"])
-46
View File
@@ -42,40 +42,6 @@ class TestMCPDependencies:
assert FastMCP is not None
class TestAgentBuilderServerModule:
"""Tests for the agent_builder_server module."""
def test_module_importable(self):
"""Test that framework.mcp.agent_builder_server can be imported."""
if not MCP_AVAILABLE:
pytest.skip(MCP_SKIP_REASON)
import framework.mcp.agent_builder_server as module
assert module is not None
def test_mcp_object_exported(self):
"""Test that the module exports the 'mcp' object (FastMCP instance)."""
if not MCP_AVAILABLE:
pytest.skip(MCP_SKIP_REASON)
from mcp.server import FastMCP
from framework.mcp.agent_builder_server import mcp
assert mcp is not None
assert isinstance(mcp, FastMCP)
def test_mcp_server_name(self):
"""Test that the MCP server has the expected name."""
if not MCP_AVAILABLE:
pytest.skip(MCP_SKIP_REASON)
from framework.mcp.agent_builder_server import mcp
assert mcp.name == "agent-builder"
class TestMCPPackageExports:
"""Tests for the framework.mcp package exports."""
@@ -87,15 +53,3 @@ class TestMCPPackageExports:
import framework.mcp
assert framework.mcp is not None
def test_agent_builder_server_exported(self):
"""Test that agent_builder_server is exported from framework.mcp."""
if not MCP_AVAILABLE:
pytest.skip(MCP_SKIP_REASON)
from mcp.server import FastMCP
from framework.mcp import agent_builder_server
assert agent_builder_server is not None
assert isinstance(agent_builder_server.mcp, FastMCP)
+9 -60
View File
@@ -101,23 +101,7 @@ def main():
else:
success("all installed")
# Check 3: MCP server module
check("MCP server module")
try:
subprocess.run(
[sys.executable, "-c", "from framework.mcp import agent_builder_server"],
capture_output=True,
text=True,
check=True,
encoding="utf-8",
)
success("loads successfully")
except subprocess.CalledProcessError as e:
error("failed to import")
logger.error(f" Error: {e.stderr}")
all_checks_passed = False
# Check 4: MCP configuration file
# Check 3: MCP configuration file
check("MCP configuration file")
mcp_config = script_dir / ".mcp.json"
if mcp_config.exists():
@@ -125,14 +109,14 @@ def main():
with open(mcp_config, encoding="utf-8") as f:
config = json.load(f)
if "mcpServers" in config and "agent-builder" in config["mcpServers"]:
server_config = config["mcpServers"]["agent-builder"]
if "mcpServers" in config:
success("found and valid")
logger.info(f" Command: {server_config.get('command')}")
logger.info(f" Args: {' '.join(server_config.get('args', []))}")
logger.info(f" CWD: {server_config.get('cwd')}")
for name, server_config in config.get("mcpServers", {}).items():
logger.info(f" Server: {name}")
logger.info(f" Command: {server_config.get('command')}")
logger.info(f" Args: {' '.join(server_config.get('args', []))}")
else:
warning("exists but missing agent-builder config")
warning("exists but missing mcpServers config")
all_checks_passed = False
except json.JSONDecodeError:
error("invalid JSON format")
@@ -140,9 +124,8 @@ def main():
else:
warning("not found (optional)")
logger.info(f" Location would be: {mcp_config}")
logger.info(" Run setup_mcp.py to create it")
# Check 5: Framework modules
# Check 4: Framework modules
check("core framework modules")
modules_to_check = [
"framework.runtime.core",
@@ -170,46 +153,12 @@ def main():
else:
success(f"all {len(modules_to_check)} modules OK")
# Check 6: Test MCP server startup (quick test)
check("MCP server startup")
try:
# Try to import and instantiate the MCP server
result = subprocess.run(
[
sys.executable,
"-c",
"from framework.mcp.agent_builder_server import mcp; print('OK')",
],
capture_output=True,
text=True,
check=True,
timeout=5,
encoding="utf-8",
)
if "OK" in result.stdout:
success("server can start")
else:
warning("unexpected output")
except subprocess.TimeoutExpired:
warning("server startup slow (might be OK)")
except subprocess.CalledProcessError as e:
error("server failed to start")
logger.error(f" Error: {e.stderr}")
all_checks_passed = False
logger.info("")
logger.info("=" * 40)
if all_checks_passed:
logger.info(f"{Colors.GREEN}✓ All checks passed!{Colors.NC}")
logger.info("")
logger.info("Your MCP server is ready to use.")
logger.info("")
logger.info(f"{Colors.BLUE}To start the server:{Colors.NC}")
logger.info(" uv run python -m framework.mcp.agent_builder_server")
logger.info("")
logger.info(f"{Colors.BLUE}To use with Claude Desktop:{Colors.NC}")
logger.info(" Add the configuration from .mcp.json to your")
logger.info(" Claude Desktop MCP settings")
logger.info("Your framework is ready to use.")
else:
logger.info(f"{Colors.RED}✗ Some checks failed{Colors.NC}")
logger.info("")
+11 -11
View File
@@ -13,7 +13,7 @@ Use the Hive agent framework (MCP servers and skills) inside [Antigravity IDE](h
```bash
./scripts/setup-antigravity-mcp.sh
```
3. **Restart Antigravity IDE.** You should see **agent-builder** and **tools** as available MCP servers.
3. **Restart Antigravity IDE.** You should see **coder-tools** and **tools** as available MCP servers.
> **Important:** Always restart/refresh Antigravity IDE after running the setup script or making any changes to MCP configuration. The IDE only loads MCP servers on startup.
@@ -23,7 +23,7 @@ Done. For details, prerequisites, and troubleshooting, read on.
## What you get after setup
- **agent-builder** Create and manage agents (goals, nodes, edges).
- **coder-tools** Create and manage agents (scaffolding via `initialize_agent_package`, file I/O, tool discovery).
- **tools** File operations, web search, and other agent tools.
- **Documentation** Guided docs for building and testing agents.
@@ -68,7 +68,7 @@ The script finds the repo root, writes `~/.gemini/antigravity/mcp_config.json` w
> **Important:** Always restart/refresh Antigravity IDE after running the setup script. MCP servers are only loaded on IDE startup.
The **agent-builder** and **tools** servers should show up after restart.
The **coder-tools** and **tools** servers should show up after restart.
**Using Claude Code instead?** Run:
@@ -82,7 +82,7 @@ That writes `~/.claude/mcp.json` as well.
### Step 3: Use MCP tools + docs
Use the `agent-builder` and `tools` MCP servers in Antigravity, and use docs in `docs/` for workflow guidance.
Use the `coder-tools` and `tools` MCP servers in Antigravity, and use docs in `docs/` for workflow guidance.
---
@@ -90,7 +90,7 @@ Use the `agent-builder` and `tools` MCP servers in Antigravity, and use docs in
```
.agent/
├── mcp_config.json # Template for MCP servers (agent-builder, tools)
├── mcp_config.json # Template for MCP servers (coder-tools, tools)
```
The **setup script** writes your **user** config (`~/.gemini/antigravity/mcp_config.json`) using paths from **this repo**. The file in `.agent/` is the template; Antigravity itself uses the file in your home directory.
@@ -104,7 +104,7 @@ The **setup script** writes your **user** config (`~/.gemini/antigravity/mcp_con
- Run the setup script again from the hive repo root: `./scripts/setup-antigravity-mcp.sh`, then restart Antigravity.
- Make sure Python and deps are installed: from repo root run `./quickstart.sh`.
- Check that the servers can start: from repo root run
`cd core && uv run -m framework.mcp.agent_builder_server` (Ctrl+C to stop), and in another terminal
`cd tools && uv run coder_tools_server.py --stdio` (Ctrl+C to stop), and in another terminal
`cd tools && uv run mcp_server.py --stdio` (Ctrl+C to stop).
If those fail, fix the errors first (e.g. install deps with `uv sync`).
@@ -115,7 +115,7 @@ The **setup script** writes your **user** config (`~/.gemini/antigravity/mcp_con
**MCP tools dont show up in the UI**
- Antigravity may need a restart. Use the files in `docs/` as documentation; the MCP tools (`agent-builder`, `tools`) are the required integration point.
- Antigravity may need a restart. Use the files in `docs/` as documentation; the MCP tools (`coder-tools`, `tools`) are the required integration point.
---
@@ -126,7 +126,7 @@ Paste this into Antigravity to check that MCP is set up. It doesnt use your m
```
Check the Hive + Antigravity integration:
1. MCP: List available MCP servers/tools. Confirm that "agent-builder" and "tools" (or equivalent) are connected. If not, tell the user to run ./scripts/setup-antigravity-mcp.sh from the hive repo root, then restart Antigravity (see docs/antigravity-setup.md).
1. MCP: List available MCP servers/tools. Confirm that "coder-tools" and "tools" (or equivalent) are connected. If not, tell the user to run ./scripts/setup-antigravity-mcp.sh from the hive repo root, then restart Antigravity (see docs/antigravity-setup.md).
2. Docs: Confirm that the project has `docs/` with setup/developer guides for the workflow.
@@ -146,9 +146,9 @@ Save as `~/.gemini/antigravity/mcp_config.json` (Antigravity) or `~/.claude/mcp.
```json
{
"mcpServers": {
"agent-builder": {
"coder-tools": {
"command": "uv",
"args": ["run", "--directory", "/path/to/hive/core", "-m", "framework.mcp.agent_builder_server"],
"args": ["run", "--directory", "/path/to/hive/tools", "coder_tools_server.py", "--stdio"],
"disabled": false
},
"tools": {
@@ -184,7 +184,7 @@ python3 -c "import json; json.load(open('.agent/mcp_config.json')); print('OK: v
```bash
# Terminal 1
cd core && uv run -m framework.mcp.agent_builder_server
cd tools && uv run coder_tools_server.py --stdio
# Terminal 2
cd tools && uv run mcp_server.py --stdio
+8 -8
View File
@@ -20,11 +20,11 @@
| `core/framework/graph/executor.py` | Remove `FunctionNode` import (~L24). Remove `"function"` from `VALID_NODE_TYPES` (~L1473). Remove `node_type == "function"` branch (~L1529-1533). Remove `register_function()` (~L1975-1977). Add migration error for graphs with `node_type="function"`. |
| `core/framework/builder/workflow.py` | Remove `node_type == "function"` validation block (~L258-260). |
### 1.2 Agent Builder MCP server
### 1.2 Builder Package Generator
| File | What to change |
|---|---|
| `core/framework/mcp/agent_builder_server.py` | Remove `"function"` from `node_type` description in `add_node` (~L590) and `update_node` (~L841). Remove `node_type == "function"` simulation branch in `test_node` (~L2356-2357). |
| `core/framework/builder/package_generator.py` | Remove `"function"` from `node_type` description in `add_node` and `update_node`. Remove `node_type == "function"` simulation branch in `test_node`. |
### 1.3 Examples & demos
@@ -56,7 +56,7 @@ Already soft-deprecated with `DeprecationWarning`. No template agent uses them.
|---|---|
| `core/framework/graph/node.py` | Delete `LLMNode` class (~L660-1689, ~1000 lines). Largest single removal. |
| `core/framework/graph/executor.py` | Remove `LLMNode` import. Remove `"llm_tool_use"`/`"llm_generate"` from `VALID_NODE_TYPES`. Remove `DEPRECATED_NODE_TYPES` dict. Remove their branches in `_get_node_implementation` (~L1507-1523). Update `human_input` branch to use `EventLoopNode` instead of `LLMNode`. Add migration error for deprecated types. |
| `core/framework/mcp/agent_builder_server.py` | Remove `llm_tool_use`/`llm_generate` validation warnings and branches (~L668-683, L922-937) |
| `core/framework/builder/package_generator.py` | Remove `llm_tool_use`/`llm_generate` validation warnings and branches |
---
@@ -94,7 +94,7 @@ These tests use `node_type="function"` as convenient scaffolding but actually te
The entire Planner-Worker-Judge pattern has **zero external consumers**. No template agent, example, demo, or runner references it. It is only consumed by:
- Its own internal files (self-referential imports)
- The agent-builder MCP server (exposes tools for it)
- The builder package generator (exposes tools for it)
- Its own dedicated tests
### 5.1 Delete these files entirely
@@ -114,9 +114,9 @@ The entire Planner-Worker-Judge pattern has **zero external consumers**. No temp
`core/framework/graph/__init__.py` — Remove all planner-worker exports: `FlexibleGraphExecutor`, `ExecutorConfig`, `WorkerNode`, `StepExecutionResult`, `HybridJudge`, `create_default_judge`, `CodeSandbox`, `safe_eval`, `safe_exec`, `Plan`, `PlanStep`, `ActionType`, `ActionSpec`, and all related symbols.
### 5.3 Remove MCP tools from agent-builder server
### 5.3 Remove MCP tools from builder package generator
`core/framework/mcp/agent_builder_server.py` — Remove these 7 MCP tools:
`core/framework/builder/package_generator.py` — Remove these 7 MCP tools:
| MCP tool | Description |
|---|---|
@@ -144,7 +144,7 @@ Also remove:
4. **Remove `LLMNode` class + deprecated types** (Part 2)
5. **Delete Planner-Worker subsystem files** (Part 5.1)
6. **Clean up `__init__.py` exports** (Part 5.2)
7. **Remove MCP tools** for plans/evaluation from agent-builder server (Part 5.3)
7. **Remove MCP tools** for plans/evaluation from builder package generator (Part 5.3)
8. **Update examples/demos/docs/skills** (Parts 1.3, 1.4)
9. **Run full test suite** to verify
@@ -157,5 +157,5 @@ Also remove:
3. Load any template agent JSON — no errors
4. Attempt to load a graph with `node_type="function"` — clear `RuntimeError` with migration guidance
5. Attempt to load a graph with `node_type="llm_tool_use"` — clear `RuntimeError` with migration guidance
6. Agent builder MCP: `add_node` with `node_type="function"` — rejected with helpful message
6. Builder package generator: `add_node` with `node_type="function"` — rejected with helpful message
7. Plan/evaluation MCP tools no longer appear in tool list
+4 -4
View File
@@ -116,10 +116,10 @@ MCP (Model Context Protocol) servers are configured in `.mcp.json` at the projec
```json
{
"mcpServers": {
"agent-builder": {
"coder-tools": {
"command": "uv",
"args": ["run", "-m", "framework.mcp.agent_builder_server"],
"cwd": "core"
"args": ["run", "coder_tools_server.py", "--stdio"],
"cwd": "tools"
},
"tools": {
"command": "uv",
@@ -130,7 +130,7 @@ MCP (Model Context Protocol) servers are configured in `.mcp.json` at the projec
}
```
The tools MCP server exposes tools including web search, PDF reading, CSV processing, and file system operations.
The `coder-tools` server provides agent scaffolding via `initialize_agent_package` and related tools. The `tools` MCP server exposes tools including web search, PDF reading, CSV processing, and file system operations.
## Storage
+10 -10
View File
@@ -101,7 +101,7 @@ Get API keys:
./quickstart.sh
```
This sets up agent-builder and tools MCP workflows.
This sets up the MCP tools and workflows for building agents.
### Cursor IDE Support
@@ -117,7 +117,7 @@ MCP tools are also available in Cursor. To enable:
Hive supports [OpenAI Codex CLI](https://github.com/openai/codex) (v0.101.0+).
Configuration files are tracked in git:
- `.codex/config.toml` — MCP server config (`agent-builder`)
- `.codex/config.toml` — MCP server config
To use Codex with Hive:
1. Run `codex` in the repo root
@@ -136,7 +136,7 @@ To enable Opencode integration:
2. Configure MCP servers in `.opencode/mcp.json`
3. Restart Opencode to load the MCP servers
4. Switch to the Hive agent
* **Tools:** Accesses `agent-builder` and standard `tools` via standard MCP protocols over stdio.
* **Tools:** Accesses `coder-tools` and standard `tools` via standard MCP protocols over stdio.
### Verify Setup
@@ -146,7 +146,7 @@ uv run python -c "import framework; print('✓ framework OK')"
uv run python -c "import aden_tools; print('✓ aden_tools OK')"
uv run python -c "import litellm; print('✓ litellm OK')"
# Run an agent (after building one with agent-builder)
# Run an agent (after building one with coder-tools)
PYTHONPATH=exports uv run python -m your_agent_name validate
```
@@ -206,7 +206,7 @@ hive/ # Repository root
│ └── README.md # Tools documentation
├── exports/ # AGENT PACKAGES (user-created, gitignored)
│ └── your_agent_name/ # Created via agent-builder workflow
│ └── your_agent_name/ # Created via coder-tools workflow
├── examples/ # Example agents
│ └── templates/ # Pre-built template agents
@@ -235,7 +235,7 @@ hive/ # Repository root
## Building Agents
### Using Agent Builder Workflow
### Using Coder Tools Workflow
The fastest way to build agents is with the configured MCP workflow:
@@ -244,7 +244,7 @@ The fastest way to build agents is with the configured MCP workflow:
./quickstart.sh
# Build a new agent
Use the agent-builder MCP tools from your IDE agent chat
Use the coder-tools MCP tools from your IDE agent chat (e.g., initialize_agent_package)
```
### Agent Development Workflow
@@ -252,7 +252,7 @@ Use the agent-builder MCP tools from your IDE agent chat
1. **Define Your Goal**
```
Use the agent-builder workflow
Use the coder-tools initialize_agent_package tool
Enter goal: "Build an agent that processes customer support tickets"
```
@@ -555,7 +555,7 @@ uv add <package>
```bash
# Option 1: Use Claude Code skill (recommended)
Use the agent-builder workflow
Use the coder-tools initialize_agent_package tool
# Option 2: Create manually
# Note: exports/ is initially empty (gitignored). Create your agent directory:
@@ -563,7 +563,7 @@ mkdir -p exports/my_new_agent
cd exports/my_new_agent
# Create agent.json, tools.py, README.md (see Agent Package Structure below)
# Option 3: Use the agent builder MCP tools (advanced)
# Option 3: Use the coder-tools MCP tools (advanced)
# See core/MCP_BUILDER_TOOLS_GUIDE.md
```
+8 -8
View File
@@ -165,7 +165,7 @@ Build and run an agent using Claude Code CLI with the agent building skills:
./quickstart.sh
```
This sets up agent-builder and tools MCP workflows.
This sets up the MCP tools and workflows for building agents.
### Cursor IDE Support
@@ -180,7 +180,7 @@ MCP tools are also available in Cursor. To enable:
**Claude Code:**
```
Use the agent-builder workflow
Use the coder-tools initialize_agent_package tool to scaffold a new agent
```
**Codex CLI:**
@@ -361,7 +361,7 @@ hive/
│ └── pyproject.toml
├── exports/ # Agent packages (user-created, gitignored)
│ └── your_agent_name/ # Created via agent-builder workflow
│ └── your_agent_name/ # Created via coder-tools workflow
└── examples/
└── templates/ # Pre-built template agents
@@ -413,10 +413,10 @@ The `.mcp.json` at project root configures MCP servers to run through `uv run` i
```json
{
"mcpServers": {
"agent-builder": {
"coder-tools": {
"command": "uv",
"args": ["run", "-m", "framework.mcp.agent_builder_server"],
"cwd": "core"
"args": ["run", "coder_tools_server.py", "--stdio"],
"cwd": "tools"
},
"tools": {
"command": "uv",
@@ -453,7 +453,7 @@ This design allows agents in `exports/` to be:
### 2. Build Agent (Claude Code)
```
Use the agent-builder workflow
Use the coder-tools initialize_agent_package tool
Enter goal: "Build an agent that processes customer support tickets"
```
@@ -538,7 +538,7 @@ Run the quickstart script in the root directory:
[OpenAI Codex CLI](https://github.com/openai/codex) (v0.101.0+) is supported with project-level config:
- `.codex/config.toml` — MCP server configuration (`agent-builder`)
- `.codex/config.toml` — MCP server configuration
These files are tracked in git and available on clone. To use Codex with Hive:
+4 -4
View File
@@ -47,7 +47,7 @@ This is the recommended way to create your first agent.
# Setup already done via quickstart.sh above
# Start Claude Code and build an agent
Use the agent-builder workflow
Use the coder-tools initialize_agent_package tool
```
Follow the interactive prompts to:
@@ -115,7 +115,7 @@ hive/
│ └── file_system_toolkits/
├── exports/ # Agent Packages (user-generated, not in repo)
│ └── your_agent/ # Your agents created via agent-builder workflow
│ └── your_agent/ # Your agents created via coder-tools workflow
├── examples/
│ └── templates/ # Pre-built template agents
@@ -173,7 +173,7 @@ PYTHONPATH=exports uv run python -m my_agent test --type success
1. **Dashboard**: Run `hive open` to launch the web dashboard, or `hive tui` for the terminal UI
2. **Detailed Setup**: See [environment-setup.md](./environment-setup.md)
3. **Developer Guide**: See [developer-guide.md](./developer-guide.md)
4. **Build Agents**: Use agent-builder workflow in Claude Code
4. **Build Agents**: Use the coder-tools `initialize_agent_package` tool in Claude Code
5. **Custom Tools**: Learn to integrate MCP servers
6. **Join Community**: [Discord](https://discord.com/invite/MXE49hrKDk)
@@ -216,4 +216,4 @@ pip uninstall -y framework tools
- **Documentation**: Check the `/docs` folder
- **Issues**: [github.com/adenhq/hive/issues](https://github.com/adenhq/hive/issues)
- **Discord**: [discord.com/invite/MXE49hrKDk](https://discord.com/invite/MXE49hrKDk)
- **Build Agents**: Use agent-builder workflow to create agents
- **Build Agents**: Use the coder-tools workflow to create agents
+3 -3
View File
@@ -32,7 +32,7 @@ Scan `exports/` for agent packages and `~/.hive/agents/` for runtime data. Retur
### 3-7. Session & Checkpoint Inspection
Ported from `agent_builder_server.py` lines 3484-3856. Pure filesystem reads — JSON + pathlib, zero framework imports.
Ported from the former `agent_builder_server.py`. Pure filesystem reads — JSON + pathlib, zero framework imports.
| Tool | Purpose |
|------|---------|
@@ -40,13 +40,13 @@ Ported from `agent_builder_server.py` lines 3484-3856. Pure filesystem reads —
| `list_agent_checkpoints(agent_name, session_id)` | List checkpoints for debugging |
| `get_agent_checkpoint(agent_name, session_id, checkpoint_id?)` | Load a checkpoint's full state |
**Key difference from agent-builder:** These tools accept `agent_name` (e.g. `"deep_research_agent"`) instead of raw `agent_work_dir` paths. They resolve to `~/.hive/agents/{agent_name}/` internally. Friendlier for the LLM.
**Key difference from the old agent-builder server:** These tools accept `agent_name` (e.g. `"deep_research_agent"`) instead of raw `agent_work_dir` paths. They resolve to `~/.hive/agents/{agent_name}/` internally. Friendlier for the LLM.
### 8. Test Execution
**`run_agent_tests(agent_name, test_types?, fail_fast?)`**
Ported from `agent_builder_server.py` lines 2756-2920. Runs pytest on an agent's test suite, sets PYTHONPATH automatically, parses output into structured results (passed/failed/skipped counts, per-test status, failure details).
Ported from the former `agent_builder_server.py`. Runs pytest on an agent's test suite, sets PYTHONPATH automatically, parses output into structured results (passed/failed/skipped counts, per-test status, failure details).
---
+1 -1
View File
@@ -59,7 +59,7 @@ Full rewrite of account listing and configuration:
---
### Modified: `core/framework/mcp/agent_builder_server.py`
### Modified: `core/framework/builder/package_generator.py`
- `store_credential(name, value, alias="default", ...)` — added `alias` param; now delegates to `LocalCredentialRegistry.save_account()` with auto health check; returns `status` and `identity`
- `list_stored_credentials()` — delegates to `LocalCredentialRegistry.list_accounts()`; returns `credential_id`, `alias`, `status`, `identity`, `last_validated`
+7 -7
View File
@@ -218,7 +218,7 @@ Implement the Goal Creation Session via the Queen Bee and the dynamic Worker Age
- [x] Test case generation
- [x] Test case validation for worker agent
- [x] **Agent Creation Flow**
- [x] Hive Coder reads templates and discovers tools (mcp/agent_builder_server.py)
- [x] Hive Coder reads templates and discovers tools (builder/package_generator.py)
- [x] Generates agent.py, nodes/__init__.py, config.py
- [x] MCP server configuration discovery
- [x] Dynamic tool binding
@@ -330,7 +330,7 @@ Ship essential framework utilities: Node validation, HITL (Human-in-the-loop pau
Port popular tools, and build out the Runtime Log, Audit Trail, Excel, and Email integrations.
- [x] **File Operations (36+ tools)**
- [x] read_file, write_file, edit_file (mcp/agent_builder_server.py)
- [x] read_file, write_file, edit_file (builder/package_generator.py)
- [x] list_directory, search_files
- [x] apply_diff / apply_patch for code modification (tools/file_system_toolkits/)
- [x] data_tools (CSV/Excel parsing)
@@ -435,7 +435,7 @@ Enforce session-local memory isolation to prevent data bleed between concurrent
Implement File I/O support, streaming mode, and allow users to supply custom functions as libraries/nodes.
- [x] **File I/O**
- [x] File read/write operations (mcp/agent_builder_server.py)
- [x] File read/write operations (builder/package_generator.py)
- [x] File system navigation
- [x] Directory listing and search
- [x] **Execution Streaming**
@@ -443,7 +443,7 @@ Implement File I/O support, streaming mode, and allow users to supply custom fun
- [x] Token-by-token output via event bus
- [x] Tool call streaming
- [x] **Custom Tool Integration**
- [x] MCP server discovery (mcp/agent_builder_server.py)
- [x] MCP server discovery (builder/package_generator.py)
- [x] Dynamic tool binding
- [x] Custom tool registration
- [ ] **Streaming Mode Enhancements**
@@ -461,7 +461,7 @@ Implement File I/O support, streaming mode, and allow users to supply custom fun
Add semantic search capabilities and an interactive file system for frontend product integration.
- [x] **File Search**
- [x] search_files tool (mcp/agent_builder_server.py)
- [x] search_files tool (builder/package_generator.py)
- [x] Directory traversal
- [ ] **Semantic Search**
- [ ] Semantic indexing of files
@@ -735,7 +735,7 @@ Ship ~20 ready-to-use templates including GTM Sales, Marketing, Analytics, Train
Build a lightweight local server (e.g., FastAPI or Node) that securely exposes the Hive framework's core Event Bus and Memory Layer to the local browser environment.
- [x] **MCP Server Foundation**
- [x] FastMCP server implementation (mcp/agent_builder_server.py)
- [x] FastMCP server implementation (builder/package_generator.py)
- [x] Agent builder tools exposed
- [x] Port 4001 exposed in Docker
- [x] **Event Bus Architecture**
@@ -802,7 +802,7 @@ Create a UI component to inspect the Shared Memory and Write-Through Conversatio
- [x] **Runtime Logs Tool**
- [x] Inspect agent session logs (tools/runtime_logs_tool/)
- [x] Session state retrieval (mcp/agent_builder_server.py)
- [x] Session state retrieval (builder/package_generator.py)
- [ ] **Memory Inspector UI**
- [ ] Shared Memory visualization
- [ ] Conversation memory view (NodeConversation display)
+1 -1
View File
@@ -22,7 +22,7 @@ template_name/
### Option 1: Build from template (recommended)
Use the agent-builder workflow and select "From a template" to interactively pick a template, customize the goal/nodes/graph, and export a new agent.
Use the `coder-tools` `initialize_agent_package` tool and select "From a template" to interactively pick a template, customize the goal/nodes/graph, and export a new agent.
### Option 2: Manual copy
+2 -3
View File
@@ -721,12 +721,11 @@ $importErrors = 0
$imports = @(
@{ Module = "framework"; Label = "framework"; Required = $true },
@{ Module = "aden_tools"; Label = "aden_tools"; Required = $true },
@{ Module = "litellm"; Label = "litellm"; Required = $false },
@{ Module = "framework.mcp.agent_builder_server"; Label = "MCP server module"; Required = $true }
@{ Module = "litellm"; Label = "litellm"; Required = $false }
)
# Batch check all imports in single process (reduces subprocess spawning overhead)
$modulesToCheck = @("framework", "aden_tools", "litellm", "framework.mcp.agent_builder_server")
$modulesToCheck = @("framework", "aden_tools", "litellm")
try {
$checkOutput = & uv run python scripts/check_requirements.py @modulesToCheck 2>&1 | Out-String
+2 -3
View File
@@ -321,7 +321,7 @@ echo ""
IMPORT_ERRORS=0
# Batch check all imports in single process (reduces subprocess spawning overhead)
CHECK_RESULT=$(uv run python scripts/check_requirements.py framework aden_tools litellm framework.mcp.agent_builder_server 2>/dev/null)
CHECK_RESULT=$(uv run python scripts/check_requirements.py framework aden_tools litellm 2>/dev/null)
CHECK_EXIT=$?
# Parse and display results
@@ -337,8 +337,7 @@ try:
modules = [
('framework', 'framework imports OK', True),
('aden_tools', 'aden_tools imports OK', True),
('litellm', 'litellm imports OK', False),
('framework.mcp.agent_builder_server', 'MCP server module OK', True)
('litellm', 'litellm imports OK', False)
]
import_errors = 0
for mod, label, required in modules:
+1 -1
View File
@@ -49,7 +49,7 @@ Write-Host "Using Python: $PythonCmd" -ForegroundColor Green
Write-Host ""
# Define modules to check
$modules = @("framework", "aden_tools", "litellm", "framework.mcp.agent_builder_server")
$modules = @("framework", "aden_tools", "litellm")
# Benchmark old approach (individual subprocess calls)
Write-Host "Testing OLD approach (individual subprocess calls)..." -ForegroundColor Yellow
+2 -2
View File
@@ -4,7 +4,7 @@
#
# Run from anywhere inside the hive repo. Generates ~/.gemini/antigravity/mcp_config.json
# based on .agent/mcp_config.json template, with absolute paths so the IDE can
# connect to agent-builder and tools MCP servers without manual path editing.
# connect to tools MCP servers without manual path editing.
#
set -e
@@ -56,6 +56,6 @@ fi
echo ""
echo "Next: Restart Antigravity IDE so it loads the MCP config."
echo " Then open this repo; agent-builder and tools should appear."
echo " Then open this repo; tools should appear."
echo ""
echo "For Claude Code, run: $0 --claude"
+64
View File
@@ -1347,6 +1347,70 @@ def validate_agent_package(agent_name: str) -> str:
)
# ── Meta-agent: Package initialization ─────────────────────────────────────
@mcp.tool()
def initialize_agent_package(agent_name: str, agent_json_path: str) -> str:
"""Generate a full Python agent package from an exported agent.json file.
Reads the agent.json (goal, nodes, edges), validates the graph, and
generates all files needed for a runnable agent in exports/{agent_name}/:
config.py, nodes/__init__.py, agent.py, __init__.py, __main__.py,
mcp_servers.json, tests/conftest.py, agent.json, README.md.
Call this INSTEAD of manually writing package files.
Args:
agent_name: Name for the agent package. Must be snake_case (e.g. 'my_agent').
agent_json_path: Path to the exported agent.json file to import.
Returns:
JSON with files written, validation warnings, and next steps.
"""
resolved = _resolve_path(agent_json_path)
if not os.path.isfile(resolved):
return json.dumps({"success": False, "error": f"File not found: {agent_json_path}"})
env = os.environ.copy()
core_path = os.path.join(PROJECT_ROOT, "core")
exports_path = os.path.join(PROJECT_ROOT, "exports")
fw_agents_path = os.path.join(PROJECT_ROOT, "core", "framework", "agents")
pythonpath = env.get("PYTHONPATH", "")
path_parts = [core_path, exports_path, fw_agents_path, PROJECT_ROOT]
if pythonpath:
path_parts.append(pythonpath)
env["PYTHONPATH"] = os.pathsep.join(path_parts)
try:
proc = subprocess.run(
[
"uv", "run", "python", "-m",
"framework.builder.package_generator",
agent_name,
resolved,
],
capture_output=True,
text=True,
timeout=60,
env=env,
cwd=PROJECT_ROOT,
stdin=subprocess.DEVNULL,
)
if proc.returncode == 0:
return proc.stdout.strip() or json.dumps({"success": True})
else:
return json.dumps({
"success": False,
"error": proc.stderr.strip()[:3000],
"stdout": proc.stdout.strip()[:1000],
})
except subprocess.TimeoutExpired:
return json.dumps({"success": False, "error": "Package generation timed out (60s)"})
except Exception as e:
return json.dumps({"success": False, "error": str(e)})
# ── Main ──────────────────────────────────────────────────────────────────