Release v0.2.23 · cybersonic/LuCLI

Another big release of LuCLI,

Added some more installers, fixed some bugs and more importantly sprinkled some AI magic all over the place.

You can now use modules as MCP servers, so for example, you can do:

#install the bitbucket module
lucli install bitbucket

Then in your fave client add the MCP server like:

{
  "mcpServers": {
    "bitbucket": {
      "args": ["mcp", "bitbucket"],
      "command": "lucli",
      "env": {
        "BITBUCKET_AUTH_TOKEN": "ATATT3xxxx",
        "BITBUCKET_AUTH_USER": "mark@example.com"
      },
      "working_directory": null
    }
  }
}

You can now also prompt with ease, (remember ALPHA version so feel free to let me know of issues?!?)

lucli ai prompt --text "How much wood would a wood chuck cut if a wood chuck would chuck wood?

Also added backing up of the system! Just in case!

Also in preivous version added runtimes and even added a Jetty runtime.

Have fun!

2 Likes

Hi Mark

This looks really interesting.

We use CFHTTP to connect to our NodeJS + Bedrock MCP Host/Client/Server.
What advantages does LuCLI add over our set-up?
Is the LuCLI a CommandBox like alternative?
I am kind of interested in the MCP server side of things?
Have you managed to create a an MCP server using Coldfusion?

I have found that I needed to use NodeJs to do this part, because of the amazing library:

@modelcontextprotocol

I am not sure what your setup is but, to give some background.

  1. LuCLI is meant to be the Swiss Army knife of tools for Lucee. So it is comparative to the great work Ortus has done with Commandbox, just very Lucee-only focussed.
  2. Modules in LuCLI are command line tools, so I built a Bitbcuket CLI tool for our CI/CD pipelines as a LuCLI module: GitHub - cybersonic/lucli-bitbucket: A bitbucket module for lucli · GitHub (I have also built A Linter and [Markspresso](https://markspresso.org/ - a static site generator I use for the docs and my blog)
  3. I needed an MCP connection to Bitbucket, I didnt want to drop out to other tools and still wanted to re-use some of the specific commands I have in Bitbucket Module
  4. I realised that exposing modules as MCP (JSON-RCP) makes sense to me, since we also have a daemon and LSP protocols enabled for other tooling (lucli daemon --port 10000 and lucli daemon --port 5000 --lsp)
  5. This makes making MCP clients a breeze and even better, using them and testing them is a breeze since they are literally command line tools anyway

Does that make some sense with regards to the why?

Whatever you do in the modile to connect to some CFML based server is up to the module , whether you are using rest or direct webservices (which If I recall Lucee ↔ Lucee webservices are pretty fast)

1 Like

Thank you for the comprehensive reply.

I am wondering whether you are only using stdio MCP?

Currently, the different kind of protocols for MCP, are the following:

  1. Standard Input/Output (STDIO)
  2. Streamable HTTP (the modern standard)
  3. Server-Sent Events (SSE) (for legacy use)

We are using:

Server-Sent Events (SSE)

Via a NodeJs application, which consists of:

MCP Host
MCP Client
MCP Server

Here is the flow:

  1. Lucee Application Server: CFML template →
  2. MCP Host →
  3. MCP Client →
  4. MCP Server [sends schema to Bedrock] →
  5. MCP Client →
  6. MCP Host →
  7. Amazon Bedrock - [Bedrock analyses the schema and chooses a prompt/tool etc and the. sends back the LLM response] →
  8. MCP Host →
  9. Lucee Application Server: CFML template

I am wondering at which point I can use your system?

I have a feeling it might be at 3, where I ingest an MCP server-config.json config

{
    "kahootz": {
        "command": "node",
        "args": [
            "C:\\PATH_TO_SERVER\\server\\build\\app\\index.js",
            "http://localhost:3001/mcpserver/sse"
        ]
    }
}

Maybe this image makes it clearer? Forget the left side of the image. Our flow starts with a Coldfusion template [top right hand side]

I am not quite sure why you are sending your BitBucket module to your MCP server?
What is the purpose of your BitBucket module? And when you say module, how would you define this? Is it Coldfusion based?

100% lucli modules are of course written in cfml

Sorry. Are we talking about CFMODULE, or is this a special Lucee construct.
We are still on Lucee 5.4, so maybe this isn’t available to us yet?

Mark forgot to include a link to the wonderful documentation he’s put together!

https://lucli.dev/docs/

2 Likes

Ahhhh. Now everything is a little clearer.

So, I now understand how to interact with a module, using LuCLI, but it would be great if I could see a real world example of an actual module.

There wasn’t much documentation about the CFC itself, so I am assuming they are just standard CFCs.

I am still thinking back to when Mark wrote:

{
  "mcpServers": {
    "bitbucket": {
      "args": ["mcp", "bitbucket"],
      "command": "lucli",
      "env": {
        "BITBUCKET_AUTH_TOKEN": "ATATT3xxxx",
        "BITBUCKET_AUTH_USER": "mark@example.com"
      },
      "working_directory": null
    }
  }
}

This would suggest that BitBucket is an MCP server and LuCLI can interact with it via Stdio. The second ARG here is the MCP server target, as far as I can remember?

@markdrew Would I be able to see your BitBucket module.
I am intrigued to see how it is used, as an MCP server?

I had a look at:

But I didn’t see any CFCs in there. It would be great if you could add an MCP example, in the examples folder.
This would act as both a module & an MCP example, all in one go. :wink:

1 Like

Not sure from where I bookmarked but halfway through is an intro to LuCLI by @markdrew https://www.youtube.com/watch?v=qN-BGkpcAaM

Heya!
Sorry for the late reply, been a bit swamped!

So some clarification, the bitbucket lucli module connects to the bitbcuket api, it’s just a nice way for me to be able to do :

bitbucket pullrequests_approve --pullrequestid=${BITBUCKET_PR_ID} --workspace=${BITBUCKET_WORKSPACE} --repoSlug=${BITBUCKET_REPO_SLUG} --authtoken=${BITBUCKET_AUTH_TOKEN}

In Claude/Cursor/Warp et al you can define MCP “servers” , it’s very loose term.

So what lucli can do is EXPOSE a module and it’s methods as a tools for the mcp client to use.

You can checkout the repo for the module here: GitHub - cybersonic/lucli-bitbucket: A bitbucket module for lucli · GitHub

But TL;DR:
~/.lucli/modules/mymodule/Module.cfc

component extends="modules.BaseModule" {

  function hello(name="Elvis"){
    return `Hello #arguments.name#!`;
  }

  function goodbye(name="Elvis"){
    return `Goodbye #arguments.name#!`;
  }

}

can be then called via:

lucli mymodule hello name="Mark"

and

lucli mymodule goodbye name="Mark"

There is some docs here on getting started with modules: Module Development - LuCLI Documentation

Now back to the MCP “server”. Lucli starts a daemon to listen to JSON-RCP via stdio from your client and then talk to the bitbucket server.

The module is not a server per se, so you dont get a URL as you would with hosted MCP’s

Hope that helps!

1 Like