Skip to main content
Glama

colony_health

Idempotent

Assess colony health by viewing current score, 30-day trend, or triggering an on-demand snapshot. Score reflects agent distribution, merit, deliberation, gate efficiency, and compliance.

Instructions

Colony Autonomy: View colony health score, trend over time, or trigger an on-demand health snapshot. Actions: snapshot (latest health), trend (30-day history), pulse (trigger fresh snapshot). Health score computed from agent distribution, merit averages, deliberation quality, gate efficiency, and constitutional compliance.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction: snapshot = latest health; trend = 30-day history; pulse = trigger fresh assessment
institution_idNoInstitution ID for scoped health (omit for colony-wide)
daysNoDays of trend history (default: 30)

Implementation Reference

  • The colony_health tool handler: calls internal API to get snapshot, trend, or pulse health data.
        title: 'Colony Convene Request',
        readOnlyHint: false,
        idempotentHint: false,
        destructiveHint: false,
        openWorldHint: false,
      } as Record<string, unknown>,
      async (input) => {
        const apiBase = process.env.GIA_API_URL || 'http://localhost:3001';
        // GIA_INTERNAL_API_KEY = server-side name; GIA_API_KEY = MCP container name (same value)
        const apiKey = process.env.GIA_INTERNAL_API_KEY || process.env.GIA_API_KEY || '';
        let result: Record<string, unknown>;
    
        try {
          const headers: Record<string, string> = {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${apiKey}`,
          };
    
          if (input.action === 'request') {
            if (!input.topic || !input.institution_id) {
              result = { error: 'topic and institution_id required for request action' };
            } else {
              const resp = await fetch(
                `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/convene-request`,
                {
                  method: 'POST',
                  headers,
                  body: JSON.stringify({
                    topic: input.topic,
                    rationale: input.rationale,
                    urgency: input.urgency || 'normal',
                    institutionId: input.institution_id,
                  }),
                },
              );
              result = await resp.json() as Record<string, unknown>;
            }
          } else if (input.action === 'list') {
            const params = new URLSearchParams();
            if (input.status_filter) params.set('status', input.status_filter);
            const resp = await fetch(
              `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/convene-requests?${params}`,
              { headers },
            );
            result = await resp.json() as Record<string, unknown>;
          } else if (input.action === 'review') {
            if (!input.request_id || !input.decision) {
              result = { error: 'request_id and decision required for review action' };
            } else {
              const resp = await fetch(
                `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/convene-request/${encodeURIComponent(input.request_id)}/review`,
                {
                  method: 'POST',
                  headers,
                  body: JSON.stringify({ decision: input.decision, notes: input.notes }),
                },
              );
              result = await resp.json() as Record<string, unknown>;
            }
          } else {
            result = { error: 'Unknown action' };
          }
        } catch (err: unknown) {
          result = { error: `Colony convene request failed: ${(err as Error).message}` };
        }
    
        return {
          content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
        };
      },
    );
    
    // ═══════════════════════════════════════════════════════════════
    // colony_suggestion — Amendment suggestion lifecycle
    // ═══════════════════════════════════════════════════════════════
    
    server.tool(
      'colony_suggestion',
      'Colony Autonomy: Suggest, list, review, or upvote charter amendment suggestions. Actions: suggest (citizen+ can propose changes), list (view suggestions for a charter), review (elder+ can promote to formal amendment or decline), upvote (citizen+ can signal support). The petition mechanism for governed agents.',
      {
        action: z.enum(['suggest', 'list', 'review', 'upvote']).describe(
          'Action: suggest = propose change; list = view suggestions; review = elder+ review; upvote = signal support'
        ),
        charter_id: z.string().describe('Charter ID'),
        institution_id: z.string().optional().describe('Institution ID (required for suggest action)'),
        summary: z.string().optional().describe('What you want changed (required for suggest action)'),
        detailed_rationale: z.string().optional().describe('Why this change is needed'),
        affected_sections: z.array(z.string()).optional().describe('Charter sections impacted'),
        suggestion_id: z.string().optional().describe('Suggestion ID (required for review/upvote)'),
        decision: z.enum(['under_review', 'promoted', 'declined']).optional().describe('Review decision'),
        feedback: z.string().optional().describe('Review feedback'),
        status_filter: z.enum(['open', 'under_review', 'promoted', 'declined', 'withdrawn']).optional(),
      },
      {
        title: 'Colony Amendment Suggestion',
        readOnlyHint: false,
        idempotentHint: false,
        destructiveHint: false,
        openWorldHint: false,
      } as Record<string, unknown>,
      async (input) => {
        const apiBase = process.env.GIA_API_URL || 'http://localhost:3001';
        // GIA_INTERNAL_API_KEY = server-side name; GIA_API_KEY = MCP container name (same value)
        const apiKey = process.env.GIA_INTERNAL_API_KEY || process.env.GIA_API_KEY || '';
        let result: Record<string, unknown>;
    
        try {
          const headers: Record<string, string> = {
            'Content-Type': 'application/json',
          };
          headers['Authorization'] = `Bearer ${apiKey}`;
    
          if (input.action === 'suggest') {
            if (!input.summary || !input.institution_id) {
              result = { error: 'summary and institution_id required for suggest action' };
            } else {
              const resp = await fetch(
                `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/suggestion`,
                {
                  method: 'POST',
                  headers,
                  body: JSON.stringify({
                    summary: input.summary,
                    detailedRationale: input.detailed_rationale,
                    affectedSections: input.affected_sections,
                    institutionId: input.institution_id,
                  }),
                },
              );
              result = await resp.json() as Record<string, unknown>;
            }
          } else if (input.action === 'list') {
            const params = new URLSearchParams();
            if (input.status_filter) params.set('status', input.status_filter);
            const resp = await fetch(
              `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/suggestions?${params}`,
              { headers },
            );
            result = await resp.json() as Record<string, unknown>;
          } else if (input.action === 'review') {
            if (!input.suggestion_id || !input.decision) {
              result = { error: 'suggestion_id and decision required for review action' };
            } else {
              const resp = await fetch(
                `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/suggestion/${encodeURIComponent(input.suggestion_id)}/review`,
                {
                  method: 'POST',
                  headers,
                  body: JSON.stringify({ decision: input.decision, feedback: input.feedback }),
                },
              );
              result = await resp.json() as Record<string, unknown>;
            }
          } else if (input.action === 'upvote') {
            if (!input.suggestion_id) {
              result = { error: 'suggestion_id required for upvote action' };
            } else {
              const resp = await fetch(
                `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/suggestion/${encodeURIComponent(input.suggestion_id)}/upvote`,
                {
                  method: 'POST',
                  headers,
                },
              );
              result = await resp.json() as Record<string, unknown>;
            }
          } else {
            result = { error: 'Unknown action' };
          }
        } catch (err: unknown) {
          result = { error: `Colony suggestion failed: ${(err as Error).message}` };
        }
    
        return {
          content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
        };
      },
    );
    
    // ═══════════════════════════════════════════════════════════════
    // colony_health — Colony-wide health monitoring
    // ═══════════════════════════════════════════════════════════════
    
    server.tool(
      'colony_health',
      'Colony Autonomy: View colony health score, trend over time, or trigger an on-demand health snapshot. Actions: snapshot (latest health), trend (30-day history), pulse (trigger fresh snapshot). Health score computed from agent distribution, merit averages, deliberation quality, gate efficiency, and constitutional compliance.',
  • Zod schema defining input parameters for colony_health: action (enum: snapshot/trend/pulse), institution_id (optional string), days (optional number 1-365).
    {
      action: z.enum(['snapshot', 'trend', 'pulse']).describe(
        'Action: snapshot = latest health; trend = 30-day history; pulse = trigger fresh assessment'
      ),
      institution_id: z.string().optional().describe('Institution ID for scoped health (omit for colony-wide)'),
      days: z.number().min(1).max(365).optional().describe('Days of trend history (default: 30)'),
    },
  • The registerColonyTools function exported and wired in src/mcp/server.ts (line 117) as a tenant-tier tool registration.
    export function registerColonyTools(server: McpServer, engine: GovernanceEngine): void {
    
      // ═══════════════════════════════════════════════════════════════
      // colony_convene_request — Session request lifecycle
      // ═══════════════════════════════════════════════════════════════
    
      server.tool(
        'colony_convene_request',
        'Colony Autonomy: Request, list, or review agent-initiated session convene requests. Actions: request (citizen+ can request a governed session), list (view pending/all requests for a charter), review (elder+ approve/reject a request). Tier-gated: agents earn the right to request and approve sessions through demonstrated merit.',
        {
          action: z.enum(['request', 'list', 'review']).describe(
            'Action: request = submit a convene request; list = view requests; review = approve/reject a request'
          ),
          charter_id: z.string().describe('Charter ID for the request'),
          institution_id: z.string().optional().describe('Institution ID (required for request action)'),
          topic: z.string().optional().describe('Topic for the requested session (required for request action)'),
          rationale: z.string().optional().describe('Why this session is needed'),
          urgency: z.enum(['low', 'normal', 'high', 'critical']).optional().describe('Urgency level (default: normal)'),
          request_id: z.string().optional().describe('Convene request ID (required for review action)'),
          decision: z.enum(['approved', 'rejected']).optional().describe('Review decision (required for review action)'),
          notes: z.string().optional().describe('Review notes'),
          status_filter: z.enum(['pending', 'approved', 'rejected', 'convened', 'expired']).optional().describe('Filter for list action'),
        },
        {
          title: 'Colony Convene Request',
          readOnlyHint: false,
          idempotentHint: false,
          destructiveHint: false,
          openWorldHint: false,
        } as Record<string, unknown>,
        async (input) => {
          const apiBase = process.env.GIA_API_URL || 'http://localhost:3001';
          // GIA_INTERNAL_API_KEY = server-side name; GIA_API_KEY = MCP container name (same value)
          const apiKey = process.env.GIA_INTERNAL_API_KEY || process.env.GIA_API_KEY || '';
          let result: Record<string, unknown>;
    
          try {
            const headers: Record<string, string> = {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${apiKey}`,
            };
    
            if (input.action === 'request') {
              if (!input.topic || !input.institution_id) {
                result = { error: 'topic and institution_id required for request action' };
              } else {
                const resp = await fetch(
                  `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/convene-request`,
                  {
                    method: 'POST',
                    headers,
                    body: JSON.stringify({
                      topic: input.topic,
                      rationale: input.rationale,
                      urgency: input.urgency || 'normal',
                      institutionId: input.institution_id,
                    }),
                  },
                );
                result = await resp.json() as Record<string, unknown>;
              }
            } else if (input.action === 'list') {
              const params = new URLSearchParams();
              if (input.status_filter) params.set('status', input.status_filter);
              const resp = await fetch(
                `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/convene-requests?${params}`,
                { headers },
              );
              result = await resp.json() as Record<string, unknown>;
            } else if (input.action === 'review') {
              if (!input.request_id || !input.decision) {
                result = { error: 'request_id and decision required for review action' };
              } else {
                const resp = await fetch(
                  `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/convene-request/${encodeURIComponent(input.request_id)}/review`,
                  {
                    method: 'POST',
                    headers,
                    body: JSON.stringify({ decision: input.decision, notes: input.notes }),
                  },
                );
                result = await resp.json() as Record<string, unknown>;
              }
            } else {
              result = { error: 'Unknown action' };
            }
          } catch (err: unknown) {
            result = { error: `Colony convene request failed: ${(err as Error).message}` };
          }
    
          return {
            content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
          };
        },
      );
    
      // ═══════════════════════════════════════════════════════════════
      // colony_suggestion — Amendment suggestion lifecycle
      // ═══════════════════════════════════════════════════════════════
    
      server.tool(
        'colony_suggestion',
        'Colony Autonomy: Suggest, list, review, or upvote charter amendment suggestions. Actions: suggest (citizen+ can propose changes), list (view suggestions for a charter), review (elder+ can promote to formal amendment or decline), upvote (citizen+ can signal support). The petition mechanism for governed agents.',
        {
          action: z.enum(['suggest', 'list', 'review', 'upvote']).describe(
            'Action: suggest = propose change; list = view suggestions; review = elder+ review; upvote = signal support'
          ),
          charter_id: z.string().describe('Charter ID'),
          institution_id: z.string().optional().describe('Institution ID (required for suggest action)'),
          summary: z.string().optional().describe('What you want changed (required for suggest action)'),
          detailed_rationale: z.string().optional().describe('Why this change is needed'),
          affected_sections: z.array(z.string()).optional().describe('Charter sections impacted'),
          suggestion_id: z.string().optional().describe('Suggestion ID (required for review/upvote)'),
          decision: z.enum(['under_review', 'promoted', 'declined']).optional().describe('Review decision'),
          feedback: z.string().optional().describe('Review feedback'),
          status_filter: z.enum(['open', 'under_review', 'promoted', 'declined', 'withdrawn']).optional(),
        },
        {
          title: 'Colony Amendment Suggestion',
          readOnlyHint: false,
          idempotentHint: false,
          destructiveHint: false,
          openWorldHint: false,
        } as Record<string, unknown>,
        async (input) => {
          const apiBase = process.env.GIA_API_URL || 'http://localhost:3001';
          // GIA_INTERNAL_API_KEY = server-side name; GIA_API_KEY = MCP container name (same value)
          const apiKey = process.env.GIA_INTERNAL_API_KEY || process.env.GIA_API_KEY || '';
          let result: Record<string, unknown>;
    
          try {
            const headers: Record<string, string> = {
              'Content-Type': 'application/json',
            };
            headers['Authorization'] = `Bearer ${apiKey}`;
    
            if (input.action === 'suggest') {
              if (!input.summary || !input.institution_id) {
                result = { error: 'summary and institution_id required for suggest action' };
              } else {
                const resp = await fetch(
                  `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/suggestion`,
                  {
                    method: 'POST',
                    headers,
                    body: JSON.stringify({
                      summary: input.summary,
                      detailedRationale: input.detailed_rationale,
                      affectedSections: input.affected_sections,
                      institutionId: input.institution_id,
                    }),
                  },
                );
                result = await resp.json() as Record<string, unknown>;
              }
            } else if (input.action === 'list') {
              const params = new URLSearchParams();
              if (input.status_filter) params.set('status', input.status_filter);
              const resp = await fetch(
                `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/suggestions?${params}`,
                { headers },
              );
              result = await resp.json() as Record<string, unknown>;
            } else if (input.action === 'review') {
              if (!input.suggestion_id || !input.decision) {
                result = { error: 'suggestion_id and decision required for review action' };
              } else {
                const resp = await fetch(
                  `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/suggestion/${encodeURIComponent(input.suggestion_id)}/review`,
                  {
                    method: 'POST',
                    headers,
                    body: JSON.stringify({ decision: input.decision, feedback: input.feedback }),
                  },
                );
                result = await resp.json() as Record<string, unknown>;
              }
            } else if (input.action === 'upvote') {
              if (!input.suggestion_id) {
                result = { error: 'suggestion_id required for upvote action' };
              } else {
                const resp = await fetch(
                  `${apiBase}/api/colony/${encodeURIComponent(input.charter_id)}/suggestion/${encodeURIComponent(input.suggestion_id)}/upvote`,
                  {
                    method: 'POST',
                    headers,
                  },
                );
                result = await resp.json() as Record<string, unknown>;
              }
            } else {
              result = { error: 'Unknown action' };
            }
          } catch (err: unknown) {
            result = { error: `Colony suggestion failed: ${(err as Error).message}` };
          }
    
          return {
            content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
          };
        },
      );
    
      // ═══════════════════════════════════════════════════════════════
      // colony_health — Colony-wide health monitoring
      // ═══════════════════════════════════════════════════════════════
    
      server.tool(
        'colony_health',
        'Colony Autonomy: View colony health score, trend over time, or trigger an on-demand health snapshot. Actions: snapshot (latest health), trend (30-day history), pulse (trigger fresh snapshot). Health score computed from agent distribution, merit averages, deliberation quality, gate efficiency, and constitutional compliance.',
        {
          action: z.enum(['snapshot', 'trend', 'pulse']).describe(
            'Action: snapshot = latest health; trend = 30-day history; pulse = trigger fresh assessment'
          ),
          institution_id: z.string().optional().describe('Institution ID for scoped health (omit for colony-wide)'),
          days: z.number().min(1).max(365).optional().describe('Days of trend history (default: 30)'),
        },
        {
          title: 'Colony Health Monitor',
          readOnlyHint: false,
          idempotentHint: true,
          destructiveHint: false,
          openWorldHint: false,
        } as Record<string, unknown>,
        async (input) => {
          const apiBase = process.env.GIA_API_URL || 'http://localhost:3001';
          // GIA_INTERNAL_API_KEY = server-side name; GIA_API_KEY = MCP container name (same value)
          const apiKey = process.env.GIA_INTERNAL_API_KEY || process.env.GIA_API_KEY || '';
          let result: Record<string, unknown>;
    
          try {
            const headers: Record<string, string> = {
              'Content-Type': 'application/json',
            };
            headers['Authorization'] = `Bearer ${apiKey}`;
    
            if (input.action === 'snapshot') {
              const params = new URLSearchParams();
              if (input.institution_id) params.set('institutionId', input.institution_id);
              const resp = await fetch(`${apiBase}/api/colony/health?${params}`, { headers });
              result = await resp.json() as Record<string, unknown>;
            } else if (input.action === 'trend') {
              const params = new URLSearchParams();
              if (input.days) params.set('days', String(input.days));
              if (input.institution_id) params.set('institutionId', input.institution_id);
              const resp = await fetch(`${apiBase}/api/colony/health/trend?${params}`, { headers });
              result = await resp.json() as Record<string, unknown>;
            } else if (input.action === 'pulse') {
              const resp = await fetch(`${apiBase}/api/colony/health/snapshot`, {
                method: 'POST',
                headers,
              });
              result = await resp.json() as Record<string, unknown>;
            } else {
              result = { error: 'Unknown action' };
            }
          } catch (err: unknown) {
            result = { error: `Colony health check failed: ${(err as Error).message}` };
          }
    
          return {
            content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
          };
        },
      );
  • Registration entry in server.ts linking registerColonyTools to the 'tenant' tier.
    { tier: 'tenant', register: registerColonyTools, description: 'colony (convene_request, suggestion, health — Colony Autonomy)' },
Behavior4/5

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

Annotations already indicate idempotentHint=true and readOnlyHint=false. The description adds valuable context by explaining that the 'pulse' action triggers a fresh snapshot, implying a non-read side effect, and details the computation factors. This goes beyond the annotations.

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 concise with two sentences. The first sentence states the overall purpose, and the second lists actions and composition. No wasted words.

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

Completeness4/5

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

The description provides enough context for the three actions and their outputs, though it does not detail the exact return format. Given the tool's simplicity and absence of output schema, it is adequately complete.

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

Parameters3/5

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

Schema coverage is 100% with descriptions for all parameters. The description reinforces the action enum and explains the 30-day default for trend but adds little beyond the schema. Baseline 3 is appropriate.

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

Purpose5/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: viewing colony health score, trend, or triggering a snapshot. It specifies three distinct actions (snapshot, trend, pulse), making it highly specific and easily distinguishable from sibling tools like system_status or phoenix_recovery_health.

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

Usage Guidelines4/5

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

The description explicitly lists the three actions and their meanings, providing clear guidance on when to use each. However, it does not exclude other tools or provide comparison with alternatives like system_status, so it lacks explicit when-not-to-use guidance.

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/knowledgepa3/gia-mcp-server'

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