Skip to main content
Glama
AlyssonM

HiveAuth MCP Server

by AlyssonM

refresh_credential

Renew expiring or expired verifiable credentials using W3C Credential Refresh specification. Supports automatic service discovery and credential lifecycle management within the HiveAuth ecosystem.

Instructions

Refresh expiring or expired credentials using W3C Credential Refresh specification. Supports automatic service discovery and credential lifecycle management.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
credentialIdYes
refreshServiceNo

Implementation Reference

  • Main handler function executing the refresh_credential tool. Validates input, calls HiveAuth refresh API, compares old/new credentials, generates comprehensive markdown summary with validity analysis, security info, and JSON output.
    export async function refreshCredential(args: any): Promise<CallToolResult> {
      // Validate and sanitize input
      const validation = validateAndSanitizeInput(RefreshCredentialInputSchema, args, 'refresh_credential');
      
      if (!validation.success) {
        return createValidationErrorResult(validation.error!);
      }
    
      const data = validation.data!;
      const { credentialId, refreshService } = data;
    
      const HIVEAUTH_API_BASE_URL = process.env.HIVEAUTH_API_BASE_URL || 'http://localhost:3000';
      const REFRESH_ENDPOINT = `${HIVEAUTH_API_BASE_URL}/api/refresh`;
    
      try {
        console.log(`[RefreshCredential] Starting credential refresh for: ${credentialId}`);
    
        const payload = {
          credentialId,
          ...(refreshService && { refreshService })
        };
    
        const response = await fetch(REFRESH_ENDPOINT, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(payload),
        });
    
        if (!response.ok) {
          const errorData = await response.json().catch(() => ({ message: response.statusText }));
          throw new Error(`Failed to refresh credential: ${errorData.message}`);
        }
    
        const result = await response.json();
    
        // Analyze the refresh operation
        const oldCredential = result.originalCredential;
        const newCredential = result.refreshedCredential;
        const refreshInfo = result.refreshInfo || {};
    
        const summary = [
          `πŸ”„ **Credential Refresh Results**`,
          ``,
          `β€’ Original Credential ID: ${credentialId}`,
          `β€’ New Credential ID: ${newCredential?.id || 'Generated automatically'}`,
          `β€’ Refresh Method: ${refreshInfo.method || 'W3C Credential Refresh'}`,
          `β€’ Refresh Service: ${refreshInfo.serviceEndpoint || refreshService || 'Auto-discovered'}`,
          `β€’ Refresh Status: ${result.success ? 'βœ… Successful' : '❌ Failed'}`,
          ``
        ];
    
        if (result.success && oldCredential && newCredential) {
          // Compare expiration dates
          const oldExpiry = oldCredential.expirationDate || oldCredential.validUntil;
          const newExpiry = newCredential.expirationDate || newCredential.validUntil;
          
          summary.push(`**πŸ“… Validity Period Comparison:**`);
          if (oldExpiry) {
            summary.push(`β€’ Original Expiry: ${oldExpiry}`);
            const wasExpired = new Date(oldExpiry) < new Date();
            summary.push(`β€’ Original Status: ${wasExpired ? '❌ Expired' : '⚠️ Expiring soon'}`);
          } else {
            summary.push(`β€’ Original Expiry: No expiration date set`);
          }
          
          if (newExpiry) {
            summary.push(`β€’ New Expiry: ${newExpiry}`);
            const timeUntilExpiry = new Date(newExpiry).getTime() - new Date().getTime();
            const daysUntilExpiry = Math.ceil(timeUntilExpiry / (1000 * 60 * 60 * 24));
            summary.push(`β€’ New Status: βœ… Valid for ${daysUntilExpiry} more days`);
          } else {
            summary.push(`β€’ New Expiry: No expiration date (indefinite validity)`);
          }
          summary.push(``);
    
          // Compare credential content
          summary.push(`**πŸ” Content Comparison:**`);
          const contentChanges = compareCredentialContent(oldCredential, newCredential);
          if (contentChanges.length === 0) {
            summary.push(`β€’ Content: βœ… Unchanged (only validity period updated)`);
          } else {
            summary.push(`β€’ Content: ⚠️ ${contentChanges.length} changes detected`);
            contentChanges.forEach((change, index) => {
              summary.push(`  ${index + 1}. ${change}`);
            });
          }
          summary.push(``);
    
          // Issuer and signature information
          summary.push(`**πŸ” Security Information:**`);
          summary.push(`β€’ Original Issuer: ${getIssuerInfo(oldCredential)}`);
          summary.push(`β€’ New Issuer: ${getIssuerInfo(newCredential)}`);
          summary.push(`β€’ Issuer Consistency: ${getIssuerInfo(oldCredential) === getIssuerInfo(newCredential) ? 'βœ… Same issuer' : '⚠️ Different issuer'}`);
          
          if (newCredential.proof) {
            summary.push(`β€’ New Signature: βœ… Fresh cryptographic signature`);
            summary.push(`β€’ Proof Type: ${newCredential.proof.type || 'Unknown'}`);
          }
          summary.push(``);
    
          // Refresh service information
          if (refreshInfo.serviceDiscovered) {
            summary.push(`**πŸ”Ž Service Discovery:**`);
            summary.push(`β€’ Service Discovery: βœ… Automatic discovery successful`);
            summary.push(`β€’ Discovered Endpoint: ${refreshInfo.serviceEndpoint}`);
            summary.push(`β€’ Discovery Method: ${refreshInfo.discoveryMethod || 'DID Document'}`);
            summary.push(``);
          }
    
          // Chain of trust
          if (result.trustChain) {
            summary.push(`**πŸ”— Trust Chain:**`);
            summary.push(`β€’ Original credential linked: βœ… Cryptographic reference maintained`);
            summary.push(`β€’ Chain integrity: ${result.trustChain.valid ? 'βœ… Valid' : '❌ Broken'}`);
            summary.push(`β€’ Refresh authorization: ${result.trustChain.authorized ? 'βœ… Authorized' : '❌ Unauthorized'}`);
            summary.push(``);
          }
        } else if (!result.success) {
          summary.push(`**❌ Refresh Failed:**`);
          summary.push(`β€’ Reason: ${result.error || 'Unknown error'}`);
          if (result.retryable) {
            summary.push(`β€’ Retry Possible: βœ… Yes, try again later`);
            summary.push(`β€’ Suggested Retry: ${result.retryAfter || 'No specific time suggested'}`);
          } else {
            summary.push(`β€’ Retry Possible: ❌ No, manual intervention required`);
          }
          summary.push(``);
        }
    
        // Usage recommendations
        summary.push(`**πŸ’‘ Next Steps:**`);
        if (result.success) {
          summary.push(`β€’ Replace the original credential with the refreshed version`);
          summary.push(`β€’ Update any stored references to use the new credential ID`);
          summary.push(`β€’ Verify the refreshed credential independently`);
          summary.push(`β€’ Set up monitoring for the new expiration date`);
          if (result.originalCredential) {
            summary.push(`β€’ Consider revoking the original credential if policy requires it`);
          }
        } else {
          summary.push(`β€’ Check credential refresh service availability`);
          summary.push(`β€’ Verify the credential is eligible for refresh`);
          summary.push(`β€’ Contact the issuer if automatic refresh fails`);
          summary.push(`β€’ Consider manual credential renewal process`);
        }
    
        return {
          content: [
            {
              type: 'text',
              text: summary.join('\n')
            },
            {
              type: 'text',
              text: `\`\`\`json\n${JSON.stringify({
                refreshSummary: {
                  credentialId,
                  success: result.success,
                  refreshMethod: refreshInfo.method,
                  serviceEndpoint: refreshInfo.serviceEndpoint,
                  originalExpiry: oldCredential?.expirationDate || oldCredential?.validUntil,
                  newExpiry: newCredential?.expirationDate || newCredential?.validUntil,
                  contentChanges: result.success ? compareCredentialContent(oldCredential, newCredential).length : 0
                },
                refreshedCredential: result.success ? newCredential : null,
                refreshInfo: refreshInfo
              }, null, 2)}\n\`\`\``
            }
          ]
        };
      } catch (error: any) {
        // Check if it's a network error (HiveAuth API not available)
        if (error.message.includes('fetch failed') || error.message.includes('ECONNREFUSED')) {
          return {
            content: [
              {
                type: 'text',
                text: `πŸ”„ **Credential Refresh (Simulation Mode)**\n\n` +
                      `Since the HiveAuth API is not available, here's what the credential refresh would accomplish:\n\n` +
                      `**Input Analysis:**\n` +
                      `β€’ Credential ID: ${credentialId}\n` +
                      `β€’ Refresh Service: ${refreshService || 'Auto-discovery from credential'}\n\n` +
                      `**Expected Refresh Process:**\n` +
                      `β€’ Locate credential by ID in the system\n` +
                      `β€’ Check expiration status and refresh eligibility\n` +
                      `β€’ Discover or use specified refresh service endpoint\n` +
                      `β€’ Request new credential with extended validity period\n` +
                      `β€’ Maintain credential content while updating temporal properties\n` +
                      `β€’ Generate fresh cryptographic signatures\n\n` +
                      `**W3C Credential Refresh Benefits:**\n` +
                      `β€’ Automated credential lifecycle management\n` +
                      `β€’ Seamless validity period extension\n` +
                      `β€’ Maintains trust chain and cryptographic integrity\n` +
                      `β€’ Reduces manual intervention for routine renewals\n\n` +
                      `**To enable full refresh:** Ensure HiveAuth API is running at ${HIVEAUTH_API_BASE_URL}`
              }
            ]
          };
        }
    
        return {
          content: [
            {
              type: 'text',
              text: `Failed to refresh credential: ${error.message}`
            }
          ],
          isError: true
        };
      }
    }
  • Zod schema defining the input parameters for the refresh_credential tool: credentialId (required string) and optional refreshService URL.
    export const RefreshCredentialInputSchema = z.object({
      credentialId: z.string().min(1, 'Credential ID is required'),
      refreshService: z.string().url('Refresh service URL must be valid').optional()
    });
  • Tool registration in TOOL_DEFINITIONS array, converted to MCP Tool via createMCPTools() for listing available tools.
    name: 'refresh_credential',
    description: 'Refresh expiring or expired credentials using W3C Credential Refresh specification. Supports automatic service discovery and credential lifecycle management.',
    inputSchema: TOOL_SCHEMAS.refresh_credential
  • src/index.ts:110-111 (registration)
    Dispatch registration in the MCP server request handler switch statement, mapping tool name to handler execution.
    case 'refresh_credential':
      return await refreshCredential(args);
  • Schema registration in TOOL_SCHEMAS lookup object used by schemaConverter.ts.
    refresh_credential: RefreshCredentialInputSchema,
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions 'automatic service discovery' and 'credential lifecycle management,' which adds some context about how the tool operates. However, it fails to disclose critical behavioral traits such as whether this is a read-only or mutating operation, potential side effects (e.g., credential updates), authentication needs, rate limits, or error handling. This is a significant gap for a tool that likely modifies credential states.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded: two concise sentences that directly state the tool's purpose and key features. Every sentence earns its place by providing essential information without redundancy or fluff, making it easy to scan and understand quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (credential refresh with potential side effects), no annotations, no output schema, and 0% schema coverage, the description is incomplete. It lacks details on parameters, behavioral traits (e.g., mutation effects), return values, and explicit differentiation from siblings. For a tool that likely involves credential state changes, this leaves too many gaps for reliable agent use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for undocumented parameters. It does not mention any parameters or their meanings (e.g., 'credentialId' or 'refreshService'), leaving both parameters unexplained. The description adds no value beyond the schema, failing to clarify what inputs are needed or how they relate to the tool's purpose.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Refresh expiring or expired credentials' using a specific specification (W3C Credential Refresh). It includes a verb ('Refresh') and resource ('credentials'), and distinguishes from siblings like 'issue_credential' or 'revoke_credential' by focusing on renewal rather than creation or revocation. However, it doesn't explicitly contrast with all siblings (e.g., 'derive_credential' might overlap in lifecycle management).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context ('expiring or expired credentials') and mentions 'automatic service discovery and credential lifecycle management,' which suggests when to use itβ€”for maintaining valid credentials. However, it lacks explicit guidance on when not to use it (e.g., vs. 'issue_credential' for new credentials) or named alternatives, leaving some ambiguity compared to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/AlyssonM/hiveauth-mcp'

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