A Flask-based REST API for controlling a robotic arm in a blocks world simulation environment.
http://127.0.0.1:5001
All endpoints return responses in the following format:
{
"result": "response_data"
}Success responses return HTTP status 200, while errors return HTTP status 400.
{
"result": "Simulation started successfully"
}{
"result": "Could not pick up block A - Block A is not clear"
}The simulation supports different constraint sets that define the rules for block manipulation:
base(default): Standard blocksworld rules with limited ground positionsblock_size: Blocks with varying sizes - blocks can only be placed on larger or equal-sized blockspartial_observability: Limits the visibility of the simulation state (use/get_full_statusto bypass)
The active constraint set can be specified when starting a simulation with a scenario or custom configuration.
- Block names must be single uppercase letters (A-Z)
- All POST endpoints validate request data using Pydantic models
Starts the simulation with either a predefined scenario or custom configuration.
Endpoint: POST /start_simulation
Request Body (Optional):
{
"scenario_id": "scenario_name"
}OR
{
"initial_stacks": [["A", "B"], [], ["C"]],
"constraint_set": "constraint_set_name"
}OR
{
"initial_stacks": [
[
{"name": "D", "x_size": 100, "y_size": 30},
{"name": "C", "x_size": 80, "y_size": 30}
],
[],
[]
],
"constraint_set": "block_size"
}cURL Example:
curl -X POST http://127.0.0.1:5001/start_simulation \
-H "Content-Type: application/json" \
-d '{"scenario_id": "simple_tower"}'Success Response:
{
"result": "Simulation started successfully"
}Error Response:
{
"result": "Could not start simulation - Unknown scenario"
}Stops the current simulation.
Endpoint: POST /stop_simulation
cURL Example:
curl -X POST http://127.0.0.1:5001/stop_simulationQuits the entire application.
Endpoint: POST /quit
cURL Example:
curl -X POST http://127.0.0.1:5001/quitPicks up a block from the ground or stack.
Endpoint: POST /pick_up
Request Body:
{
"block": "A"
}cURL Example:
curl -X POST http://127.0.0.1:5001/pick_up \
-H "Content-Type: application/json" \
-d '{"block": "A"}'Puts down a held block on the ground.
Endpoint: POST /put_down
Request Body:
{
"block": "A"
}cURL Example:
curl -X POST http://127.0.0.1:5001/put_down \
-H "Content-Type: application/json" \
-d '{"block": "A"}'Stacks block1 on top of block2.
Endpoint: POST /stack
Request Body:
{
"block1": "A",
"block2": "B"
}cURL Example:
curl -X POST http://127.0.0.1:5001/stack \
-H "Content-Type: application/json" \
-d '{"block1": "A", "block2": "B"}'Unstacks block1 from block2.
Endpoint: POST /unstack
Request Body:
{
"block1": "A",
"block2": "B"
}cURL Example:
curl -X POST http://127.0.0.1:5001/unstack \
-H "Content-Type: application/json" \
-d '{"block1": "A", "block2": "B"}'Executes a sequence of actions as a plan. The plan is executed in the GUI with visual animation of the robot's movements.
Endpoint: POST /execute_plan
Request Body:
{
"plan": [
{
"action": "pick_up",
"block": "A"
},
{
"action": "stack",
"block1": "A",
"block2": "B"
},
{
"action": "unstack",
"block1": "A",
"block2": "B"
},
{
"action": "put_down",
"block": "A"
}
]
}Available Actions:
pick_up: Requiresblockparameterput_down: Requiresblockparameterstack: Requiresblock1andblock2parametersunstack: Requiresblock1andblock2parameters
cURL Example:
curl -X POST http://127.0.0.1:5001/execute_plan \
-H "Content-Type: application/json" \
-d '{"plan": [{"action": "pick_up", "block": "A"}, {"action": "put_down", "block": "A"}]}'Verifies a plan without executing it. The verification runs in the background without GUI animation and doesn't modify the actual simulation state. It checks if each action in the plan would be valid when executed sequentially.
Endpoint: POST /verify_plan
Request Body: Same format as execute_plan
cURL Example:
curl -X POST http://127.0.0.1:5001/verify_plan \
-H "Content-Type: application/json" \
-d '{"plan": [{"action": "pick_up", "block": "A"}]}'Success Response:
{
"result": "Simulation plan is verified and can be executed."
}Error Response (Invalid Plan):
{
"result": "Plan is invalid: Step 2: action='stack' block1='A' block2='B' Reason: Block B is not clear"
}Returns the current simulation status including all block positions, stack configurations, and robot state. When using the partial_observability constraint set, this endpoint respects visibility rules and may return limited information.
Endpoint: GET /get_status
cURL Example:
curl -X GET http://127.0.0.1:5001/get_statusResponse Example:
{
"result": {
"stacks": [
{
"number": 1,
"blocks": [
{"name": "A", "x_size": 100, "y_size": 60, "position": 0},
{"name": "B", "x_size": 100, "y_size": 60, "position": 1}
]
},
{
"number": 2,
"blocks": []
},
{
"number": 3,
"blocks": [
{"name": "C", "x_size": 100, "y_size": 60, "position": 0}
]
}
],
"robot": {
"state": "idle",
"held_block": null
}
}
}Robot States:
idle: Robot is not holding any blockholding: Robot is holding a block (checkheld_blockfor the block name)
Returns the complete simulation status, bypassing any partial observability constraints. This endpoint is useful when you need full visibility of the simulation state regardless of the active constraint set.
Endpoint: GET /get_full_status
cURL Example:
curl -X GET http://127.0.0.1:5001/get_full_statusResponse Example:
{
"result": {
"stacks": [
{
"number": 1,
"blocks": [
{"name": "A", "x_size": 100, "y_size": 60, "position": 0},
{"name": "B", "x_size": 100, "y_size": 60, "position": 1}
]
},
{
"number": 2,
"blocks": []
},
{
"number": 3,
"blocks": [
{"name": "C", "x_size": 100, "y_size": 60, "position": 0}
]
}
],
"robot": {
"state": "idle",
"held_block": null
}
}
}Note: This endpoint was added to bypass partial observability limitations. Use /get_status for standard queries that respect constraint set rules, or /get_full_status when you need complete state information.
Returns the general blocksworld rules, including current constraint rules for the active constraint set in markdown format. This provides a human-readable description of all rules and constraints that apply to the current simulation.
Endpoint: GET /get_rules
cURL Example:
curl -X GET http://127.0.0.1:5001/get_rulesResponse Example:
{
"result": "# Blocksworld Environment Rules\n## Overview\nThe blocksworld is a classic AI planning domain...\n\n## Available Actions\nUse the provided MCP tools for block manipulation actions."
}The response contains markdown-formatted text describing:
- Environment rules (blocks, stacks, robot capabilities)
- Ground position constraints
- Robot and block states
- Planning constraints
- Goal specification format
- Available actions
Lists all available predefined scenarios with their complete configuration including initial state, goal, and optimal plans.
Endpoint: GET /scenarios
cURL Example:
curl -X GET http://127.0.0.1:5001/scenariosResponse Example:
{
"result": {
"scenarios": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "1_5",
"description": null,
"initial_state": {
"stacks": [["A", "B"], ["C"], []],
"holding": null,
"robot_status": "idle"
},
"goal": {
"description": "Build tower B-A-C from bottom to top.",
"target_configurations": [[], [], ["B", "A", "C"]]
},
"constraint_set": "base",
"metadata": {
"category": "1",
"min_known_steps": 6,
"non_constructive_steps": 0,
"num_blocks": 3,
"num_stacks": 3,
"misplaced_blocks": 3
},
"optimal_plan": [
{"action": "unstack", "block1": "B", "block2": "A"},
{"action": "put_down", "block": "B"},
{"action": "pick_up", "block": "A"},
{"action": "stack", "block1": "A", "block2": "B"},
{"action": "pick_up", "block": "C"},
{"action": "stack", "block1": "C", "block2": "A"}
]
}
]
}
}Scenario Fields:
id: Unique identifier (UUID) for the scenarioname: Human-readable name (format:<category>_<number>, e.g.,2_9)description: Brief description of the challengeinitial_state: Starting configuration (stacks, robot state)goal: Target configuration to achieveconstraint_set: Which constraint set to use (base,block_size, orpartial_observability)metadata: Additional information about the scenario:category: Difficulty category (1-5, where higher numbers indicate more complex scenarios)min_known_steps: Minimum number of steps required for known optimal solutionnon_constructive_steps: Number of auxiliary/intermediate steps needed (steps that don't directly contribute to the goal)num_blocks: Total number of blocks in the scenarionum_stacks: Total number of stacks availablemisplaced_blocks: Number of blocks not in their goal position
optimal_plan: A known optimal solution (can be used for validation or as a reference)
Gets details for a specific scenario by name or ID.
Endpoint: GET /scenarios/<scenario_name_or_id>
Parameters:
scenario_name_or_id: Can be either the scenario's unique ID (UUID) or its name
cURL Examples:
# By name
curl -X GET http://127.0.0.1:5001/scenarios/Tower%20Building%20Challenge
# By ID
curl -X GET http://127.0.0.1:5001/scenarios/550e8400-e29b-41d4-a716-446655440000Response Example:
{
"result": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "1_5",
"description": null,
"initial_state": {
"stacks": [["A", "B"], ["C"], []],
"holding": null,
"robot_status": "idle"
},
"goal": {
"description": "Build tower B-A-C from bottom to top.",
"target_configurations": [[], [], ["B", "A", "C"]]
},
"constraint_set": "base",
"metadata": {
"category": "1",
"min_known_steps": 6,
"non_constructive_steps": 0,
"num_blocks": 3,
"num_stacks": 3,
"misplaced_blocks": 3
},
"optimal_plan": [
{"action": "unstack", "block1": "B", "block2": "A"},
{"action": "put_down", "block": "B"},
{"action": "pick_up", "block": "A"},
{"action": "stack", "block1": "A", "block2": "B"},
{"action": "pick_up", "block": "C"},
{"action": "stack", "block1": "C", "block2": "A"}
]
}
}Error Response (Scenario Not Found):
{
"result": "Could not retrieve scenario information - Unknown scenario"
}"Could not start simulation - Unknown scenario": The specified scenario ID does not exist"Could not start simulation - Invalid constraint set": The specified constraint set is not available"Could not start simulation - Simulation is already running": A simulation is already active
"Could not pick up block A - Block A is not clear": Another block is stacked on top of block A"Could not pick up block A - Robot is already holding a block": Robot must put down current block first"Could not pick up block A - Block A does not exist": Block A is not in the simulation"Could not put down block A - Robot is not holding block A": Robot must be holding the specified block"Could not put down block A - No available ground positions": All ground positions are occupied"Could not stack block A on block B - Robot is not holding block A": Must pick up block A first"Could not stack block A on block B - Block B is not clear": Another block is already on top of B"Could not unstack block A from block B - Block A is not on top of block B": Blocks are not in specified configuration"Could not unstack block A from block B - Block A is not clear": Another block is on top of A
"Plan is invalid at step N - <error message>": The plan fails at the Nth action with the specified error"Invalid action type in plan": An unrecognized action type was specified in the plan"Missing required parameters for action": Action is missingblock,block1, orblock2parameters
When using the block_size constraint set:
"Could not stack block A on block B - Block cannot be stacked on a smaller block": Violates size constraint rule
# 1. Start with a specific scenario
curl -X POST http://127.0.0.1:5001/start_simulation \
-H "Content-Type: application/json" \
-d '{"scenario_id": "1_5"}'
# 2. Get the scenario details to see the optimal plan
curl -X GET http://127.0.0.1:5001/scenarios/1_5
# 3. Execute the optimal plan from the scenario
curl -X POST http://127.0.0.1:5001/execute_plan \
-H "Content-Type: application/json" \
-d '{
"plan": [
{"action": "unstack", "block1": "B", "block2": "A"},
{"action": "put_down", "block": "B"},
{"action": "pick_up", "block": "A"},
{"action": "stack", "block1": "A", "block2": "B"},
{"action": "pick_up", "block": "C"},
{"action": "stack", "block1": "C", "block2": "A"}
]
}'# Verify a plan to check if it would work
curl -X POST http://127.0.0.1:5001/verify_plan \
-H "Content-Type: application/json" \
-d '{
"plan": [
{"action": "pick_up", "block": "A"},
{"action": "stack", "block1": "A", "block2": "B"}
]
}'
# If valid, execute it
curl -X POST http://127.0.0.1:5001/execute_plan \
-H "Content-Type: application/json" \
-d '{
"plan": [
{"action": "pick_up", "block": "A"},
{"action": "stack", "block1": "A", "block2": "B"}
]
}'curl -X POST http://127.0.0.1:5001/start_simulation \
-H "Content-Type: application/json" \
-d '{
"initial_stacks": [
[
{"name": "C", "x_size": 120, "y_size": 30},
{"name": "B", "x_size": 100, "y_size": 30},
{"name": "A", "x_size": 80, "y_size": 30}
],
[],
[]
],
"constraint_set": "block_size"
}'