VEX AIM MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| AIM_HOST | No | The robot's address (the default is its own hotspot) | 192.168.4.1 |
| AIM_HTTP_PORT | No | HTTP mode: the port | 8000 |
| AIM_YOLO_MODEL | No | YOLO weights (downloaded on first use) | yolo26n.pt |
| AIM_HTTP_SECRET | No | HTTP mode: the secret part of the address | |
| AIM_MAX_MOVE_MM | No | Longest single move | 1000 |
| AIM_PANEL_SETUP | No | Where the panel saves its set-up | |
| AIM_LIVE_VIEW_PORT | No | The control panel's port | 8765 |
| AIM_MAX_SPEED_PERCENT | No | Cap on driving and turning speed (100% is 200 mm/s or 180°/s) | 60 |
| AIM_IDLE_DISCONNECT_MIN | No | Let go of the robot after this many idle minutes (0 = never) | 10 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| robot_statusA | Battery, heading, position, tilt, whether it's moving or playing sound, what the kicker seems to hold, and what the robot's onboard AI vision sees right now. Connects if needed. "holding" relies on the onboard AI, which often misses a held ball in dim light; use look(). |
| lookA | Take a photo with the robot's front camera and see it yourself. Objects the robot's onboard AI recognises (sports balls, blue/orange barrels, AIM robots, AprilTags) are listed with their bearing. For anything else, read its bearing off the ruler along the top of the photo. |
| detect_objectsA | List what the robot can see, with bearings, without fetching a photo. |
| control_panelA | Open (or close) the control panel: a web page on this computer with the robot's live camera and detection boxes, team buttons, object labelling, colour teaching, a STOP button, a top-down map and a log of what the person, you and the robot do. If your app has a built-in browser, show the URL there; otherwise give the person the link, or set open_browser. What the person chooses there is shared with you: see robot_status().panel and wait_for("panel"). |
| enable_motionA | Unlock move, turn, turn_to_heading, face_object and kick for this connection. Motion starts locked every time the robot connects, because it may be sitting on a table. Ask the user first; never call this on your own initiative. |
| moveA | Drive a set distance in any direction, then stop. Waits until it has finished. Stops early if the robot bumps into something. |
| turnA | Spin on the spot by an angle, then stop. To face something seen in look(), turn by its bearing. |
| turn_to_headingA | Spin on the spot to face an absolute heading. |
| face_objectA | Find an object with the robot's onboard AI vision and turn to face it. Works for what the onboard AI knows (sports balls, blue and orange barrels, other AIM robots, AprilTags), labelled objects, and colours taught with teach_colour or the control panel. |
| scan_surroundingsA | Turn a full circle on the spot, noting the heading of every object the onboard AI recognises (sports balls, barrels, AIM robots, and AprilTags once switched on) and where each goal (a pair of same-coloured barrels) is centred, then face the starting direction again. Use the headings with turn_to_heading, approach_object or shoot_at_goal. |
| set_teamA | Choose the robot's team at the start of a goal game. Like VEX alliances, a team scores in the goal of its own colour: between the two barrels of that colour. (The person can also pick the team in the control panel.) |
| shoot_at_goalA | Score with the ball the robot is holding: find the goal (two barrels of one colour), turn so the ball passes between them, kick, and back away. Get the ball into the kicker first (approach_object) and confirm with look(). Returns a photo taken after the kick. |
| approach_objectA | Drive up to an object the onboard AI can see, re-aiming before every short step, until it's in the kicker (whose magnet then holds balls and barrels). Give a target kind or the label of an object or taught colour. If it isn't in view, use face_object or scan_surroundings first. The onboard AI often loses a ball in the last ~10 cm, so the robot finishes that part on an estimate. Unless the AI confirms the object is in the kicker, the result includes a photo: check it before kicking. |
| stopA | Stop all motion immediately, including an exploration or experiment in progress. Always allowed, even while motion is locked. |
| kickA | Fire the kicker at whatever it's holding ("soft" gently pushes or places it), then back away. Aim at open space first, since balls bounce off things, and make sure no one is in the way. Use look() to check something is in the kicker. |
| explore_arenaA | Map the arena by driving around it. It scans a full circle, then visits spots across the field chosen in the control panel (a grid 30 cm in from the edges), scanning at each. It drives around obstacles and anything already on the map (skipping a spot only if there's no way round), and stops on a bump. Without a field it only scans where it is. Takes a few minutes; the person can press STOP in the panel. Afterwards, robot_status().panel.map lists what it found. |
| test_kickA | Experiment: kick the ball in the kicker straight ahead and watch it roll, to measure how far this strength sends it. Point the robot at open floor first. The distance is saved when the ball stops in view. If it rolls out of the camera's range, ask the person to measure where it stopped and call record_kick_distance. Results build up in robot_status().panel.abilities. |
| record_kick_distanceB | Save a kick distance someone measured (e.g. after test_kick lost sight of the ball). |
| test_speedB | Experiment: drive straight ahead a measured distance and time it, to find the robot's top speed at this speed setting and how quickly it gets up to speed. Needs that much clear floor ahead. |
| fetch_ballA | Get the ball into the kicker by itself: find it (in view, on the control panel's map, or by turning to look around), drive to just short of it around obstacles and anything on the map, then creep up on it with the camera. Unlike approach_object, the ball needn't be in view. The onboard AI often loses the ball in the last ~10 cm; if the result says it can't confirm the ball is held, check with look(). STOP ends it. |
| score_goalA | Score by itself from anywhere: fetch the ball if the camera sees it elsewhere, find the goal (two barrels of the team's colour, from the map or by looking around), dribble closer if no measured kick would score from here, line up between the posts, kick with the gentlest measured strength that scores, and back away. Only uses kick strengths measured with test_kick; with none, it dribbles to 30 cm and kicks soft. shoot_at_goal instead kicks from where the robot stands. Make sure nobody is near the goal. |
| pass_ballA | Kick the ball to a spot on the field (mm, as in robot_status().panel.map: on a field (0, 0) is its centre, x right, y up the field) with the gentlest measured kick that gets there, fetching it first if needed and dribbling closer if no measured kick reaches. Refuses if something on the map is in the ball's way. |
| go_toA | Drive to a spot (field mm when a field is chosen in the control panel, otherwise from where the robot connected) around obstacles and anything on the map, finishing within a few cm; optionally face heading_deg (0 = up the field) at the end. Refuses spots off the field or within 10 cm of its walls. |
| guard_goalB | Play goalkeeper for a while: stand 25 cm in front of the goal the other team scores in (each team scores in its own colour's goal, so the blue team guards the orange goal), facing up the field, and slide sideways to stay between the ball and the goal's centre, never past a post. Ends early if it catches the ball. |
| team_listA | The robots on the team list: each player's name, team, robot address, whether it's connected, battery, and where it is on the field. "selected" is the one the tools and the control panel act on; use select_player to switch. Also which other robots the selected one can see, and whether each is a teammate, an opponent or unknown. |
| select_playerA | Make another player's robot the one the tools (and the control panel) act on. Motion starts locked on each robot: ask the person to confirm that robot is on the floor before enable_motion. |
| add_playerA | Put another AIM robot on the team list, by its player name and IP address (the robot shows its IP on its screen under Settings → Radio; the control panel's Network menu can find robots too). |
| adviseA | Strategy advice without moving: fetch, shoot, pass or dribble, and why, with the numbers behind it (distance to the goal, how far each measured kick rolls, how long the ball takes to roll there versus driving, whether the path is clear, where to dribble to). holding defaults to what the onboard AI sees, which often misses a held ball, so confirm with look(). teammates_mm: [[x, y], …] of teammates to pass to. |
| wait_forA | Watch the robot about 10 times a second and return the moment something happens, instead of checking over and over. Returns what happened (with bearings), or that it timed out. |
| teach_colourA | Teach the robot's onboard AI to detect a colour, sampled from part of the current camera view (for example a cup you spotted in a look() photo). The robot then tracks it by itself, many times a second, and its name works as a label in approach_object, face_object and wait_for. This is the colour signature from VEXcode's AI Vision Utility; the robot holds 7. |
| reset_positionA | Make the current heading 0° and the current position (0, 0). |
| set_lightsB | Set the colour of the robot's ring of six lights. |
| show_emojiB | Show one of the robot's animated faces on its screen ("none" hides it). |
| show_textB | Write text on the robot's 240x240 screen, replacing whatever was there. Long lines wrap. |
| reactA | Show the player card on the robot's screen: a small face with this expression, the player's name and team colour (from the control panel), and its lights in the team colour. Use it in games: excited after a goal, sad after a miss, wink after a good pass, surprised after a bump. It goes back to the resting face after a few seconds. |
| play_soundC | Play one of the robot's built-in sounds. |
| play_notesA | Play a tune on the robot's speaker and wait for it to finish (30 seconds at most). |
| sayB | Speak out loud through the robot's speaker, using this Mac's text-to-speech. |
| connect_robotA | Connect, or reconnect, to the robot. Other tools connect automatically, so this is only needed to switch robots or to recover after the connection dropped. |
| disconnect_robotA | Release the robot so VEXcode or a Python script can use it. Tools reconnect automatically. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 40 tools
The set has real clusters of overlap: kick/shoot_at_goal/score_goal/pass_ball/test_kick all concern kicking, and approach_object/fetch_ball both acquire balls, while look/detect_objects/robot_status all report vision. However, descriptions actively cross-reference each other (e.g. 'unlike approach_object', 'shoot_at_goal instead kicks from where the robot stands'), so an agent can usually choose correctly.
Nearly everything is snake_case verb-first or verb_noun (move, turn, face_object, go_to, kick, pass_ball, set_team, teach_colour, add_player), which is predictable and readable. A few noun-first outliers (robot_status, team_list, control_panel) and bare imperatives (look, say, react, advise) deviate slightly without breaking comprehension.
40 tools is heavy and exceeds the comfortable range, though the domain is genuinely broad (motion, vision, audio, display, team play, experiments, strategy). Several functions could plausibly be consolidated (test_kick/test_speed/record_kick_distance, the multiple display tools), so it sits at the crowded end of reasonable.
The surface covers the full lifecycle: connection, motion and aiming, vision, ball handling, scoring, passing, goalkeeping, mapping, experiments, team roster management, TTS/sound/lights/screen, plus strategy advice and event waiting. No obvious dead ends or missing operations are apparent for a robot-control agent.