# KISC MCP Server - MCPF Integration Deployment Guide **Project:** MCPF (MCP Trust Framework) Integration for KISC MCP Server **Target Server:** llm.kis.gov.lv **DID:** `did:web:llm.kis.gov.lv` **Date:** 2026-01-30 --- ## πŸ“‹ Table of Contents 1. [Overview](#overview) 2. [Package Contents](#package-contents) 3. [Prerequisites](#prerequisites) 4. [Part A: Local Implementation](#part-a-local-implementation) 5. [Part B: VeriTrust Integration](#part-b-veritrust-integration) 6. [Validation & Testing](#validation--testing) 7. [Troubleshooting](#troubleshooting) --- ## Overview This package integrates MCPF (MCP Trust Framework) into the KISC MCP Server, providing: βœ… **Cryptographic Identity** β€” `did:web:llm.kis.gov.lv` with Ed25519 signing βœ… **Verifiable Credentials** β€” VeriTrust-issued MCPServerCredential βœ… **Trust Metadata** β€” Discoverable at `/.well-known/mcp-trust-registry.json` βœ… **Standards Compliance** β€” W3C DID Core, VC Data Model, MCPF Specification --- ## Package Contents ``` kisc-mcpf-deploy/ β”œβ”€β”€ README.md # This file β”œβ”€β”€ keypair-SECURE.json # ⚠️ PRIVATE KEY (secure handling!) β”œβ”€β”€ public-key.json # Public key reference β”‚ β”œβ”€β”€ wellknown/ # .well-known files for nginx β”‚ β”œβ”€β”€ did.json # DID Document β”‚ β”œβ”€β”€ jwks.json # JWK Set (public keys) β”‚ β”œβ”€β”€ mcp-trust-registry.json # MCPF registry discovery β”‚ β”œβ”€β”€ security.txt # RFC 9116 security contact β”‚ β”œβ”€β”€ mcp/ β”‚ β”‚ └── manifest.json # MCP server capabilities β”‚ └── credentials/ β”‚ └── mcp-server.json # VC placeholder (VeriTrust will replace) β”‚ β”œβ”€β”€ scripts/ # Deployment automation β”‚ β”œβ”€β”€ deploy-wellknown.sh # Deploy .well-known to server β”‚ β”œβ”€β”€ validate-endpoints.sh # Test all endpoints β”‚ └── update-env.sh # Add MCPF_PRIVATE_KEY to .env β”‚ β”œβ”€β”€ nginx/ # nginx configuration β”‚ └── wellknown.conf # nginx config for .well-known β”‚ β”œβ”€β”€ docs/ # Documentation β”‚ β”œβ”€β”€ DEPLOYMENT.md # Step-by-step deployment β”‚ β”œβ”€β”€ INTEGRATION.md # start.sh/status.sh updates β”‚ └── TESTING.md # Validation procedures β”‚ └── veritrust/ # VeriTrust submission β”œβ”€β”€ README-VERITRUST.md # Instructions for VeriTrust β”œβ”€β”€ mcp-server-request.json # Credential request payload └── install-credential.sh # Install received VC ``` --- ## Prerequisites Before deployment, ensure: - [ ] SSH access to `llm.kis.gov.lv` (10.20.30.96) - [ ] Sudo privileges or ownership of `/opt/kisc-llm/` - [ ] POC stack running (`/opt/kisc-llm/poc/deploy/`) - [ ] nginx container (kisc-nginx) operational - [ ] Let's Encrypt certificates valid - [ ] Git access to `kisc-gov-lv/MCP-KISC-architecture` --- ## Part A: Local Implementation ### Step 1: Secure Private Key Storage **⚠️ CRITICAL: Handle `keypair-SECURE.json` securely!** ```bash # On your local machine (NOT on server yet) cat keypair-SECURE.json # Contains: private_key_pem, public_key_pem, multibase, jwk_x # Verify integrity sha256sum keypair-SECURE.json ``` **DO NOT:** - ❌ Commit to Git - ❌ Send via unencrypted email - ❌ Store in Slack/Teams - ❌ Print to logs **DO:** - βœ… Transfer via encrypted channel (scp with key auth, 1Password, etc.) - βœ… Store in `/opt/kisc-llm/poc/deploy/.env` only - βœ… Backup offline (encrypted USB/vault) - βœ… Document who has access --- ### Step 2: Deploy .well-known Files to Server ```bash # On llm.kis.gov.lv server # 1. Create .well-known directory sudo mkdir -p /opt/kisc-llm/poc/deploy/.well-known/{mcp,credentials} sudo chown -R "$USER":"$USER" /opt/kisc-llm/poc/deploy/.well-known # 2. Copy .well-known files cd /opt/kisc-llm/poc/deploy rsync -av /path/to/kisc-mcpf-deploy/wellknown/ .well-known/ # 3. Verify structure tree .well-known/ # Expected: # .well-known/ # β”œβ”€β”€ did.json # β”œβ”€β”€ jwks.json # β”œβ”€β”€ mcp-trust-registry.json # β”œβ”€β”€ security.txt # β”œβ”€β”€ mcp/ # β”‚ └── manifest.json # └── credentials/ # └── mcp-server.json # 4. Set permissions (read-only for nginx) chmod -R 644 .well-known/**/* find .well-known -type d -exec chmod 755 {} \; ``` --- ### Step 3: Add Private Key to .env ```bash # On llm.kis.gov.lv server cd /opt/kisc-llm/poc/deploy # Extract private key from keypair-SECURE.json PRIVATE_KEY_PEM=$(cat /path/to/keypair-SECURE.json | jq -r '.private_key_pem') # Add to .env (replace newlines with \n) echo "MCPF_PRIVATE_KEY=\"$PRIVATE_KEY_PEM\"" >> .env # Verify (should show -----BEGIN PRIVATE KEY-----) grep MCPF_PRIVATE_KEY .env | head -c 100 # Secure the .env file chmod 600 .env ``` --- ### Step 4: Update nginx Configuration ```bash # On llm.kis.gov.lv server cd /opt/kisc-llm/poc/deploy/nginx/conf.d # Backup existing config cp default.conf default.conf.backup-$(date +%Y%m%d) # Add .well-known location block (insert after line 30, before "location /") cat >> default.conf << 'EOF' # ========================================================================== # MCPF .well-known endpoints # ========================================================================== location /.well-known/ { alias /opt/kisc-llm/poc/deploy/.well-known/; # CORS headers for trust framework discovery add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods "GET, OPTIONS" always; add_header Access-Control-Allow-Headers "Content-Type" always; # Cache DID documents for 1 hour (they rarely change) add_header Cache-Control "public, max-age=3600" always; # Serve JSON files location ~ \.(json)$ { add_header Content-Type application/json; } # Serve text files location ~ \.(txt)$ { add_header Content-Type text/plain; } # No directory listing autoindex off; } EOF # Validate nginx config docker exec kisc-nginx nginx -t # If validation passes, reload docker exec kisc-nginx nginx -s reload ``` --- ### Step 5: Update start.sh Script Add MCPF integration steps to `/opt/kisc-llm/poc/deploy/scripts/start.sh`: ```bash # Insert after Step 3 (TLS cert handling), before Step 4 (OpenGateLLM start) # ============================================================================= # Step 3.5: MCPF .well-known Files # ============================================================================= log_step "Step 3.5: Checking MCPF .well-known files..." if [[ ! -f "$DEPLOY_DIR/.well-known/did.json" ]]; then log_error "MCPF .well-known files not found!" log_error "Run: rsync -av /path/to/wellknown/ $DEPLOY_DIR/.well-known/" exit 1 fi # Verify critical files exist REQUIRED_FILES=( ".well-known/did.json" ".well-known/jwks.json" ".well-known/mcp-trust-registry.json" ".well-known/mcp/manifest.json" ".well-known/credentials/mcp-server.json" ) for file in "${REQUIRED_FILES[@]}"; do if [[ ! -f "$DEPLOY_DIR/$file" ]]; then log_warn "Missing: $file" fi done log_info "MCPF .well-known files OK" ``` --- ### Step 6: Update status.sh Script Add MCPF health checks to `/opt/kisc-llm/poc/deploy/scripts/status.sh`: ```bash # Insert at the end, before final completion message # ============================================================================= # MCPF ENDPOINTS STATUS # ============================================================================= echo -e "${CYAN}MCPF Endpoints:${NC}" echo "----------------------------------------" check_wellknown() { local endpoint=$1 local name=$2 local response response=$(curl -sS -k --connect-timeout 2 "https://localhost$endpoint" 2>/dev/null || echo "") if [[ -n "$response" ]] && echo "$response" | grep -q "@context\|keys\|mcpfVersion"; then echo -e " ${GREEN}βœ…${NC} $name" else echo -e " ${RED}❌${NC} $name (HTTP error or empty response)" fi } check_wellknown "/.well-known/did.json" "DID Document" check_wellknown "/.well-known/jwks.json" "JWKS" check_wellknown "/.well-known/mcp-trust-registry.json" "MCPF Registry Discovery" check_wellknown "/.well-known/mcp/manifest.json" "MCP Manifest" check_wellknown "/.well-known/credentials/mcp-server.json" "MCP Credential" echo "" ``` --- ### Step 7: Validate Deployment ```bash # On llm.kis.gov.lv server cd /opt/kisc-llm/poc/deploy # Test .well-known endpoints ./scripts/validate-endpoints.sh # Expected output: # βœ… DID Document: https://llm.kis.gov.lv/.well-known/did.json # βœ… JWKS: https://llm.kis.gov.lv/.well-known/jwks.json # βœ… MCPF Registry: https://llm.kis.gov.lv/.well-known/mcp-trust-registry.json # βœ… MCP Manifest: https://llm.kis.gov.lv/.well-known/mcp/manifest.json # βœ… MCP Credential: https://llm.kis.gov.lv/.well-known/credentials/mcp-server.json ``` --- ## Part B: VeriTrust Integration ### Step 8: Submit to VeriTrust for Credential Issuance **KISC already has a VeriTrust profile!** Existing KISC DID in VeriTrust: - `did:key:z6Mkuwv1z6y2yorbBf4LEkNzJCg16ERVfWE3bJEPKXtQm7a9` (Holder DID) - `did:web:veritrust.vc:portal:company:df0684bd-b54a-4684-b3d6-93a3b1c4bcb9` (Public Alias) **Action Required:** 1. **Contact VeriTrust** via existing relationship 2. **Request MCPServerCredential** for `did:web:llm.kis.gov.lv` 3. **Provide:** - DID: `did:web:llm.kis.gov.lv` - Public Key (multibase): `z6MkjWGNnJsdyvutfbsytFJhkwDwyHkMkfWVL8X1fS1yBm2w` - MCP Endpoint: `https://llm.kis.gov.lv/mcp` - Manifest URL: `https://llm.kis.gov.lv/.well-known/mcp/manifest.json` - Organization: KISC (KultΕ«ras informācijas sistΔ“mu centrs) - Owner: KultΕ«ras ministrija - Compliance: GDPR, NIS2, Latvian Data Protection Act **Submission Payload:** See `veritrust/mcp-server-request.json` --- ### Step 9: Install VeriTrust-Issued Credential Once VeriTrust issues the credential: ```bash # On llm.kis.gov.lv server cd /opt/kisc-llm/poc/deploy # Backup placeholder cp .well-known/credentials/mcp-server.json .well-known/credentials/mcp-server.json.placeholder # Install VeriTrust credential (replace PLACEHOLDER with actual credential) cat > .well-known/credentials/mcp-server.json << 'EOF' { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://mcpf.dev/credentials/v1" ], "id": "https://llm.kis.gov.lv/.well-known/credentials/mcp-server.json", ... (VeriTrust-provided credential JSON) ... } EOF # Verify signature (use MCPF-python or manual verification) # The credential MUST be signed by did:web:veritrust.vc # Reload nginx to pick up new credential docker exec kisc-nginx nginx -s reload ``` --- ## Validation & Testing ### Local Tests (from server) ```bash # Test DID Document curl https://llm.kis.gov.lv/.well-known/did.json | jq # Test MCPF Registry Discovery curl https://llm.kis.gov.lv/.well-known/mcp-trust-registry.json | jq # Test MCP Manifest curl https://llm.kis.gov.lv/.well-known/mcp/manifest.json | jq # Test credential (placeholder until VeriTrust issues) curl https://llm.kis.gov.lv/.well-known/credentials/mcp-server.json | jq ``` ### External Tests (from any machine) ```bash # DID Resolution (W3C standard) curl https://llm.kis.gov.lv/.well-known/did.json # Should return: # { # "@context": [...], # "id": "did:web:llm.kis.gov.lv", # "verificationMethod": [...], # ... # } ``` ### AI Agent Discovery Test ```python import requests # Agent discovers MCPF-enabled MCP server registry_response = requests.get("https://llm.kis.gov.lv/.well-known/mcp-trust-registry.json") print(registry_response.json()) # Agent fetches credential for verification credential_url = registry_response.json()["services"]["mcp"]["credential"] credential = requests.get(credential_url).json() # Agent verifies signature against did:web:veritrust.vc # (Use MCPF-python for full verification) ``` --- ## Troubleshooting ### Issue: 404 on .well-known endpoints **Cause:** nginx not serving .well-known directory **Fix:** ```bash # Check nginx volume mount docker inspect kisc-nginx | grep .well-known # If missing, update docker-compose.yml: volumes: - ./.well-known:/opt/kisc-llm/poc/deploy/.well-known:ro # Restart docker restart kisc-nginx ``` --- ### Issue: CORS errors when agents try to fetch DID **Cause:** Missing CORS headers **Fix:** Ensure nginx config has: ```nginx add_header Access-Control-Allow-Origin * always; ``` --- ### Issue: Private key not found in .env **Cause:** MCPF_PRIVATE_KEY not set **Fix:** ```bash # Check .env grep MCPF_PRIVATE_KEY /opt/kisc-llm/poc/deploy/.env # If missing, extract from keypair-SECURE.json and add ``` --- ## Security Checklist Before going to production: - [ ] `keypair-SECURE.json` deleted from server (only in `.env`) - [ ] `.env` has permissions `600` (read/write by owner only) - [ ] `.well-known` files have permissions `644` (world-readable) - [ ] Private key backed up offline (encrypted) - [ ] Access control documented (who has private key) - [ ] VeriTrust credential installed (not placeholder) - [ ] All endpoints accessible via HTTPS only - [ ] nginx TLS configured correctly (Let's Encrypt) --- ## Next Steps 1. **Deploy locally** (Part A) β€” Complete Steps 1-7 2. **Submit to VeriTrust** (Part B) β€” Step 8 3. **Install credential** β€” Step 9 (after VeriTrust response) 4. **Test with AI agents** β€” Validate MCPF discovery workflow 5. **Monitor** β€” Check logs, status.sh output 6. **Document** β€” Update KISC internal documentation --- ## Support - **MCPF Specification:** https://github.com/MCPTrustFramework/MCPF-specification - **VeriTrust:** https://veritrust.vc - **Questions:** Contact Rihards (Veritrust relationship) or KISC IT team --- **Version:** 1.0 **Last Updated:** 2026-01-30 **Status:** Ready for Deployment