Controlling a Live Coding Environment Using AI – an MCP for Pharo

AI tools are essentially about modifying files and performing requests to APIs to generate even more files. This is one reason why they work so well for editing code: they have access to a vast amount of literature, and they excel at manipulating documents.

However, Smalltalk programming is different. It is much more powerful than traditional programming languages such as Java, TypeScript, Rust, etc., because it is a live programming environment. What is a live programming environment? It means you are coding while the program already exists and is running. You always have access to the state of all objects.

Learn more about this here: https://pharo.org/features

Agent Coding

Some people enjoy what is called agent coding. The UI is no longer the IDE interface, but a chat UX, and they interact only with this window. It hides some of the project's complexity and is easy to use when dealing with several agents working for them.

We will not discuss here whether this is interesting, its impact on code quality, or any other considerations, but rather how to connect this kind of environment to Smalltalk.

Access to Files – The Challenge

In a more traditional context, the AI has access to the files containing the code, the tools to build the project (via terminal commands), the tests, etc. In the Smalltalk context, all these tools are embedded inside the IDE. This is part of what makes Smalltalk so powerful, but less convenient for AI to use.

There are two solutions to make the context accessible to AI: (1) using a tool that creates a virtual file system from a Pharo image (such as a VSCode plugin), or (2) building an API usable by AI to interact with the image, for instance using the MCP protocol.

Let's dive into the second option.

Building an MCP

First of all, we will create a package called MCP and a class named MCP as well. This is always a good start! 😄

Looking at the official documentation, MCP uses the RPC protocol. Hopefully, smalltalk already have a great support of RPC protocol thanks to the JRPC project.

This project allows us to create easily the endpoint required by the MCP protocol. There are actually few endpoints, and we will focus first on what it is called "tool call" that allows an AI to execute function held by a server.

Tools definition will be explain in next section :winking:. To define an endpoint, we create a method in the MCP class.

1rpcToolsList 2 3 <jrpc: #'tools/list'> 4 ^ {(#tools -> toolsList values asArray)} asDictionary asJRPCJSON

Note the <jrpc: #'tools/list'>. It is the declaration of the endpoint for the JRPC framework of Pharo. The tool list is then transmited.

For tool call, the code is not complex too.

1rpcToolCall: name withParams: arguments 2 3 <jrpc: #'tools/call'> 4 toolsList 5 at: name 6 ifPresent: [ :tool | 7 ^ (MCPStructureCallToolResult content: 8 (tool executeWithArguments: arguments)) asJRPCJSON ] 9 ifAbsent: [ ToolNotFound signal ]

We retrieve again the <jrpc: #'tools/call'> for the endpoint definition. MCPStructureCallToolResult is used to define the response to the AI. It is basically a DTO object.

Defining tools

Thus, building an MCP server using smalltalk technology is trivial. The most important part is about building tool. Again, tool are not complex object, they basically have a name, a description, inputs and output schemas, and the code that need to be executed. To represent the tools, one can create an abstract structure representing the tools, and then create concretes one with relative code.

This is what I did 😄. And you do not need many tools to interact with a coding environment. For now, I made 7 tools: get_packages, get_package_class, pharo_read_class, pharo_eval, pharo_execute_class_test, pharo_execute_all_class_test, pharo_create_package.

The names of the tools are safe explaning, however, I'd like to highlight one major tool: pharo_eval. This tool allows the AI to execute any piece of Pharo code. And Pharo is a living environment. So, you can to everything using only this command. You can debug code, you can test program, you can create classes. Other tools act as helper for the (AI) user but are unnecessary.

What's next

We have built an MCP server that enable AI to interact with Pharo. For instance, codex can now create code in smalltalk. And we do not need to build an inner tool, but to use the same.

You want to use it, it is easy: download the project and give it a try.

And from issues, we can build documentation to give to AI so it can even more easily understand how to manipulate smalltalk environment with dedicated AI documentation.