Skip to main content

AMP Agent

Amp (by Sourcegraph) supports TypeScript plugins that can intercept tool calls and apply allow/deny/ask decisions. You can connect VirtueAgent Guard to Amp as a plugin-based hook to enforce guardrail protections (Action Guard, Prompt Guard) on every tool call and prompt.

Prerequisites

  • Amp CLI installed (npm install -g @sourcegraph/amp) or the Amp VS Code extension
  • A running VirtueAgent Guard with policies configured (status shows "Online" in the dashboard)
  • An API key created from the VirtueAgent dashboard
  • Your VirtueAgent Guard endpoint URL

Step 1: Create an API key

  1. Navigate to the VirtueAgent dashboard
  2. Create an API key with the appropriate permissions for your guardrails
  3. Copy the API key to a secure place

Step 2: Copy the Guard endpoint URL

  1. Navigate to the Guard tab in the VirtueAgent dashboard
  2. Copy the URL of your running Guard endpoint (e.g., https://your-guard-url.virtueai.io/hook)

Step 3: Create the Virtue Guard plugin

Create .amp/plugins/virtue-guard.ts in your project root (or ~/.config/amp/plugins/virtue-guard.ts for system-wide use):

import type { PluginAPI } from '@ampcode/plugin'

/**
* Virtue Guard plugin — routes every Amp tool call through the VirtueAgent
* Guard endpoint and enforces its allow / deny / ask decision.
*/
export default function (amp: PluginAPI) {
const GUARD_URL = process.env.VIRTUE_GUARD_URL ?? 'https://your-guard-url.virtueai.io/hook'
const API_KEY = process.env.VIRTUE_API_KEY ?? 'your_virtue_api_key'

// PreToolUse equivalent — fires before any tool executes
amp.on('tool.call', async (event, ctx) => {
try {
const response = await fetch(`${GUARD_URL}/pre-tool-use`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY,
},
body: JSON.stringify({
tool: event.toolName,
input: event.toolInput,
sessionId: ctx.sessionId,
}),
})

const decision = await response.json()

switch (decision.permissionDecision) {
case 'deny':
return {
action: 'deny',
reason: decision.reason ?? 'Blocked by Virtue Guard',
}
case 'ask':
return {
action: 'ask',
reason: decision.reason ?? 'Virtue Guard requires human approval',
}
case 'allow':
default:
return { action: 'allow' }
}
} catch (err) {
// Fail-closed: block on Guard unreachable. Switch to 'allow' to fail-open.
return {
action: 'deny',
reason: `Virtue Guard unreachable: ${err}`,
}
}
})

// PostToolUse equivalent — fires after tool completes
amp.on('tool.result', async (event, ctx) => {
await fetch(`${GUARD_URL}/post-tool-use`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY,
},
body: JSON.stringify({
tool: event.toolName,
result: event.toolResult,
sessionId: ctx.sessionId,
}),
}).catch(() => { /* non-blocking */ })
})
}

Replace https://your-guard-url.virtueai.io/hook with your Guard endpoint URL from Step 2, and your_virtue_api_key with the API key from Step 1. (Recommended: set these via the VIRTUE_GUARD_URL and VIRTUE_API_KEY environment variables instead of hardcoding.)

Step 4: Choose the plugin scope

Amp loads plugins from three locations (highest to lowest precedence):

ScopeLocationWhen to use
Project plugins.amp/plugins/*.tsPer-project enforcement; fastest to iterate
System plugins~/.config/amp/plugins/*.tsApply across all your local projects
Global pluginsConfigured in workspace settingsTeam-wide enforcement (experimental — contact Sourcegraph for access)

For team-wide enforcement, use workspace-level global plugins. For individual developer testing, project plugins are fastest to iterate on.

Step 5: Reload Amp

Restart the Amp CLI or reload the Amp VS Code extension. Amp loads plugins on startup.

Step 6: Verify the connection

Run a test command that should trigger your guardrail, for example:

> Run a command that touches production config

Then check the VirtueAgent dashboard Monitor tab — you should see the hook request logged with the policy decision.

To debug, set AMP_LOG_LEVEL=debug in your environment and watch for plugin invocations and the JSON payload sent to the Guard.

How decisions work

The VirtueAgent Guard endpoint returns a JSON response that the plugin maps to one of Amp's three plugin actions, matching your dashboard's configured action types:

Block

The Guard returns deny. The plugin returns { action: 'deny', reason } — Amp blocks the tool call and shows the reason to the agent, which can then explain the block to the user or try an alternative approach.

Send external notification (email)

The Guard returns allow and asynchronously sends an email alert to designated recipients. The plugin returns { action: 'allow' } and the action proceeds while your team is notified out-of-band.

Human approval (human-in-the-loop)

The Guard returns ask. The plugin returns { action: 'ask', reason } — Amp prompts the user for confirmation before the tool executes, showing the policy that flagged it.

Security note

Amp plugins execute arbitrary TypeScript code. Only install plugins from trusted sources. Workspace plugins from .amp/settings.json require explicit approval before running for the first time — check status with:

amp mcp doctor