Skip to content

Feature: Add metadata annotations and MCP server generation for AI agent integration #92

Description

@StevenTCramer

Summary

Add the ability to annotate Nuru route definitions with metadata (access mode, safety level, tags, idempotency) and generate MCP (Model Context Protocol) servers that expose Nuru CLI commands as tools for AI agents like OpenCode.

Background

This analysis was performed from the OpenCode repository to understand how AI coding assistants consume tools.

How OpenCode Works

OpenCode uses a Tool abstraction with this schema:

interface Tool.Info {
  id: string
  init: () => Promise<{
    description: string
    parameters: ZodSchema  // Converted to JSON Schema
    execute(args, ctx): Promise<{ title, metadata, output }>
  }>
}

Tools are consumed via:

  1. Built-in tools (bash, read, edit, glob, grep, etc.)
  2. MCP servers configured in opencode.json
  3. Plugins (npm packages or local .opencode/tool/*.ts files)

Permission System

OpenCode has a permission model for bash commands using wildcard patterns:

permission: {
  edit: "allow" | "ask" | "deny",
  bash: {
    "git status*": "allow",
    "rm *": "ask",
    "*": "deny"
  }
}

The bash tool parses commands with tree-sitter and matches against these patterns. However, MCP tools have no equivalent metadata — there's no way for an MCP tool to declare "I'm a read-only operation" or "I'm destructive."

MCP Tool Annotations

MCP 1.0 spec includes tool annotations:

  • readOnlyHint
  • destructiveHint
  • idempotentHint
  • openWorldHint

These aren't fully consumed by OpenCode's permission system yet, but provide a foundation.

ACP ToolKind

OpenCode also supports ACP (Agent Client Protocol) which has a ToolKind enum: execute, edit, search, read, fetch, other. Currently this is hardcoded by tool name rather than declared by tools.

Proposed Feature

1. Route Metadata Annotations

Add fluent API for annotating routes:

builder.Map("deploy {env}", (string env) => ...)
    .WithAccess(Access.Write)           // Read, Write, Execute
    .WithSafety(Safety.Ask)             // Allow, Ask, Deny (default hint)
    .WithTags("deployment", "infra")
    .WithIdempotent(false)
    .WithCategory("infrastructure");

builder.Map("status", () => ...)
    .WithAccess(Access.Read)
    .WithSafety(Safety.Allow);

builder.Map("delete {id:int}", (int id) => ...)
    .WithAccess(Access.Write)
    .WithSafety(Safety.Ask)
    .WithDestructive(true);

2. MCP Server Generation

Add capability to run a Nuru CLI app as an MCP server:

// In Program.cs or via CLI flag
builder.RunAsMcpServer();

Or via command line:

./myapp --mcp-server

This would:

  • Expose each route as an MCP tool
  • Generate JSON Schema from route parameters and types
  • Include metadata as MCP tool annotations
  • Support stdio transport (for local) or HTTP/SSE (for remote)

3. Schema Export

Generate schema for documentation or configuration:

./myapp --export-schema > tools.json

Output format:

{
  "tools": [
    {
      "id": "deploy",
      "description": "Deploy to target environment",
      "parameters": {
        "type": "object",
        "properties": {
          "env": { "type": "string", "description": "Target environment" },
          "dryRun": { "type": "boolean" }
        },
        "required": ["env"]
      },
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false
      },
      "metadata": {
        "access": "write",
        "safety": "ask",
        "tags": ["deployment", "infrastructure"],
        "category": "infrastructure"
      }
    }
  ],
  "permissionHints": {
    "allow": ["status *", "list *", "get *"],
    "ask": ["deploy *", "delete *"],
    "deny": []
  }
}

The permissionHints section could be used to auto-generate OpenCode permission configurations.

Benefits

  1. Any Nuru CLI becomes AI-accessible — just add --mcp-server flag
  2. Safety metadata flows from code — no separate configuration needed
  3. Type-safe schema generation — parameter types from route patterns become JSON Schema
  4. Permission pattern generation — helps users configure AI agents safely
  5. Framework-agnostic — MCP is supported by OpenCode, Claude Desktop, and other AI tools

Related Protocols

Protocol Purpose Relevance
MCP Agent → Tools ✅ Primary target for this feature
ACP Editor ↔ Agent Indirect (OpenCode is an ACP agent that consumes MCP)
A2A Agent ↔ Agent Not relevant (Nuru commands are tools, not agents)

Implementation Considerations

  • Route parameter types ({id:int}, {file:FileInfo}, etc.) map to JSON Schema types
  • Optional parameters ({tag?}) become non-required in schema
  • Catch-all parameters ({*args}) become string arrays
  • Options (--verbose, --config {mode}) become boolean/typed properties
  • Descriptions ({env|Target environment}) become schema descriptions

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions