Skip to main content
Glama
by pangeacyber
vault.ts8.69 kB
import type { FastMCP } from 'fastmcp'; import { PangeaConfig, VaultService } from 'pangea-node-sdk'; import { z } from 'zod'; import type { FastMCPSessionAuth, ServerContext } from '../types.js'; const VAULT_ITEM_ID_REGEX = /^pvi_[a-z2-7]{32}$/; export function registerVaultTools< T extends FastMCPSessionAuth = FastMCPSessionAuth, >({ server, context }: { server: FastMCP<T>; context: ServerContext }) { server.addTool({ name: 'get_vault_item', description: 'Retrieve details for a Vault key, secret, token, or folder.', parameters: z.object({ id: z .string() .regex(VAULT_ITEM_ID_REGEX) .describe('ID of a Vault key, secret, token, or folder'), }), execute: async ({ id }) => { const vault = new VaultService( context.apiToken, new PangeaConfig({ domain: 'aws.us.pangea.cloud' }) ); const response = await vault.getItem({ id }); if (!response.success) { return { content: [ { type: 'text', text: 'Failed to get Vault item', }, ], }; } return { content: [ { type: 'text', text: `Result:\n\n${JSON.stringify(response.result, null, 2)}`, }, ], }; }, }); server.addTool({ name: 'list_vault_items', description: 'Retrieve an array of Vault items matching a given filter, including secrets, keys, tokens, and folders, along with their common details.', parameters: z.object({ filter: z .object({}) .partial() .describe( 'Filters to customize your search, for example:\n```\n{\n "folder": "/encryption",\n "tags": "personal",\n "name__contains": "my",\n "created_at__gt": "2020-03-11"\n}\n```' ), size: z .number() .optional() .describe('Maximum number of items in the response'), order: z .enum(['asc', 'desc']) .optional() .describe('Direction for ordering the results'), order_by: z .enum([ 'id', 'type', 'created_at', 'algorithm', 'purpose', 'expiration', 'last_rotated', 'next_rotation', 'name', 'folder', 'item_state', ]) .optional() .describe('Property by which to order the results'), last: z .string() .optional() .describe( 'Internal ID returned in the previous look up response. Used for pagination.' ), }), execute: async ({ filter, size, order, order_by, last }) => { const vault = new VaultService( context.apiToken, new PangeaConfig({ domain: 'aws.us.pangea.cloud' }) ); const response = await vault.list({ filter, size, // @ts-expect-error order, // @ts-expect-error order_by, last, }); if (!response.success) { return { content: [ { type: 'text', text: 'Failed to list items', }, ], }; } return { content: [ { type: 'text', text: `Result:\n\n${JSON.stringify(response.result, null, 2)}`, }, ], }; }, }); server.addTool({ name: 'delete_vault_item', description: 'Delete a Vault key, secret, token, or folder.', parameters: z.object({ id: z .string() .regex(VAULT_ITEM_ID_REGEX) .describe('ID of a Vault key, secret, token, or folder'), }), execute: async ({ id }) => { const vault = new VaultService( context.apiToken, new PangeaConfig({ domain: 'aws.us.pangea.cloud' }) ); const response = await vault.delete(id); if (!response.success) { return { content: [ { type: 'text', text: 'Failed to delete Vault item', }, ], }; } return { content: [ { type: 'text', text: `Result:\n\n${JSON.stringify(response.result, null, 2)}`, }, ], }; }, }); server.addTool({ name: 'generate_key', description: 'Generate a symmetric or asymmetric key.', parameters: z.object({ type: z.enum(['asymmetric_key', 'symmetric_key']), purpose: z .union([ z .enum(['signing', 'encryption', 'jwt', 'pki']) .describe('Asymmetric key purpose'), z .enum(['encryption', 'jwt', 'fpe']) .describe('Symmetric key purpose'), ]) .describe('Purpose of the key:'), algorithm: z.union([ z .enum([ 'ED25519', 'RSA-PKCS1V15-2048-SHA256', 'ES256', 'ES384', 'ES512', 'ES256K', 'RSA-PSS-2048-SHA256', 'RSA-PSS-3072-SHA256', 'RSA-PSS-4096-SHA256', 'RSA-PSS-4096-SHA512', 'ED25519-DILITHIUM2-BETA', 'ED448-DILITHIUM3-BETA', 'SPHINCSPLUS-128F-SHAKE256-SIMPLE-BETA', 'SPHINCSPLUS-128F-SHAKE256-ROBUST-BETA', 'SPHINCSPLUS-128F-SHA256-SIMPLE-BETA', 'SPHINCSPLUS-128F-SHA256-ROBUST-BETA', 'SPHINCSPLUS-192F-SHAKE256-SIMPLE-BETA', 'SPHINCSPLUS-192F-SHAKE256-ROBUST-BETA', 'SPHINCSPLUS-192F-SHA256-SIMPLE-BETA', 'SPHINCSPLUS-192F-SHA256-ROBUST-BETA', 'SPHINCSPLUS-256F-SHAKE256-SIMPLE-BETA', 'SPHINCSPLUS-256F-SHAKE256-ROBUST-BETA', 'SPHINCSPLUS-256F-SHA256-SIMPLE-BETA', 'SPHINCSPLUS-256F-SHA256-ROBUST-BETA', 'FALCON-1024-BETA', ]) .describe('Algorithm for type=asymmetric_key, purpose=signing'), z .enum([ 'RSA-OAEP-2048-SHA1', 'RSA-OAEP-2048-SHA256', 'RSA-OAEP-2048-SHA512', 'RSA-OAEP-3072-SHA1', 'RSA-OAEP-3072-SHA256', 'RSA-OAEP-3072-SHA512', 'RSA-OAEP-4096-SHA1', 'RSA-OAEP-4096-SHA256', 'RSA-OAEP-4096-SHA512', ]) .describe('Algorithm for type=asymmetric_key, purpose=encryption'), z .enum(['ES256', 'ES384', 'ES512']) .describe('Algorithm for type=asymmetric_key, purpose=jwt'), z .enum([ 'ED25519', 'RSA-2048-SHA256', 'RSA-3072-SHA256', 'RSA-4096-SHA256', 'RSA-PSS-2048-SHA256', 'RSA-PSS-3072-SHA256', 'RSA-PSS-4096-SHA256', 'RSA-PSS-4096-SHA512', 'ECDSA-SHA256', 'ECDSA-SHA384', 'ECDSA-SHA512', ]) .describe('Algorithm for type=asymmetric_key, purpose=pki'), z .enum([ 'AES-CFB-128', 'AES-CFB-256', 'AES-GCM-256', 'AES-CBC-128', 'AES-CBC-256', ]) .describe('Algorithm for type=symmetric_key, purpose=encryption'), z .enum(['HS256', 'HS384', 'HS512']) .describe('Algorithm for type=symmetric_key, purpose=jwt'), z .enum(['AES-FF3-1-128-BETA', 'AES-FF3-1-256-BETA']) .describe('Algorithm for type=symmetric_key, purpose=fpe'), ]), name: z.string(), folder: z.string().optional(), }), execute: async ({ type, purpose, algorithm, name, folder }) => { const vault = new VaultService( context.apiToken, new PangeaConfig({ domain: 'aws.us.pangea.cloud' }) ); const response = type === 'asymmetric_key' ? await vault.asymmetricGenerate({ // @ts-expect-error purpose, // @ts-expect-error algorithm, name, folder, }) : await vault.symmetricGenerate({ // @ts-expect-error purpose, // @ts-expect-error algorithm, name, folder, }); if (!response.success) { return { content: [ { type: 'text', text: 'Failed to generate key', }, ], }; } return { content: [ { type: 'text', text: `Result:\n\n${JSON.stringify(response.result, null, 2)}`, }, ], }; }, }); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pangeacyber/pangea-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server