@purplesquirrel/ibmz-mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,90 @@
1
+ # LinkedIn Post - IBM Z MCP Server
2
+
3
+ ---
4
+
5
+ ## Post Option 1 (Technical Focus)
6
+
7
+ **Just shipped: IBM Z MCP Server** šŸ”
8
+
9
+ I built an MCP server that brings IBM Z mainframe capabilities to Claude Code.
10
+
11
+ The result? Claude can now manage HSM-backed encryption keys and call mainframe APIs directly.
12
+
13
+ **Key Protect Integration:**
14
+ • Create/manage encryption keys in FIPS 140-2 Level 3 HSMs
15
+ • Envelope encryption for securing data at rest
16
+ • Key rotation and lifecycle management
17
+
18
+ **z/OS Connect Integration:**
19
+ • REST APIs to CICS, IMS, and batch programs
20
+ • OpenAPI spec discovery
21
+ • Bridge modern AI agents to legacy systems
22
+
23
+ This pairs with my watsonx MCP server for a complete IBM Cloud + AI integration:
24
+ - Claude orchestrates complex tasks
25
+ - watsonx.ai handles foundation model workloads
26
+ - Key Protect secures sensitive data
27
+ - z/OS Connect bridges to enterprise systems
28
+
29
+ šŸ“– Demo: https://purplesquirrelmedia.github.io/ibmz-mcp-server/
30
+ šŸ’» Source: https://github.com/PurpleSquirrelMedia/ibmz-mcp-server
31
+
32
+ #IBM #IBMz #Mainframe #Claude #MCP #Anthropic #Security #EnterpriseAI
33
+
34
+ ---
35
+
36
+ ## Post Option 2 (Enterprise Value Focus)
37
+
38
+ **Connecting AI Agents to Enterprise Mainframes** šŸ¢
39
+
40
+ Just released an open-source integration that lets Claude Code interact with IBM Z infrastructure.
41
+
42
+ Why this matters:
43
+ → 70% of Fortune 500 companies run mission-critical workloads on IBM Z
44
+ → AI agents need access to enterprise data and systems
45
+ → Security can't be compromised
46
+
47
+ What I built:
48
+ 1. **Key Protect MCP Tools** - Claude can create and manage encryption keys stored in hardware security modules
49
+ 2. **z/OS Connect Tools** - Claude can discover and call mainframe APIs
50
+
51
+ The security model:
52
+ - Keys never leave the HSM
53
+ - All operations are audited
54
+ - Claude handles orchestration, not secrets
55
+
56
+ Real use case: An AI agent analyzing financial data can request a wrapped DEK, decrypt locally, process, then discard - the root key stays in the HSM the entire time.
57
+
58
+ Links:
59
+ šŸ”— https://github.com/PurpleSquirrelMedia/ibmz-mcp-server
60
+ šŸ“– https://purplesquirrelmedia.github.io/ibmz-mcp-server/
61
+
62
+ #EnterpriseAI #IBMz #Security #CloudSecurity #MCP
63
+
64
+ ---
65
+
66
+ ## Post Option 3 (Short & Punchy)
67
+
68
+ Two new MCP servers for IBM Cloud:
69
+
70
+ **watsonx-mcp-server**
71
+ → Claude delegates to Granite, Llama, Mistral models
72
+ → Two-agent AI architecture
73
+
74
+ **ibmz-mcp-server**
75
+ → HSM-backed key management
76
+ → z/OS Connect mainframe APIs
77
+
78
+ The stack:
79
+ ā˜ļø IBM Cloud free tier
80
+ šŸ” Key Protect HSM
81
+ šŸ¤– watsonx.ai foundation models
82
+ šŸ¢ z/OS Connect (optional)
83
+ 🧠 Claude Code orchestration
84
+
85
+ All tested. All working. All open source.
86
+
87
+ šŸ”— watsonx: https://github.com/PurpleSquirrelMedia/watsonx-mcp-server
88
+ šŸ”— IBM Z: https://github.com/PurpleSquirrelMedia/ibmz-mcp-server
89
+
90
+ #MCP #IBM #Claude #OpenSource
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@purplesquirrel/ibmz-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for IBM Z mainframe integration - Key Protect HSM and z/OS Connect",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "start": "node index.js"
9
+ },
10
+ "keywords": [
11
+ "mcp",
12
+ "ibm",
13
+ "ibm-z",
14
+ "mainframe",
15
+ "key-protect",
16
+ "hsm",
17
+ "zos-connect",
18
+ "claude",
19
+ "anthropic"
20
+ ],
21
+ "author": "Matthew Karsten",
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "@ibm-cloud/ibm-key-protect": "^0.4.1",
25
+ "@ibm-cloud/watsonx-ai": "^1.7.5",
26
+ "@modelcontextprotocol/sdk": "^1.0.0",
27
+ "ibm-cloud-sdk-core": "^5.1.0"
28
+ }
29
+ }
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import IbmKeyProtectApiV2 from '@ibm-cloud/ibm-key-protect/ibm-key-protect-api/v2.js';
3
+ import { IamAuthenticator } from 'ibm-cloud-sdk-core';
4
+ import crypto from 'crypto';
5
+
6
+ const client = new IbmKeyProtectApiV2({
7
+ authenticator: new IamAuthenticator({
8
+ apikey: process.env.IBM_CLOUD_API_KEY,
9
+ }),
10
+ serviceUrl: process.env.KEY_PROTECT_URL,
11
+ });
12
+
13
+ const instanceId = process.env.KEY_PROTECT_INSTANCE_ID;
14
+ const rootKeyId = 'dcd74ed6-5e33-45db-a25c-38f668f2f664';
15
+
16
+ // Generate a random data encryption key (DEK) - 32 bytes for AES-256
17
+ const dek = crypto.randomBytes(32);
18
+ const dekBase64 = dek.toString('base64');
19
+ console.log('Original DEK:', dekBase64);
20
+
21
+ // Wrap the DEK with our root key (envelope encryption)
22
+ console.log('\nWrapping DEK with root key...');
23
+ const wrapResult = await client.wrapKey({
24
+ bluemixInstance: instanceId,
25
+ id: rootKeyId,
26
+ keyActionWrapBody: {
27
+ plaintext: dekBase64
28
+ }
29
+ });
30
+
31
+ const wrappedDek = wrapResult.result.ciphertext;
32
+ console.log('Wrapped DEK:', wrappedDek.substring(0, 50) + '...');
33
+
34
+ // Unwrap the DEK to verify it works
35
+ console.log('\nUnwrapping DEK...');
36
+ const unwrapResult = await client.unwrapKey({
37
+ bluemixInstance: instanceId,
38
+ id: rootKeyId,
39
+ keyActionUnwrapBody: {
40
+ ciphertext: wrappedDek
41
+ }
42
+ });
43
+
44
+ const unwrappedDek = unwrapResult.result.plaintext;
45
+ console.log('Unwrapped DEK:', unwrappedDek);
46
+ console.log('\nāœ… Envelope encryption test:', dekBase64 === unwrappedDek ? 'SUCCESS!' : 'FAILED');
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Test watsonx.ai text generation
4
+ * Requires either a project_id or space_id
5
+ */
6
+
7
+ import { WatsonXAI } from '@ibm-cloud/watsonx-ai';
8
+ import { IamAuthenticator } from 'ibm-cloud-sdk-core';
9
+
10
+ const apiKey = process.env.WATSONX_API_KEY || 'YveH06g9T_XKZoKapGJsjm9q9xCz6WJ6z4GBRM_LJ9R5';
11
+ const projectId = process.env.WATSONX_PROJECT_ID;
12
+
13
+ const client = WatsonXAI.newInstance({
14
+ version: '2024-05-31',
15
+ serviceUrl: 'https://us-south.ml.cloud.ibm.com',
16
+ authenticator: new IamAuthenticator({ apikey: apiKey }),
17
+ });
18
+
19
+ console.log('=== watsonx.ai Text Generation Test ===\n');
20
+
21
+ // First, list models to confirm connection
22
+ console.log('1. Checking available models...');
23
+ const modelsResp = await client.listFoundationModelSpecs({ limit: 20 });
24
+ const models = modelsResp.result.resources || [];
25
+
26
+ // Find text generation capable models
27
+ const textGenModels = models.filter(m =>
28
+ m.model_id?.includes('granite') ||
29
+ m.model_id?.includes('llama') ||
30
+ m.model_id?.includes('mistral')
31
+ );
32
+
33
+ console.log(` Found ${textGenModels.length} text generation models:`);
34
+ textGenModels.slice(0, 5).forEach(m => console.log(` • ${m.model_id}`));
35
+
36
+ if (!projectId) {
37
+ console.log('\nāš ļø No WATSONX_PROJECT_ID set.');
38
+ console.log('\nTo enable text generation:');
39
+ console.log('1. Go to https://dataplatform.cloud.ibm.com');
40
+ console.log('2. Create a new project');
41
+ console.log('3. Copy the Project ID from Settings → General');
42
+ console.log('4. Add to ~/.claude.json under mcpServers.watsonx.env:');
43
+ console.log(' "WATSONX_PROJECT_ID": "your-project-id"');
44
+ console.log('\nOr set environment variable:');
45
+ console.log(' export WATSONX_PROJECT_ID=your-project-id');
46
+ process.exit(0);
47
+ }
48
+
49
+ // Test generation if project ID is available
50
+ console.log('\n2. Testing text generation...');
51
+ console.log(` Using project: ${projectId}`);
52
+
53
+ try {
54
+ const response = await client.generateText({
55
+ input: 'Explain envelope encryption in one sentence:',
56
+ modelId: 'ibm/granite-3-8b-instruct',
57
+ projectId: projectId,
58
+ parameters: {
59
+ max_new_tokens: 100,
60
+ temperature: 0.7,
61
+ }
62
+ });
63
+
64
+ console.log('\n Generated response:');
65
+ console.log(` "${response.result.results[0].generated_text.trim()}"`);
66
+ console.log('\nāœ… Text generation working!');
67
+ } catch (error) {
68
+ console.log('\nāŒ Generation failed:', error.message);
69
+ if (error.message.includes('project_id')) {
70
+ console.log('\n The project ID may be invalid or not properly configured.');
71
+ }
72
+ }