Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 5 additions & 12 deletions mastra-test-app/docs/DEPLOYMENT_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This guide provides an exact, copy‑pasteable sequence to deploy `mastra-test-a
- Google Cloud project with billing enabled
- `gcloud` CLI installed and authenticated
- API keys: OpenAI, Anthropic, Exa
- PostgreSQL connection URL (Neon or other)
- PostgreSQL connection URL (currently Neon)

---

Expand Down Expand Up @@ -72,7 +72,7 @@ NODE_ENV=production
EOF
```

### 6) Build and (optionally) apply migrations
### 7) Build and (optionally) apply migrations
```bash
# Build the app and prepare Prisma client in the output
pnpm build
Expand All @@ -81,9 +81,9 @@ pnpm build
npx prisma migrate deploy
```

### 7) Start the application
### 8) Start the application
```bash
pnpm start
pnpm dev
```

The server listens on `0.0.0.0:4111`. In another terminal:
Expand All @@ -94,13 +94,6 @@ EXTERNAL_IP=$(gcloud compute instances describe mastra-app \
echo "http://$EXTERNAL_IP:4111/auth/login"
```

Optional: keep it running with PM2
```bash
sudo npm install -g pm2
pm2 start "pnpm start" --name mastra-app
pm2 startup && pm2 save
```

---

### Notes
Expand All @@ -111,4 +104,4 @@ pm2 startup && pm2 save
### Troubleshooting
- Prisma client errors: ensure you ran `pnpm build`. If needed, run `npx prisma generate` once, then `pnpm build` again.
- Firewall: verify with `gcloud compute firewall-rules list --filter="name~allow-mastra-app"`.
- Logs: if using PM2, run `pm2 logs mastra-app`; otherwise, observe terminal output from `pnpm start`.
- Logs: if using PM2, run `pm2 logs mastra-app`; otherwise, observe terminal output from `pnpm dev`.
14 changes: 12 additions & 2 deletions mastra-test-app/src/mastra/agents/web-automation-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { databaseTools } from '../tools/database-tools';
import { google } from '@ai-sdk/google';
import { openai } from '@ai-sdk/openai';

const base = process.env.DB_BASE || "../";
// Path is relative to .mastra/output/ when bundled
const storage = new LibSQLStore({
url: "file:../mastra.db",
Expand All @@ -27,7 +26,7 @@ const memory = new Memory({
lastMessages: 10,
workingMemory: {
enabled: true,
scope: 'resource',
scope: 'thread',
template: `
- **Name**
- **Description**
Expand Down Expand Up @@ -98,6 +97,17 @@ export const webAutomationAgent = new Agent({
- Do not fill optional fields unless specified
- Submit only when all required fields are complete

**Screenshot Protocol:**
- Take a screenshot after completing all fields on a page
- Use fullPage: true to capture the complete viewport including off-screen content
- Do NOT take screenshots for individual form interactions
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a note I have is not taking screenshots of security risk ones like SSN. Most forms will hide this after they enter in their SSN with *** but there are less technical advance forms that do not have this feature

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I agree, the defensible approach is to not take a screenshot. However if the form is a single page this means we are not able to visually confirm.

There are targeted approaches to taking screenshots as well:

https://playwright.dev/docs/screenshots#element-screenshot

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving as is for now based on standup conversation, but underscoring this as a security consideration along with other artifacts (traces, snapshots).

- NEVER specify a filename parameter - let the system auto-generate timestamps

Example screenshot tool call:
browser_take_screenshot({
fullPage: true
})

**Autonomous Progression:**
PROCEED AUTOMATICALLY for:
- Navigation buttons (Next, Continue, Get Started, Proceed, Begin)
Expand Down
40 changes: 21 additions & 19 deletions mastra-test-app/src/mastra/mcp.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
import 'dotenv/config';
import { MCPClient } from "@mastra/mcp";

// Create separate clients for different tool sets
const buildPlaywrightArgs = () => {

const args = [
"@playwright/mcp@latest",
"--isolated",
"--browser=chromium",
"--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
"--viewport-size=1920,1080",
"--no-sandbox",
"--output-dir=artifacts",
"--save-session",
"--save-trace"
];

return args;
};

export const playwrightMCP = new MCPClient({
servers: {
playwright: {
command: "npx",
args: ["@playwright/mcp@latest", "--isolated"],
args: buildPlaywrightArgs(),
env: {
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
}
},
},
});
Expand All @@ -22,20 +41,3 @@ export const exaMCP = new MCPClient({
},
},
});

// Combined client for agents that need all tools
export const mcp = new MCPClient({
servers: {
playwright: {
command: "npx",
args: ["@playwright/mcp@latest", "--isolated"],
},
exa: {
command: "npx",
args: ["-y", "exa-mcp-server"],
env: {
EXA_API_KEY: process.env.EXA_API_KEY!
},
},
},
});
4 changes: 2 additions & 2 deletions mastra-test-app/src/mastra/tools/research-tools.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { createTool } from '@mastra/core/tools';
import { z } from 'zod';
import { mcp } from '../mcp';
import { exaMCP } from '../mcp';

// Get EXA tools from MCP
const exaTools = await mcp.getTools();
const exaTools = await exaMCP.getTools();

// Service/Program Research Tool - for finding government services, programs, applications
export const serviceResearchTool = createTool({
Expand Down