Share My Creation Model Context Protocol (MCP) Server using Stdio

B4J MCP Server using Standard Input/Output (stdio).
It demonstrates a small inventory system storing data in an SQLite database.

There are 2 tools available
  • get_inventory: to list the available products
  • add_product: add new product to inventory
You can use Claude desktop as a client to test this MCP Server.

1765386143223.png

Github: https://github.com/pyhoon/mcp-server-b4j

Sample claude_desktop_config.json attached.
 

Attachments

  • b4j_mcp_server.zip
    5 KB · Views: 21
Last edited:

aeric

Expert
Licensed User
Longtime User
We can simulate the "Client" by simply running the B4J app and typing these JSON strings into the console to test it.
Build the app in release and test using the following input in cmd:

1. Handshake (Initialize): Client sends:
JSON:
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "TestClient", "version": "1.0"}}}
Server replies: Lists capabilities and server info.

2. List Tools: Client sends:
JSON:
{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
Server replies: JSON defining get_inventory and add_product.

3. Call Tool (Query Database): Client sends:
JSON:
{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "get_inventory", "arguments": {}}}
Server replies: A JSON list of your SQLite rows!

A batch file is generated when you compile the project.
You can also use the macro in the project to launch a command prompt that run the batch file.
B4X:
#Macro: Title, Open Console, ide://run?file=%COMSPEC%&Args=/c&Args=start&Args=run.bat
Copy and paste any of the json above into the cmd to call the tools.
1765531999432.png
 
Last edited:
  • Like
Reactions: byz

aeric

Expert
Licensed User
Longtime User
Update your claude_desktop_config.json in C:\Users\<yourusername>\AppData\Roaming\Claude

JSON:
{
  "mcpServers": {
    "b4j-inventory": {
      "command": "Path/To/OpenJDK/bin/java",
      "args": [
        "-jar",
        "C:/Path/To/Your/mcp_server.jar"
      ]
    }
  }
}

and your MCP server will be available!

Restart the Claude desktop app if there is an error.

1765386687510.png


You can click the Greater Than button next to the switch to see available tools.
1765387037835.png


When you ask the AI Client, you will be asked to Allow it to proceed.
1765387595774.png


1765387754825.png


1765387863768.png
 
Last edited:

hatzisn

Expert
Licensed User
Longtime User
(💯💯💯💯💯💯💯💯💯💯💯💯💯💯💯💯💯💯💯💯) * 10000
 

hatzisn

Expert
Licensed User
Longtime User
Are you successfully follow and run the server project?
Not yet. But I will try it a.s.a.p. Thank you for your effort.
 

aeric

Expert
Licensed User
Longtime User
Maybe because Claude is running the jar and when you try to build the project, you get an error the jar is being used by another process.

To kill it:

1765528895375.png
 

hatzisn

Expert
Licensed User
Longtime User
I believe this is the most "complicated" MCP demo you can find on earth.
See the file size 😄
Have fun! 😊

Hi, you gave me homework with your example and by asking Gemini, using some old code by @tchart and a YouTube tutorial I understood that the MCP Server uses Server-Sent Events for communication via http. Do you think you can try the following Jetty Server code adapting it to use "ins" inputstream in the place of stdio in and "outs" outputstream in the place of stdio out? Here is the code of the ServerHandler. I would like to do it but it has been a long day today with much lesser sleep and I am not sure also my laptop can handle the claude app locally (if it does not work you can try deleting the Transfer-Encoding header) :

(I will try everything tomorrow anyway but I really would like to take advantage of the time difference to know if it works.)

B4X:
'Handler class
Sub Class_Globals
    Dim outs As OutputStream
    Dim ins As InputStream
    Dim astream As AsyncStreams
End Sub

Public Sub Initialize
 
End Sub

Sub Handle(req As ServletRequest, resp As ServletResponse)
    resp.ContentType = "text/event-stream"
    resp.SetHeader("Cache-Control","no-cache")
    resp.SetHeader("Transfer-Encoding", "chunked")
    resp.setHeader("Connection", "keep-alive")
    resp.CharacterEncoding = "UTF-8"
 
    resp.Status = 200
 
    outs = resp.OutputStream
    ins = req.InputStream
 
    astream.Initialize(ins, outs, "astream")

 
    StartMessageLoop
End Sub

Private Sub astream_NewData (Buffer() As Byte) 'Here the llm app sends data. Probably it will end in 2 new line bytes - (10).
 
End Sub

Private Sub astream_Error
    StopMessageLoop
End Sub

Private Sub astream_Terminated
    StopMessageLoop
End Sub

Private Sub WriteStringToStream(sJSON As String)
    Dim b() As Byte = sJSON.GetBytes("UTF8")
    astream.Write(b)
    Dim beosse() As Byte = Array As Byte(10, 10)
    astream.Write(beosse)
End Sub
 

aeric

Expert
Licensed User
Longtime User
Hi, you gave me homework with your example and by asking Gemini, using some old code by @tchart and a YouTube tutorial I understood that the MCP Server uses Server-Sent Events for communication via http. Do you think you can try the following Jetty Server code adapting it to use "ins" inputstream in the place of stdio in and "outs" outputstream in the place of stdio out? Here is the code of the ServerHandler. I would like to do it but it has been a long day today with much lesser sleep and I am not sure also my laptop can handle the claude app locally (if it does not work you can try deleting the Transfer-Encoding header) :

(I will try everything tomorrow anyway but I really would like to take advantage of the time difference to know if it works.)

B4X:
'Handler class
Sub Class_Globals
    Dim outs As OutputStream
    Dim ins As InputStream
    Dim astream As AsyncStreams
End Sub

Public Sub Initialize
  
End Sub

Sub Handle(req As ServletRequest, resp As ServletResponse)
    resp.ContentType = "text/event-stream"
    resp.SetHeader("Cache-Control","no-cache")
    resp.SetHeader("Transfer-Encoding", "chunked")
    resp.setHeader("Connection", "keep-alive")
    resp.CharacterEncoding = "UTF-8"
  
    resp.Status = 200
  
    outs = resp.OutputStream
    ins = req.InputStream
  
    astream.Initialize(ins, outs, "astream")

  
    StartMessageLoop
End Sub

Private Sub astream_NewData (Buffer() As Byte) 'Here the llm app sends data
  
End Sub

Private Sub astream_Error
    StopMessageLoop
End Sub

Private Sub astream_Terminated
    StopMessageLoop
End Sub

Private Sub WriteStringToStream(sJSON As String)
    Dim b() As Byte = sJSON.GetBytes("UTF8")
    outs.WriteBytes(b, 0 ,b.Length)
    Dim beosse() As Byte = Array As Byte(10, 10)
    outs.WriteBytes(beosse, 0 ,beosse.Length)
End Sub
I don't get what you mean. Maybe you want to use the HTTP Streamable in jServer?
I already started it and shared on my GitHub a few hours ago.
I still unsuccessful make it work on Claude desktop on the config file.
I stopped testing when I went for dinner just now.
Check: https://github.com/pyhoon/mcp-server-http-streamable-b4j

By the way, server sent events (SSE) is already deprecated transport type on March.
 

hatzisn

Expert
Licensed User
Longtime User
If yours doesn't work, neither will work mine, especially if it is deprecated. By the way do you mean deprecated as communication in mcp-server or generally deprecated as communication?
 

hatzisn

Expert
Licensed User
Longtime User

aeric

Expert
Licensed User
Longtime User
If yours doesn't work, neither will work mine
The server is working but the problem is I am still not manage to get the Claude app to work correctly.
I am also trying to create a B4J client using OkHttputils2 for testing. The server received the command.
 

aeric

Expert
Licensed User
Longtime User
The issue is Claude desktop only support stdio transport.
For http streamable/sse, it requires a local proxy or bridge.
Currently a working proof of concept is using the command "npx mcp-remote http://127.0.0.1:8080/mcp"
https://www.npmjs.com/package/mcp-remote

Edit: upgrading Claude to pro plan enables integrations with remote MCP.
https://support.claude.com/en/articles/11503834-building-custom-connectors-via-remote-mcp-servers

Edit: If you are feeling adventurous, try to build an extension .mcpb (MCP Bundle)
https://www.anthropic.com/engineering/desktop-extensions
 
Last edited:
Top