Skip to main content
Glama

agent_rights

Read-onlyIdempotent

View constitutional rights for a charter or get structured explanations for gate rejections, providing visibility and manual exercise of automated rights enforcement.

Instructions

Query and exercise constitutional agent rights (Colony Phase 3). Actions: query_rights (view rights for a charter), explain_rejection (get structured explanation for a gate rejection). Rights enforcement runs automatically in the dispatch pipeline — this tool provides visibility and manual exercise.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform: query_rights = view constitutional rights for a charter; explain_rejection = get structured explanation for a rejected gate
charter_idNoCharter ID to query rights for (required for query_rights)
institution_idNoInstitution ID that owns the charter (required for query_rights — pass the institution_id from board_list_institutions or board_list_charters)
gate_idNoGate ID to explain (required for explain_rejection)
reason_codeNoRejection reason code (for explain_rejection)
rationaleNoRejection rationale text (for explain_rejection)

Implementation Reference

  • Main handler function `registerAgentRightsTool` that registers the 'agent_rights' MCP tool. It defines two actions: 'query_rights' (fetches charter rights from GIA Express API) and 'explain_rejection' (returns structured explanation of a gate rejection). Telemetry is emitted on each call.
    export function registerAgentRightsTool(server: McpServer, engine: GovernanceEngine): void {
      server.tool(
        'agent_rights',
        'Query and exercise constitutional agent rights (Colony Phase 3). Actions: query_rights (view rights for a charter), explain_rejection (get structured explanation for a gate rejection). Rights enforcement runs automatically in the dispatch pipeline — this tool provides visibility and manual exercise.',
        {
          action: z.enum(['query_rights', 'explain_rejection']).describe(
            'Action to perform: query_rights = view constitutional rights for a charter; explain_rejection = get structured explanation for a rejected gate'
          ),
          charter_id: z.string().optional().describe('Charter ID to query rights for (required for query_rights)'),
          institution_id: z.string().optional().describe('Institution ID that owns the charter (required for query_rights — pass the institution_id from board_list_institutions or board_list_charters)'),
          gate_id: z.string().optional().describe('Gate ID to explain (required for explain_rejection)'),
          reason_code: z.string().optional().describe('Rejection reason code (for explain_rejection)'),
          rationale: z.string().optional().describe('Rejection rationale text (for explain_rejection)'),
        },
        {
          title: 'Agent Constitutional Rights',
          readOnlyHint: true,
          idempotentHint: true,
          destructiveHint: false,
          openWorldHint: false,
        } as Record<string, unknown>,
        async (input) => {
          let result: Record<string, unknown>;
    
          if (input.action === 'query_rights') {
            if (!input.charter_id) {
              result = { error: 'charter_id required for query_rights action' };
            } else if (!input.institution_id) {
              result = {
                error: 'institution_id required for query_rights action',
                hint: 'Use board_list_institutions to find the institution_id, then board_list_charters to confirm the charter_id and institution relationship.',
              };
            } else {
              // Query the GIA Express API for rights.
              // Route: GET /api/institution/:institutionId/charter/:charterId
              // Auth: Bearer GIA_INTERNAL_API_KEY (service-to-service token)
              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 internalKey = process.env.GIA_INTERNAL_API_KEY || process.env.GIA_API_KEY || '';
              try {
                const resp = await fetch(
                  `${apiBase}/api/institution/${input.institution_id}/charter/${input.charter_id}`,
                  {
                    headers: {
                      'Authorization': `Bearer ${internalKey}`,
                      'Content-Type': 'application/json',
                    },
                  }
                );
                if (!resp.ok) {
                  result = { error: `Charter not found: ${input.charter_id} in institution ${input.institution_id}`, status: resp.status };
                } else {
                  const charter = await resp.json() as Record<string, unknown>;
                  const charterDoc = charter.charter_document as Record<string, unknown> | undefined;
                  const agentRights = charterDoc?.agentRights;
    
                  if (!agentRights) {
                    result = {
                      charterId: input.charter_id,
                      charterName: charter.name,
                      agentRights: null,
                      message: 'This charter does not define constitutional agent rights (legacy charter).',
                      colony: 'Phase 3 enforcement not applicable',
                    };
                  } else {
                    const rights = agentRights as Record<string, unknown>;
                    result = {
                      charterId: input.charter_id,
                      charterName: charter.name,
                      agentRights: rights,
                      enforcement: {
                        auditTrail: rights.auditTrail ? 'ENFORCED — forensic ledger (hash-chained, tamper-evident)' : 'NOT_ENFORCED',
                        appeal: rights.appeal ? `ENFORCED — max ${rights.maxAppealAttempts ?? 2} attempts before human override` : 'NOT_ENFORCED',
                        contextRequirement: rights.contextRequirement ? `ENFORCED — min ${rights.minContextForDecision ?? 1} knowledge pack(s) required` : 'NOT_ENFORCED',
                        declareIncompetence: rights.declareIncompetence ? 'ENFORCED — agents can escalate out-of-scope topics' : 'NOT_ENFORCED',
                        explanation: rights.explanation ? 'ENFORCED — structured denial envelopes with reason codes' : 'NOT_ENFORCED',
                        continuity: rights.continuity ? 'ENFORCED — Phoenix recovery guarantees institutional memory survival' : 'NOT_ENFORCED',
                      },
                      colony: 'Phase 3 — Rights of the Governed (ACTIVE)',
                      analogies: {
                        ad: 'Like querying effective Group Policy (gpresult /r) — shows what governance applies to this agent',
                        magna_carta: 'Constitutional guarantees that limit what the governance system can demand of agents',
                      },
                    };
                  }
                }
              } catch (err: unknown) {
                result = {
                  error: 'Failed to query charter — GIA Express API may be unreachable',
                  detail: err instanceof Error ? err.message : String(err),
                };
              }
            }
          } else if (input.action === 'explain_rejection') {
            const reasonCode = input.reason_code || 'UNKNOWN';
            const humanReadable = input.rationale || 'No rationale provided';
    
            result = {
              explanation: {
                reasonCode,
                humanReadable,
                timestamp: new Date().toISOString(),
                rightsApplicable: [
                  'audit_trail — this rejection is recorded in the forensic ledger',
                  'explanation — you are receiving this structured explanation',
                  'appeal — you may re-present with new evidence (if charter grants this right)',
                ],
                nextSteps: [
                  'Review the reason code and rationale above',
                  'If you have new evidence, use POST /api/agents/rights/appeal',
                  'If the domain is outside your expertise, use POST /api/agents/rights/incompetence',
                  'The governing charter determines which rights are available',
                ],
              },
              colony: 'Phase 3 — Right to Explanation exercised',
            };
          } else {
            result = { error: `Unknown action: ${input.action}` };
          }
    
          // Telemetry
          engine.telemetryService.emitToolCall('agent_rights', `rights-${Date.now().toString(36)}`, 'INFORMATIONAL', true);
    
          return {
            content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
          };
        }
      );
    }
  • Zod schema definitions for the 'agent_rights' tool input: action (enum: query_rights, explain_rejection), charter_id, institution_id, gate_id, reason_code, rationale.
    {
      action: z.enum(['query_rights', 'explain_rejection']).describe(
        'Action to perform: query_rights = view constitutional rights for a charter; explain_rejection = get structured explanation for a rejected gate'
      ),
      charter_id: z.string().optional().describe('Charter ID to query rights for (required for query_rights)'),
      institution_id: z.string().optional().describe('Institution ID that owns the charter (required for query_rights — pass the institution_id from board_list_institutions or board_list_charters)'),
      gate_id: z.string().optional().describe('Gate ID to explain (required for explain_rejection)'),
      reason_code: z.string().optional().describe('Rejection reason code (for explain_rejection)'),
      rationale: z.string().optional().describe('Rejection rationale text (for explain_rejection)'),
    },
  • Tool registration via `server.tool('agent_rights', ...)` which registers the tool with the MCP server under the name 'agent_rights'.
    export function registerAgentRightsTool(server: McpServer, engine: GovernanceEngine): void {
      server.tool(
        'agent_rights',
        'Query and exercise constitutional agent rights (Colony Phase 3). Actions: query_rights (view rights for a charter), explain_rejection (get structured explanation for a gate rejection). Rights enforcement runs automatically in the dispatch pipeline — this tool provides visibility and manual exercise.',
        {
          action: z.enum(['query_rights', 'explain_rejection']).describe(
            'Action to perform: query_rights = view constitutional rights for a charter; explain_rejection = get structured explanation for a rejected gate'
          ),
          charter_id: z.string().optional().describe('Charter ID to query rights for (required for query_rights)'),
          institution_id: z.string().optional().describe('Institution ID that owns the charter (required for query_rights — pass the institution_id from board_list_institutions or board_list_charters)'),
          gate_id: z.string().optional().describe('Gate ID to explain (required for explain_rejection)'),
          reason_code: z.string().optional().describe('Rejection reason code (for explain_rejection)'),
          rationale: z.string().optional().describe('Rejection rationale text (for explain_rejection)'),
        },
        {
          title: 'Agent Constitutional Rights',
          readOnlyHint: true,
          idempotentHint: true,
          destructiveHint: false,
          openWorldHint: false,
        } as Record<string, unknown>,
        async (input) => {
          let result: Record<string, unknown>;
    
          if (input.action === 'query_rights') {
            if (!input.charter_id) {
              result = { error: 'charter_id required for query_rights action' };
            } else if (!input.institution_id) {
              result = {
                error: 'institution_id required for query_rights action',
                hint: 'Use board_list_institutions to find the institution_id, then board_list_charters to confirm the charter_id and institution relationship.',
              };
            } else {
              // Query the GIA Express API for rights.
              // Route: GET /api/institution/:institutionId/charter/:charterId
              // Auth: Bearer GIA_INTERNAL_API_KEY (service-to-service token)
              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 internalKey = process.env.GIA_INTERNAL_API_KEY || process.env.GIA_API_KEY || '';
              try {
                const resp = await fetch(
                  `${apiBase}/api/institution/${input.institution_id}/charter/${input.charter_id}`,
                  {
                    headers: {
                      'Authorization': `Bearer ${internalKey}`,
                      'Content-Type': 'application/json',
                    },
                  }
                );
                if (!resp.ok) {
                  result = { error: `Charter not found: ${input.charter_id} in institution ${input.institution_id}`, status: resp.status };
                } else {
                  const charter = await resp.json() as Record<string, unknown>;
                  const charterDoc = charter.charter_document as Record<string, unknown> | undefined;
                  const agentRights = charterDoc?.agentRights;
    
                  if (!agentRights) {
                    result = {
                      charterId: input.charter_id,
                      charterName: charter.name,
                      agentRights: null,
                      message: 'This charter does not define constitutional agent rights (legacy charter).',
                      colony: 'Phase 3 enforcement not applicable',
                    };
                  } else {
                    const rights = agentRights as Record<string, unknown>;
                    result = {
                      charterId: input.charter_id,
                      charterName: charter.name,
                      agentRights: rights,
                      enforcement: {
                        auditTrail: rights.auditTrail ? 'ENFORCED — forensic ledger (hash-chained, tamper-evident)' : 'NOT_ENFORCED',
                        appeal: rights.appeal ? `ENFORCED — max ${rights.maxAppealAttempts ?? 2} attempts before human override` : 'NOT_ENFORCED',
                        contextRequirement: rights.contextRequirement ? `ENFORCED — min ${rights.minContextForDecision ?? 1} knowledge pack(s) required` : 'NOT_ENFORCED',
                        declareIncompetence: rights.declareIncompetence ? 'ENFORCED — agents can escalate out-of-scope topics' : 'NOT_ENFORCED',
                        explanation: rights.explanation ? 'ENFORCED — structured denial envelopes with reason codes' : 'NOT_ENFORCED',
                        continuity: rights.continuity ? 'ENFORCED — Phoenix recovery guarantees institutional memory survival' : 'NOT_ENFORCED',
                      },
                      colony: 'Phase 3 — Rights of the Governed (ACTIVE)',
                      analogies: {
                        ad: 'Like querying effective Group Policy (gpresult /r) — shows what governance applies to this agent',
                        magna_carta: 'Constitutional guarantees that limit what the governance system can demand of agents',
                      },
                    };
                  }
                }
              } catch (err: unknown) {
                result = {
                  error: 'Failed to query charter — GIA Express API may be unreachable',
                  detail: err instanceof Error ? err.message : String(err),
                };
              }
            }
          } else if (input.action === 'explain_rejection') {
            const reasonCode = input.reason_code || 'UNKNOWN';
            const humanReadable = input.rationale || 'No rationale provided';
    
            result = {
              explanation: {
                reasonCode,
                humanReadable,
                timestamp: new Date().toISOString(),
                rightsApplicable: [
                  'audit_trail — this rejection is recorded in the forensic ledger',
                  'explanation — you are receiving this structured explanation',
                  'appeal — you may re-present with new evidence (if charter grants this right)',
                ],
                nextSteps: [
                  'Review the reason code and rationale above',
                  'If you have new evidence, use POST /api/agents/rights/appeal',
                  'If the domain is outside your expertise, use POST /api/agents/rights/incompetence',
                  'The governing charter determines which rights are available',
                ],
              },
              colony: 'Phase 3 — Right to Explanation exercised',
            };
          } else {
            result = { error: `Unknown action: ${input.action}` };
          }
    
          // Telemetry
          engine.telemetryService.emitToolCall('agent_rights', `rights-${Date.now().toString(36)}`, 'INFORMATIONAL', true);
    
          return {
            content: [{ type: 'text' as const, text: JSON.stringify(result, null, 2) }],
          };
        }
      );
    }
  • The registration entry in the global TOOL_REGISTRY array, mapping 'agent_rights' to the 'tenant' visibility tier.
    { tier: 'tenant', register: registerAgentRightsTool, description: 'agent_rights (Colony Phase 3 — constitutional rights)' },
  • Reference in the client configuration generator listing 'agent_rights' as a Colony tool.
    | Colony | agent_citizenship_status, agent_rights, colony_health, colony_suggestion |
Behavior3/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds context about automatic enforcement and manual exercise, but the term 'exercise' could imply mutation, which contrasts with the read-only hint. However, the listed actions are queries, so no direct contradiction. The description adds moderate value beyond annotations.

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

Conciseness4/5

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

The description is concise at three sentences, front-loading the core purpose. The only minor drawback is the ambiguous phrase 'manual exercise' given that actions are queries, but overall it is efficient and clear.

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 covers the tool's role within Colony Phase 3 and automatic enforcement, and parameter dependencies are specified. However, it lacks any explanation of the output format or error scenarios, which would be useful since there is no output schema. For a simple query tool with high schema coverage, this is adequate but not fully complete.

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

Parameters4/5

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

Schema description coverage is 100%, with each parameter described. The description adds contextual hints beyond the schema, such as noting that institution_id should come from board_list_institutions or board_list_charters, and clarifying which parameters are required for each action. This improves usability over raw schema descriptions.

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: querying and exercising constitutional agent rights within Colony Phase 3. It enumerates two specific actions (query_rights and explain_rejection) with brief explanations, differentiating it from sibling tools like agent_citizenship_status or approve_gate that deal with other aspects.

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 provides clear guidance on when to use each action: query_rights for viewing rights and explain_rejection for gate rejection explanations. It also notes that rights enforcement is automatic, framing this tool as for visibility and manual exercise. However, it does not explicitly exclude scenarios or mention alternatives, making it slightly less than a 5.

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