<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Isaac Johnson</title>
    <description>The latest articles on DEV Community by Isaac Johnson (@idjohnson).</description>
    <link>https://dev.to/idjohnson</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1027695%2Fe6c4af09-9442-476f-9488-060317b6d4aa.jpeg</url>
      <title>DEV Community: Isaac Johnson</title>
      <link>https://dev.to/idjohnson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/idjohnson"/>
    <language>en</language>
    <item>
      <title>COBOL Web and MCP Servers</title>
      <dc:creator>Isaac Johnson</dc:creator>
      <pubDate>Fri, 09 Jan 2026 00:45:15 +0000</pubDate>
      <link>https://dev.to/gde/cobol-web-and-mcp-servers-2810</link>
      <guid>https://dev.to/gde/cobol-web-and-mcp-servers-2810</guid>
      <description>&lt;p&gt;Today we will do two things: look at webservers and try and make MCP servers.  In both cases, we are going to leverage a bit older of a language, COBOL.  &lt;/p&gt;

&lt;p&gt;Lets get started with Web Servers first...&lt;/p&gt;

&lt;h2&gt;
  
  
  WebBol
&lt;/h2&gt;

&lt;p&gt;Let's start by cloning down &lt;a href="https://github.com/jmsdnns/webbol" rel="noopener noreferrer"&gt;Webbol&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder@DESKTOP-QADGF36:~/Workspaces$ git clone https://github.com/jmsdnns/webbol.git
Cloning into 'webbol'...
remote: Enumerating objects: 41, done.
remote: Counting objects: 100% (41/41), done.
remote: Compressing objects: 100% (28/28), done.
remote: Total 41 (delta 20), reused 34 (delta 13), pack-reused 0 (from 0)
Receiving objects: 100% (41/41), 20.16 KiB | 607.00 KiB/s, done.
Resolving deltas: 100% (20/20), done.
builder@DESKTOP-QADGF36:~/Workspaces$ cd webbol/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I'll need the GNU Cobol compiler, if I don't already have it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt-get install gnucobol
[sudo] password for builder:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
gnucobol is already the newest version (5).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now &lt;code&gt;make&lt;/code&gt; to compile the app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder@DESKTOP-QADGF36:~/Workspaces/webbol$ make
cobc -free -c -I. path-utils.cbl
cobc -free -c -I. mime-types.cbl
cobc -free -c -I. file-ops.cbl
cobc -free -c -I. http-handler.cbl
cobc -free -c -I. url-decode.cbl
cobc -free -x -I. webserver.cbl path-utils.o mime-types.o file-ops.o http-handler.o url-decode.o -o webserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I need something to serve up&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ echo "&amp;lt;HTML&amp;gt;&amp;lt;HEAD&amp;gt;&amp;lt;TITLE&amp;gt;CobolFTW&amp;lt;/TITLE&amp;gt;&amp;lt;/HEAD&amp;gt;&amp;lt;BODY&amp;gt;&amp;lt;H1&amp;gt;Hello w0rld&amp;lt;/H1&amp;gt;&amp;lt;/BODY&amp;gt;&amp;lt;/HTML&amp;gt;" &amp;gt; index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can now fire up &lt;code&gt;webserver&lt;/code&gt; to host a web server on port 8080&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder@DESKTOP-QADGF36:~/Workspaces/webbol$ ./webserver
COBOL Web Server Starting...
Press Ctrl+C to stop

Server listening on port 08080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first time it hung on me and didn't return (then crashed).  But the second time it worked&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./webserver
COBOL Web Server Starting...
Press Ctrl+C to stop

Server listening on port 08080
Request #00000002:
GET / HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9
Request #00000004:
GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
sec-ch-ua-platform: "Windows"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"
sec-ch-ua-mobile: ?0
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Referer: http://127.0.0.1:8080/
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-01.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2lkqvb1b2s59ns7qhroz.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-01.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP server
&lt;/h2&gt;

&lt;p&gt;I made a modified version that should serve up a basic Hello World MCP server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder@LuiGi:~/Workspaces$ git clone https://github.com/idjohnson/webbol-mcp.git
Cloning into 'webbol-mcp'...
remote: Enumerating objects: 47, done.
remote: Counting objects: 100% (47/47), done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 47 (delta 24), reused 37 (delta 14), pack-reused 0 (from 0)
Receiving objects: 100% (47/47), 23.79 KiB | 11.90 MiB/s, done.
Resolving deltas: 100% (24/24), done.
builder@LuiGi:~/Workspaces$ cd webbol-mcp/



builder@LuiGi:~/Workspaces/webbol-mcp$ make
cobc -free -c -I. path-utils.cbl
&amp;lt;command-line&amp;gt;: warning: ‘_FORTIFY_SOURCE’ redefined
&amp;lt;command-line&amp;gt;: note: this is the location of the previous definition
cobc -free -c -I. mime-types.cbl
&amp;lt;command-line&amp;gt;: warning: ‘_FORTIFY_SOURCE’ redefined
&amp;lt;command-line&amp;gt;: note: this is the location of the previous definition
cobc -free -c -I. file-ops.cbl
&amp;lt;command-line&amp;gt;: warning: ‘_FORTIFY_SOURCE’ redefined
&amp;lt;command-line&amp;gt;: note: this is the location of the previous definition
cobc -free -c -I. http-handler.cbl
&amp;lt;command-line&amp;gt;: warning: ‘_FORTIFY_SOURCE’ redefined
&amp;lt;command-line&amp;gt;: note: this is the location of the previous definition
cobc -free -c -I. url-decode.cbl
&amp;lt;command-line&amp;gt;: warning: ‘_FORTIFY_SOURCE’ redefined
&amp;lt;command-line&amp;gt;: note: this is the location of the previous definition
cobc -free -x -I. webserver.cbl path-utils.o mime-types.o file-ops.o http-handler.o url-decode.o -o webserver
&amp;lt;command-line&amp;gt;: warning: ‘_FORTIFY_SOURCE’ redefined
&amp;lt;command-line&amp;gt;: note: this is the location of the previous definition

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the side, I'll launch the MCP inspector&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nvm use lts/jod
Now using node v22.20.0 (npm v10.9.3)

$ npx @modelcontextprotocol/inspector
Need to install the following packages:
@modelcontextprotocol/inspector@0.18.0
Ok to proceed? (y) Y

Starting MCP inspector...
⚙️ Proxy server listening on localhost:6277
🔑 Session token: dffd143fd8859f9173dd18cbdcd226d212ad330c48e025076ef0e2aaf8388982
   Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth

🚀 MCP Inspector is up and running at:
   http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=dffd143fd8859f9173dd18cbdcd226d212ad330c48e025076ef0e2aaf8388982

🌐 Opening browser...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I can fire up the webserver&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder@LuiGi:~/Workspaces/webbol-mcp$ ./webserver 
COBOL Web Server Starting...
Press Ctrl+C to stop

Server listening on port 08080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll be straight - I worked on this for a while.  It just is not consistent, at least with HTTPStreamable.&lt;/p&gt;

&lt;p&gt;It times out and I think a lot of the issue is how it reads files into memory.&lt;/p&gt;

&lt;p&gt;I did stash my work in &lt;a href="https://github.com/idjohnson/webbol-mcp" rel="noopener noreferrer"&gt;idjohnson/webbol-mcp&lt;/a&gt; in case I (or anyone else) wanted to take back over the charge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try two
&lt;/h2&gt;

&lt;p&gt;I hammered at this for another full day.  I started to think the method of modifying an existing Cobol repo might be a fools errand.  I decided to switch to Aggy and use a requirements driven approach.&lt;/p&gt;

&lt;p&gt;I created a requirements.md:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Goal

Create a basic hello world MCP server using COBOL.  It can be httpStreamable or STDIO.

# Requirements

It must:
- Have a Dockerfile and work in a container
- Have all documentation to build and run stored in a README.md
- compile with gnucobol (cobc)
- Create a "test.sh" script that can launch a built docker container on port 8089 and test it for proper MCP server JSON responses

# Examples to use

A Web Server in gnucobol: https://github.com/jmsdnns/webbol.git
A python MCP server: https://github.com/jlowin/fastmcp.git
- hint: review Python implementation and convert to COBOL
MCP Transport documentation with requirements: 
- https://modelcontextprotocol.io/specification/2025-03-26/basic/transports
- https://mcp-framework.com/docs/Transports/http-stream-transport/

# MCP Requirements

Should handle connect session (often a POST to / or /mcp)
Should advertise a "hello world" tool that takes in a single string
Tool should then reply with "hello $string"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I fired this up in Aggy&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-02.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6do1z02abyqe0np30b5.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-02.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And asked it to execute to plan&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-03.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6cdxxmekfalqtabzx30.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-03.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My thought is that if I give it some creative freedom and stick to my requirements, it might come up with a better idea that I was using.  &lt;/p&gt;

&lt;p&gt;I might argue, this is true in life too - if you get a really smart Junior or intern (or take that for wherever you are in your stage of life) and just order them to build to your preconceived ideas, you might not get the best product.  But if you step back and just say your rules and requirements, you might be surprised with what they come up with.&lt;/p&gt;

&lt;p&gt;Here is my first real gripe with Aggy.. It was launched with WSL but keeps trying to do things with windows. So it's vomiting on powershell.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-04.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa54ndfda1j9wy4ubw8c.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-04.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That said, it did at first get hung up on a used port (so i moved it to 8090) then I noticed it started to really do as I asked (use Docker)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-05.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzqpa0309iuaqe8svcm0l.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-05.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This really worked, it took plenty of time, so I'm curious what my end cost might be, but it wrote and tested things over and over, which I really respect&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-06.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqrvahl0p6433h5w46pz.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-06.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It took a long while, I wont lie.  We tag teamed, Aggy and Me, and finally sorted out all the issues.  It was a pointless waste of tokens, but I had to give it some kudos&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-07.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc647xij628z9zr5hl092.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-07.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some proof it works:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-08.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmssc8uogy10bjqgw2ph9.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-08.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With a few more tweaks, it works in Copilot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-09.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feahpbk151ijerkojr061.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-09.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and Gemini CLI&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-10.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1vujytyzn02ilggdzp9q.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-10.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now remember, sharing is caring, so let's push out a copy for everyone&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder@DESKTOP-QADGF36:~/Workspaces/cobolMcp$ docker build -t idjohnson/cobolmcp:latest .
[+] Building 0.8s (11/11) FINISHED                                                                                    docker:default
 =&amp;gt; [internal] load build definition from Dockerfile                                                                            0.0s
 =&amp;gt; =&amp;gt; transferring dockerfile: 339B                                                                                            0.0s
 =&amp;gt; [internal] load metadata for docker.io/library/ubuntu:22.04                                                                 0.7s
 =&amp;gt; [auth] library/ubuntu:pull token for registry-1.docker.io                                                                   0.0s
 =&amp;gt; [internal] load .dockerignore                                                                                               0.0s
 =&amp;gt; =&amp;gt; transferring context: 2B                                                                                                 0.0s
 =&amp;gt; [1/5] FROM docker.io/library/ubuntu:22.04@sha256:104ae83764a5119017b8e8d6218fa0832b09df65aae7d5a6de29a85d813da2fb           0.0s
 =&amp;gt; =&amp;gt; resolve docker.io/library/ubuntu:22.04@sha256:104ae83764a5119017b8e8d6218fa0832b09df65aae7d5a6de29a85d813da2fb           0.0s
 =&amp;gt; [internal] load build context                                                                                               0.0s
 =&amp;gt; =&amp;gt; transferring context: 207B                                                                                               0.0s
 =&amp;gt; CACHED [2/5] RUN apt-get update &amp;amp;&amp;amp; apt-get install -y     gnucobol     gcc     make     &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*      0.0s
 =&amp;gt; CACHED [3/5] WORKDIR /app                                                                                                   0.0s
 =&amp;gt; CACHED [4/5] COPY cobol-mcp/ .                                                                                              0.0s
 =&amp;gt; CACHED [5/5] RUN cobc -x -free -o mcp-server server.cbl mcp-handler.cbl                                                     0.0s
 =&amp;gt; exporting to image                                                                                                          0.0s
 =&amp;gt; =&amp;gt; exporting layers                                                                                                         0.0s
 =&amp;gt; =&amp;gt; writing image sha256:734f9f3b089300a14e209f28fba72c0377bde45943755268eeacfc898ec8420c                                    0.0s
 =&amp;gt; =&amp;gt; naming to docker.io/idjohnson/cobolmcp:latest                                                                            0.0s
builder@DESKTOP-QADGF36:~/Workspaces/cobolMcp$ docker push idjohnson/cobolmcp:latest
The push refers to repository [docker.io/idjohnson/cobolmcp]
8d40b8071372: Pushed
ceee004e5fea: Pushed
b97bff40fbbf: Pushed
3d4ff65c54e8: Pushed
73974f74b436: Mounted from library/ubuntu
latest: digest: sha256:487e0a0e7f057941d3a6c5ea4309f13e9c3e06273cc98a90178e8b444a5762a1 size: 1364
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I really want to use Gemini CLI extensions, but the Docker ones seem limited to STDIO.&lt;/p&gt;

&lt;p&gt;I initially tried cheating and firing up an MCP server in docker then trying to use it locally, but it timed out&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cat gemini-extension.json
{
  "name": "cobolMCP",
  "version": "1.0.0",
  "mcpServers": {
    "startdocker": {
      "command": "docker",
      "args": [
         "run",
         "--rm",
         "-p",
         "8090:8090",
         "idjohnson/cobolmcp:latest"
      ]
    },
    "usedocker": {
      "httpUrl": "http://localhost:8090",
      "timeout": 5000
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I pivoted instead to firing up a Helm chart with an ingress.&lt;/p&gt;

&lt;p&gt;I needed to fire up a new A record in GCP CloudDNS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ gcloud dns --project=myanthosproject2 record-sets create cobolmcp.steeped.icu --zone="steeped
icu" --type="A" --ttl="300" --rrdatas="174.53.161.33"
NAME                   TYPE  TTL  DATA
cobolmcp.steeped.icu.  A     300  174.53.161.33
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now with some local values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Default values for cobolmcp.&lt;/span&gt;
&lt;span class="c1"&gt;# This is a YAML-formatted file.&lt;/span&gt;
&lt;span class="c1"&gt;# Declare variables to be passed into your templates.&lt;/span&gt;

&lt;span class="na"&gt;replicaCount&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;idjohnson/cobolmcp&lt;/span&gt;
  &lt;span class="na"&gt;pullPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Always&lt;/span&gt;
  &lt;span class="c1"&gt;# Overrides the image tag whose default is the chart appVersion.&lt;/span&gt;
  &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latest"&lt;/span&gt;

&lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nginx"&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cert-manager.io/cluster-issuer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gcpleprod2&lt;/span&gt;
    &lt;span class="na"&gt;ingress.kubernetes.io/proxy-body-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0"&lt;/span&gt;
    &lt;span class="na"&gt;ingress.kubernetes.io/ssl-redirect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
    &lt;span class="na"&gt;kubernetes.io/tls-acme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/proxy-body-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0"&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/proxy-read-timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3600"&lt;/span&gt;
    &lt;span class="na"&gt;nginx.ingress.kubernetes.io/proxy-send-timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3600"&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cobolmcp.steeped.icu&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
          &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ImplementationSpecific&lt;/span&gt;
  &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;secretName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cobolmcpgcp-tls&lt;/span&gt;
     &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
       &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cobolmcp.steeped.icu&lt;/span&gt;

&lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;250m&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;256Mi&lt;/span&gt;
  &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;100m&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;128Mi&lt;/span&gt;

&lt;span class="na"&gt;autoscaling&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;minReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;maxReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
  &lt;span class="na"&gt;targetCPUUtilizationPercentage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I could install the chart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ helm install cobolmcp -f ./values.yaml ./charts/cobolmcp
NAME: cobolmcp
LAST DEPLOYED: Thu Jan  8 14:08:20 2026
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  https://cobolmcp.steeped.icu/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I had to rework my liveness and readiness probes to use TCP over HTTP, but I managed to get a container up&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get po -l app.kubernetes.io/instance=cobolmcp
NAME                        READY   STATUS    RESTARTS   AGE
cobolmcp-5bd67cdf8b-49ww4   1/1     Running   0          34s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the cert was satisified&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get cert | grep mc
cobolmcpgcp-tls                     True    cobolmcpgcp-tls                     8m34s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to test&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;builder@DESKTOP-QADGF36:~/Workspaces/cobolMcp$ cat gemini-extension.json
{
  "name": "cobolMCP",
  "version": "1.0.0",
  "mcpServers": {
    "cobolMCP": {
      "httpUrl": "https://cobolmcp.steeped.icu",
      "timeout": 5000
    }
  }
}

builder@DESKTOP-QADGF36:~/Workspaces/cobolMcp$ gemini extensions link /home/builder/Workspaces/cobolMcp/
Installing extension "cobolMCP".
**The extension you are about to install may have been created by a third-party developer and sourced from a public repository. Google does not vet, endorse, or guarantee the functionality or security of extensions. Please carefully inspect any extension and its source code before installing to understand the permissions it requires and the actions it may perform.**
This extension will run the following MCP servers:
  * cobolMCP (remote): https://cobolmcp.steeped.icu
Do you want to continue? [Y/n]: Y
Extension "cobolMCP" linked successfully and enabled.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can now see that this uses an external server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ gemini mcp list
Configured MCP servers:

✗ cobolMCP (from cobolMCP): https://cobolmcp.steeped.icu (http) - Disconnected
✗ forgejomcp (from forgejomcp): https://nodejsmcp-511842454269.us-east1.run.app/mcp (http) - Disconnected
✓ nanobanana (from nanobanana): node /home/builder/.gemini/extensions/nanobanana/mcp-server/dist/index.js (stdio) - Connected
✓ nodeServer (from vikunja): docker run -i --rm -e VIKUNJA_URL -e VIKUNJA_USERNAME -e VIKUNJA_PASSWORD harbor.freshbrewed.science/library/vikunjamcp:0.26 (stdio) - Connected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's now test it&lt;/p&gt;


    


&lt;p&gt;I now have the code published into &lt;a href="https://github.com/idjohnson/cobolMCP" rel="noopener noreferrer"&gt;https://github.com/idjohnson/cobolMCP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After a while, even saw it show up on the &lt;a href="https://geminicli.com/extensions/" rel="noopener noreferrer"&gt;Gemini CLI Extensions Library&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-12.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddgdd120c3qnu4bih6g6.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-12.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;which will show how to install it if you &lt;a href="https://geminicli.com/extensions/?name=idjohnsoncobolMCP" rel="noopener noreferrer"&gt;click on the entry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://freshbrewed.science/content/images/2026/01/cobol-13.png" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsw919vt94o914uw66wx6.png" alt="https://freshbrewed.science/content/images/2026/01/cobol-13.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;We started with &lt;a href="https://github.com/jmsdnns/webbol" rel="noopener noreferrer"&gt;Webbol&lt;/a&gt; which was easy to Dockerize and run in a container.  I, at first, spent way too much time trying to modify it into a working MCP server and ultimately gave up (but stashed my branch in a GIT repo &lt;a href="https://github.com/idjohnson/webbol-mcp.git" rel="noopener noreferrer"&gt;https://github.com/idjohnson/webbol-mcp.git&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I moved on to starting fresh and between Gemini CLI and Antigravity (which i call Aggy), and a whole lot of testing and debugging, we built out &lt;a href="https://github.com/idjohnson/cobolMCP" rel="noopener noreferrer"&gt;cobolMCP&lt;/a&gt;.  It has a Helm chart, a running service in my K8s, a Gemini CLI extension and a public docker image.  I call that a win.&lt;/p&gt;

</description>
      <category>gde</category>
      <category>gemini</category>
      <category>cobol</category>
    </item>
  </channel>
</rss>
