MCP server for content moderation with Claude and Cursor. App Store policy testing.
npm install @vettly/mcpMCP server for App Store Guideline 1.2 compliance. Enables AI assistants to make policy-governed, auditable content decisions.
Apple requires every iOS app with user-generated content to implement four things. The MCP server lets AI assistants participate in all four:
| Requirement | Guideline | MCP Integration |
|-------------|-----------|-----------------|
| Content filtering | 1.2.1 | moderate_content tool |
| User reporting | 1.2.2 | get_recent_decisions tool (review flagged content) |
| User blocking | 1.2.3 | Pair with server-side SDK (POST /v1/blocks) |
| Audit trail | ā | Every tool response includes decisionId |
``
Prompt: "Check if this user comment is safe for our app: 'Great product!'
Use the app-store policy."
ā moderate_content returns decisionId, action: "allow", categories, scores
`
AI assistants are increasingly used in content creation and moderation workflows. With the Vettly MCP server:
- Governed decisions - AI assistants check content against your explicit policies
- Audit trail - Every decision made by AI is recorded with a decision ID
- Policy access - Assistants can view and validate your policy configurations
- Usage visibility - Check usage stats and recent decisions
`bash`
npm install -g @vettly/mcpor run directly
npx @vettly/mcp
Add to your claude_desktop_config.json:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.json
Windows:
`json`
{
"mcpServers": {
"vettly": {
"command": "npx",
"args": ["-y", "@vettly/mcp"],
"env": {
"VETTLY_API_KEY": "sk_live_xxx"
}
}
}
}
| Variable | Required | Description |
|----------|----------|-------------|
| VETTLY_API_KEY | Yes | Your Vettly API key |VETTLY_API_URL
| | No | Custom API URL (default: https://api.vettly.dev) |
---
Check content against a Vettly policy. Returns a decision with full audit trail.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| content | string | Yes | The content to check |policyId
| | string | Yes | Policy ID to apply |contentType
| | string | No | text, image, or video (default: text) |
Example prompts:
`
Check if this text is safe: "Hello world" using the "community-safe" policy
Moderate this user comment using my default-policy:
"This product is terrible and the company should be ashamed"
Is this image appropriate for my platform? Use the strict policy.
[image URL]
`
Response includes:
- decisionId - Unique ID for audit trailaction
- - allow, warn, flag, or blockcategories
- - Array of category scores and thresholdssafe
- / flagged - Boolean indicators
---
Validate a policy YAML without saving it. Useful for testing policy changes.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| yamlContent | string | Yes | The YAML policy content |
Example prompts:
`
Validate this policy YAML:
name: my-policy
rules:
- category: hate_speech
threshold: 0.7
action: block
Check if this policy configuration is valid:
[paste YAML]
`
Response includes:
- valid - Boolean indicating if policy is validerrors
- - Array of validation errors (if any)
---
List all available policies in your account.
Parameters: None
Example prompts:
`
What policies do I have configured?
List my Vettly policies
Show me all available moderation policies
`
Response includes:
- Array of policies with id, name, version, updatedAt
---
Get usage statistics for your account.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| days | number | No | Days to include (1-365, default: 30) |
Example prompts:
`
How many moderation requests have I made this month?
Show my Vettly usage for the last 7 days
What's my content moderation cost so far?
`
Response includes:
- Request counts by content type
- Cost breakdown
- Decision outcome distribution
---
Get recent moderation decisions with optional filtering.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| limit | number | No | Results to return (1-50, default: 10) |flagged
| | boolean | No | Filter by flagged status |policyId
| | string | No | Filter by policy ID |contentType
| | string | No | Filter by content type |
Example prompts:
`
Show me the last 10 blocked content decisions
What content was flagged recently?
List recent moderation decisions for the community-safe policy
`
Response includes:
- Array of decisions with id, action, categories, createdAt
---
The MCP server exposes read-only resources for policy inspection.
List of all available policies.
``
Access the vettly://policies resource to see all policies
Specific policy YAML configuration.
`
Show me the YAML for my community-safe policy
What are the thresholds configured in default-policy?
`
---
Use the server in your own MCP applications:
`typescript
import { createVettlyMcpServer } from '@vettly/mcp'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
const server = createVettlyMcpServer({
apiKey: process.env.VETTLY_API_KEY!,
apiUrl: 'https://api.vettly.dev' // optional
})
// Connect to stdio transport (for Claude Desktop)
const transport = new StdioServerTransport()
await server.connect(transport)
// Or use with other transports
// server.connect(yourCustomTransport)
`
---
`
I'm reviewing user-submitted content for our platform. Can you check these
submissions against our community-safe policy and tell me which ones
need manual review?
1. "Great product, highly recommend!"
2. "This is garbage, you people are idiots"
3. "Love the new features in this update"
`
`
I want to create a new policy for our support chat. Can you help me
write the YAML and then validate it?
Requirements:
- Block hate speech with threshold 0.6
- Flag harassment for review at 0.7
- Allow profanity up to 0.8
`
``
Can you check our moderation usage this week and let me know if we're
on track for our monthly budget?
``
A user is appealing a content decision. Can you look up decision ID
abc-123 and explain why their content was blocked?
---
- API keys are passed via environment variables, not in config files
- The MCP server only has read access to policies (cannot create/modify)
- Decision IDs can be used for audit trails but don't expose content
---
1. Sign up at vettly.dev
2. Go to Dashboard > API Keys
3. Create and copy your key
4. Set as VETTLY_API_KEY` environment variable (see Configuration above)
---
- vettly.dev - Sign up
- docs.vettly.dev - Documentation
- MCP Specification - MCP docs
- @vettly/sdk - Core SDK