Skip to main content
Glama
OpenZeppelin

OpenZeppelin Contracts MCP Server

Official
by OpenZeppelin

solidity-governor

Generate smart contract code for implementing DAO governance with configurable voting parameters, timelocks, and upgradeability options.

Instructions

Make a contract to implement governance, such as for a DAO.

Returns the source code of the generated contract, formatted in a Markdown code block. Does not write to disk.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameYesThe name of the contract
delayYesThe delay since proposal is created until voting starts, default is "1 day"
periodYesThe length of period during which people can cast their vote, default is "1 week"
votesNoThe type of voting to use
clockModeNoThe clock mode used by the voting token. For Governor, this must be chosen to match what the ERC20 or ERC721 voting token uses.
timelockNoThe type of timelock to use
blockTimeNoThe block time of the chain, default is 12
decimalsNoThe number of decimals to use for the contract, default is 18 for ERC20Votes and 0 for ERC721Votes (because it does not apply to ERC721Votes)
proposalThresholdNoMinimum number of votes an account must have to create a proposal, default is 0.
quorumModeNoThe type of quorum mode to use
quorumPercentNoThe percent required, in cases of quorumMode equals percent
quorumAbsoluteNoThe absolute quorum required, in cases of quorumMode equals absolute
storageNoEnable storage of proposal details and enumerability of proposals
settingsNoAllow governance to update voting settings (delay, period, proposal threshold)
upgradeableNoWhether the smart contract is upgradeable. Transparent uses more complex proxy with higher overhead, requires less changes in your contract. Can also be used with beacons. UUPS uses simpler proxy with less overhead, requires including extra code in your contract. Allows flexibility for authorizing upgrades.
infoNoMetadata about the contract and author

Implementation Reference

  • Handler function that destructures input parameters, constructs GovernorOptions, and generates Solidity code using OpenZeppelin Wizard's governor.print() inside safePrintSolidityCodeBlock.
    async ({
      name,
      delay,
      period,
      votes,
      clockMode,
      timelock,
      blockTime,
      decimals,
      proposalThreshold,
      quorumMode,
      quorumPercent,
      quorumAbsolute,
      storage,
      settings,
      upgradeable,
      info,
    }) => {
      const opts: GovernorOptions = {
        name,
        delay,
        period,
        votes,
        clockMode,
        timelock,
        blockTime,
        decimals,
        proposalThreshold,
        quorumMode,
        quorumPercent,
        quorumAbsolute,
        storage,
        settings,
        upgradeable,
        info,
      };
      return {
        content: [
          {
            type: 'text',
            text: safePrintSolidityCodeBlock(() => governor.print(opts)),
          },
        ],
      };
    },
  • Zod schema for validating inputs to the solidity-governor tool, defining all GovernorOptions fields with descriptions.
    export const governorSchema = {
      name: z.string().describe(commonDescriptions.name),
      delay: z.string().describe(solidityGovernorDescriptions.delay),
      period: z.string().describe(solidityGovernorDescriptions.period),
      votes: z.literal('erc20votes').or(z.literal('erc721votes')).optional().describe(solidityGovernorDescriptions.votes),
      clockMode: z
        .literal('blocknumber')
        .or(z.literal('timestamp'))
        .optional()
        .describe(solidityGovernorDescriptions.clockMode),
      timelock: z
        .literal(false)
        .or(z.literal('openzeppelin'))
        .or(z.literal('compound'))
        .optional()
        .describe(solidityGovernorDescriptions.timelock),
      blockTime: z.number().optional().describe(solidityGovernorDescriptions.blockTime),
      decimals: z.number().optional().describe(solidityGovernorDescriptions.decimals),
      proposalThreshold: z.string().optional().describe(solidityGovernorDescriptions.proposalThreshold),
      quorumMode: z
        .literal('percent')
        .or(z.literal('absolute'))
        .optional()
        .describe(solidityGovernorDescriptions.quorumMode),
      quorumPercent: z.number().optional().describe(solidityGovernorDescriptions.quorumPercent),
      quorumAbsolute: z.string().optional().describe(solidityGovernorDescriptions.quorumAbsolute),
      storage: z.boolean().optional().describe(solidityGovernorDescriptions.storage),
      settings: z.boolean().optional().describe(solidityGovernorDescriptions.settings),
      upgradeable: commonSchema.upgradeable,
      info: commonSchema.info,
    } as const satisfies z.ZodRawShape;
  • Registers the solidity-governor tool on the MCP server with its name, detailed prompt, schema, and handler function.
    export function registerSolidityGovernor(server: McpServer): RegisteredTool {
      return server.tool(
        'solidity-governor',
        makeDetailedPrompt(solidityPrompts.Governor),
        governorSchema,
        async ({
          name,
          delay,
          period,
          votes,
          clockMode,
          timelock,
          blockTime,
          decimals,
          proposalThreshold,
          quorumMode,
          quorumPercent,
          quorumAbsolute,
          storage,
          settings,
          upgradeable,
          info,
        }) => {
          const opts: GovernorOptions = {
            name,
            delay,
            period,
            votes,
            clockMode,
            timelock,
            blockTime,
            decimals,
            proposalThreshold,
            quorumMode,
            quorumPercent,
            quorumAbsolute,
            storage,
            settings,
            upgradeable,
            info,
          };
          return {
            content: [
              {
                type: 'text',
                text: safePrintSolidityCodeBlock(() => governor.print(opts)),
              },
            ],
          };
        },
      );
    }
  • Includes the governor tool registration in the getRegisterFunctions map, called by registerSolidityTools.
      Governor: () => registerSolidityGovernor(server),
      Custom: () => registerSolidityCustom(server),
    };
  • Calls registerSolidityTools which ultimately registers all Solidity tools including solidity-governor.
    registerSolidityTools(server);
Behavior3/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 adds some context: it specifies that the tool 'Returns the source code of the generated contract, formatted in a Markdown code block' and 'Does not write to disk,' which clarifies the output format and non-destructive nature. However, it lacks details on permissions, rate limits, error handling, or other behavioral traits, leaving gaps for a mutation-like tool.

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 appropriately sized with two sentences: the first states the purpose, and the second specifies the output format and non-destructive behavior. It's front-loaded with the main action and avoids unnecessary details. However, it could be slightly more structured by explicitly separating purpose from behavioral notes, but it's still efficient.

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

Completeness3/5

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

Given the complexity (16 parameters, no output schema, no annotations), the description is minimally adequate. It covers the purpose and key behavioral aspects (output format, non-destructive), but for a tool generating governance contracts with many configurable options, it lacks guidance on usage, prerequisites, or error handling. The absence of an output schema means the description doesn't explain return values, which is a gap, but it partially compensates by stating the output format.

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?

The input schema has 100% description coverage, so the schema already documents all 16 parameters thoroughly. The description adds no parameter-specific information beyond what the schema provides. According to the rules, with high schema coverage (>80%), the baseline is 3 even with no param info in the description, which applies here.

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: 'Make a contract to implement governance, such as for a DAO.' It specifies the action ('Make a contract') and the resource/domain ('governance, such as for a DAO'). However, it doesn't explicitly differentiate from sibling tools like 'solidity-custom' or 'cairo-governor' beyond the 'solidity-' prefix in the name, which is why it doesn't reach a perfect 5.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'solidity-custom' (for custom contracts) or 'cairo-governor' (for governance in Cairo), nor does it specify prerequisites or exclusions. The only usage hint is implicit in the domain ('governance'), but this is insufficient for clear decision-making.

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/OpenZeppelin/contracts-wizard'

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