IR
irwinrodriguez.dev
Back to docs

Quick Start

Before this you need FoxAgent installed (Installation). By the end you will have your VFP application running and an agent able to look inside it.

Step 1: check that the Broker is running

The installer left the Broker as a Windows service with automatic start. To check it:

Checking that the Broker service is running
# In PowerShell or CMD:
sc query FoxAgentBroker

# It should say: STATE: 4 RUNNING

If the service is not running, start it from the Windows services console (services.msc) or with this command:

Starting the Broker service by hand
# Start the service by hand:
net start FoxAgentBroker

Step 2: connect your VFP application

The integration is three injection points: register the application at start-up, register your tools right after, and disconnect on the way out. The third one is the one that gets forgotten, and the cost is not yours: it is your customer's.

Connecting the application at start-up and disconnecting on exit
* --- 1. At start-up, once _VFP exists and BEFORE READ EVENTS ---
PUBLIC goBridge
goBridge = CREATEOBJECT("FoxAgent.Bridge")

* Required before Connect: this is what lets the agent look inside.
goBridge.SetInstance(_VFP)

* Connect(id, name, rung) returns a JSON STRING, not a logical.
* Rung 10 (operator) is the business user's rung: the agent reaches
* exactly as far as that person reaches by hand, because everything
* goes through your forms and their validation.
LOCAL lcRes
lcRes = goBridge.Connect("my-app-001", "My VFP Application", 10)
IF !('"ok":true' $ lcRes)
    * If the Broker is stopped or no license seat is free, your
    * application must keep working: FoxAgent is an accessory to it,
    * not a dependency. Log it and carry on.
    goBridge = .NULL.
ENDIF

* The Bridge sends heartbeats by itself every 15 seconds. Do not call
* Heartbeat() manually.

* --- 3. On the way out, in your clean-up routine or ON SHUTDOWN ---
IF VARTYPE(goBridge) = "O" AND !ISNULL(goBridge)
    TRY
        goBridge.Disconnect("my-app-001")
    CATCH
        * A failure here must never stop the application from closing.
    ENDTRY
    goBridge = .NULL.
ENDIF
Disconnect() is not optional An application that never disconnects leaves a FoxAgent thread running while VFP tears itself down, and the user can be shown "Mismatched pushjmp/popjmp call" as they close the program. It also holds the license seat for the full expiry window, so relaunching straight away can be refused with "instance limit reached". This was measured in the field, both ways round, on the same application on the same day. The complete example, with the three points commented, ships as SDK\quickstart.prg.

Step 3: register your tools (UDTs)

One RegisterTool() call per tool, immediately after a successful Connect. Nothing is scanned from disk, and that is the security model rather than a limitation: the agent can only run what you wrote, reviewed and compiled.

Loading the SDK and registering your tools
* The two SDK base classes, before the first CREATEOBJECT of a tool.
* TWO files: FoxAgentTool inherits from FoxToolIsolated, which lives
* in FoxTool.prg. If it is missing you get
* "Class definition FOXTOOLISOLATED is not found".
SET PROCEDURE TO "C:\Program Files\FoxAgent\SDK\FoxTool.prg"      ADDITIVE
SET PROCEDURE TO "C:\Program Files\FoxAgent\SDK\FoxAgentTool.prg" ADDITIVE
SET PROCEDURE TO "MyTools.prg" ADDITIVE

* One call per tool, after Connect.
goBridge.RegisterTool(CREATEOBJECT("FindCustomerTool"))
goBridge.RegisterTool(CREATEOBJECT("CustomerBalanceTool"))

How one of those classes is written is in Configuration. When the logged-in user changes you can rebuild the list with ClearTools() and UnregisterTool(name): which tools exist is your application's decision, per user.

Step 4: connect your AI client

The installer configures Claude Desktop and OpenCode if it finds them. For any other client it leaves the block ready, with the real path already filled in, at C:\Program Files\FoxAgent\mcp-foxagent.json. This is it:

FoxAgent MCP block (mcp-foxagent.json)
{
  "mcpServers": {
    "foxagent": {
      "command": "C:\\Program Files\\FoxAgent\\FoxAgent.McpHost.exe",
      "args": []
    }
  }
}
ClientWhere it goes
Claude Desktopclaude_desktop_config.json (Settings ▸ Developer ▸ Edit config)
Claude Codeclaude mcp add foxagent -- "C:\Program Files\FoxAgent\FoxAgent.McpHost.exe"
Cursor%USERPROFILE%\.cursor\mcp.json
OpenCode%USERPROFILE%\.config\opencode\opencode.jsonc (different format: see its documentation)
Use the path exactly as written Do not shorten it to an 8.3 name. Two FoxAgent executables in that folder collide in 8.3, and the ~1 / ~2 suffix is handed out by creation order: a reinstall can leave your client starting the Broker, which does not speak MCP, and it hangs without telling you why. Spaces are not a problem as long as you double every backslash. Restart the client after editing the configuration.

Step 5: ask

With the Broker running, your application connected and the MCP client configured, the start-up order matters: Broker → your application → the AI client. Try asking:

  • "List the connected VFP instances"
  • "Which forms are open in my-app-001?"
  • "Take a screenshot of the application"
  • "Which custom tools does that instance have registered?"
  • "Look up customer 1042 with the find_customer tool"

The last two work from rung 0. Reading variables and cursors needs rung 20, and raw VFP needs 90: if the agent answers that it cannot, the refusal names the rung it needs and who set the ceiling. The rungs are explained in Configuration.

Next steps

  • Create custom tools (UDTs): The base class, the parameters and the session pattern you must follow to read data
  • Role system: The four rungs, who bounds each one and how your own application raises it