Working with MCP resources

Resources provide context to models provided by the MCP server.

In this example, we will work with a Postgres database that you are expected to have manually and an MCP server that exposes it (read-only) to the LLM.

dbString := 'postgresql://postgres:mysecretpassword@localhost/mydb'.

process := (GtExternalProcessBuilder new: 'npx')
		args: {'@modelcontextprotocol/server-postgres'. dbString};
		pipeStdin;
		pipeStdout;
		pipeStderr;
		spawn
  

Once we’ve established the process, we can start the client.

mcpClient := GtMcpClient new
		transport: (GtMcpStdioTransport new process: process)
  

This particular server provides one resource per database table. To query the structure of a table named my_table we would write:

resource := mcpClient readResource: 'postgres://postgres@localhost/my_table/schema'.

"to get to the text directly"
tableDescription := resource first at: 'text'
  

Now we could, for instance, provide this description to the LLM before asking it to query the table using the query tool provided by the server.

chat := GtLlmChat new.

mcpClient llmFunctionTools do: [:aTool | chat provider addTool: aTool].

chat addMessage: (GtLlmUserMessage new content: 'Description of `my_table`:

', tableDescription).

chat sendMessage: '`Query all contents of `my_table` and summarize them for me.'