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