Skip to content

Try fix the workers observability prompts to make Claude Sonet more effective #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Apr 30, 2025
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
24 changes: 5 additions & 19 deletions apps/workers-observability/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,27 +59,13 @@ export class ObservabilityMCP extends McpAgent<Env, State, Props> {
sentry: initSentryWithUser(env, this.ctx, this.props.user.id),
options: {
instructions: `# Cloudflare Workers Observability Tool
* A cloudflare worker is a serverless function
* Workers Observability is the tool to inspect the logs for your cloudflare Worker
* Each log is a structured JSON payload with keys and values

This tool provides powerful capabilities to analyze and troubleshoot your Cloudflare Workers through logs and metrics. Here's how to use it effectively:

## IMPORTANT: Query Discipline

**STOP after the first successful query if it answers the user's question.** Do not run multiple queries unless absolutely necessary. The first query often contains the answer - review it thoroughly before running additional queries.

## Best Practices

### Efficient Querying
- Start with a focused query that's most likely to answer the question
- Review results completely before deciding if additional queries are needed
- If the first query provides the answer, STOP and present it to the user
- Only run additional queries when specifically directed or when essential information is missing

### When to STOP Querying
- STOP after presenting meaningful results from the first query
- STOP when you've answered the user's specific question
- STOP when the user hasn't requested additional exploration
- Only continue if explicitly directed with "EXPLORE" or similar instruction
`,
This server allows you to analyze your Cloudflare Workers logs and metrics.
`,
},
})

Expand Down
54 changes: 3 additions & 51 deletions apps/workers-observability/src/tools/observability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,8 @@ export function registerObservabilityTools(agent: ObservabilityMCP) {
'query_worker_observability',
`Query the Workers Observability API to analyze logs and metrics from your Cloudflare Workers.

The resulting information should answer the users query. STOP HERE and show them the answer to there question.
If you can't answer the question ask for a follow up.

## Output handling

Once you have ran this query you must IMMEDIATELY present the user with this information.

- **Events**: Display as a table with key fields. For detailed inspection, show full JSON of individual events.
- **Calculations**: Use appropriate charts based on the data (bar charts for comparisons, line charts for time series)
- **Invocations**: Show full request/response details with syntax highlighting for important fields

## When to Use This tool

- Investigate errors or performance issues in your Cloudflare Workers
- Monitor Worker usage patterns and resource consumption
- Debug specific request failures or unexpected behaviors
- Verify recent deployments are working as expected
- Generate performance reports for specific Workers or endpoints
- Track down user-reported issues with request ID or user information
- Analyze trends in response times, error rates, or request volumes

* A query typical query looks like this:
{"view":"events","queryId":"workers-logs-events","limit":5,"dry":true,"parameters":{"datasets":["cloudflare-workers"],"filters":[{"id":"520","key":"message","operation":"eq","type":"string","value":"Clickhouse Statistics"},{"id":"2088","key":"statistics.elapsed","operation":"gt","type":"number","value":"0.269481519"}],"calculations":[],"groupBys":[],"havings":[]},"timeframe":{"to":"2025-04-30T20:53:15Z","from":" ""2025-04-30T19:53:15Z"}}
## Core Capabilities
This tool provides three primary views of your Worker data:
1. **List Events** - Browse individual request logs and errors
Expand Down Expand Up @@ -104,31 +85,11 @@ This tool provides three primary views of your Worker data:

agent.server.tool(
'observability_keys',
`Find keys in the Workers Observability Data.

## When to Use This Tool
- Before creating new queries to discover available data fields
- When building complex filters to verify field names exist
- To explore the schema of your Workers data
- When troubleshooting "invalid field" errors in queries
- To discover metrics fields available for calculations

## Core Capabilities
This tool provides a comprehensive view of available data fields:
1. **Discover Schema** - Explore what fields exist in your Workers data
2. **Validate Fields** - Confirm field names before using them in filters
3. **Understand Data Types** - Learn the type of each field for proper filtering
`Find keys in the Workers Observability Data

## Best Practices
- Set a high limit (1000+) to ensure you see all available keys
- Add the $metadata.service filter to narrow results to a specific Worker
- Use this tool before a query with unfamiliar fields
- Pay attention to field data types when crafting filters

## Common Key Categories
- $metadata.* fields: Core Worker metadata including service name, level, etc.
- $workers.* fields: Worker-specific metadata like request ID, trigger type, etc.
- custom fields: Any fields added via console.log in your Worker code

## Troubleshooting
- If expected fields are missing, verify the Worker is actively logging
Expand Down Expand Up @@ -176,15 +137,6 @@ This tool provides a comprehensive view of available data fields:
'observability_values',
`Find values in the Workers Observability Data.

## When to Use This Tool
- When building complex queries requiring exact value matches

## Best Practices
- Always specify the correct data type (string, number, boolean)
- Use needle parameter with matchCase:false for case-insensitive searches
- Combine with filters to focus on specific Workers or time periods
- When dealing with high-cardinality fields, use more specific filters

## Troubleshooting
- For no results, verify the field exists using observability_keys first
- If expected values are missing, try broadening your time range`,
Expand Down
32 changes: 14 additions & 18 deletions packages/mcp-common/src/types/workers-logs-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@ export const zSearchNeedle = z.object({
matchCase: z.boolean().optional(),
})

const zViews = z
.enum(['traces', 'events', 'calculations', 'invocations', 'requests', 'patterns'])
.optional()
const zViews = z.enum(['events', 'calculations', 'invocations'])

export const zAggregateResult = z.object({
groups: z.array(z.object({ key: z.string(), value: zPrimitiveUnion })).optional(),
Expand Down Expand Up @@ -306,6 +304,19 @@ export const zReturnedQueryRunEvents = z.object({
export const zQueryRunRequest = z.object({
// TODO: Fix these types
queryId: z.string(),
view: zViews.optional().default('calculations').describe(`## Examples by View Type
### Events View
- "Show me all errors for the worker api-proxy in the last 30 minutes"
- "Show events from worker auth-service where the path contains /login"

### Calculation View
- "What is the p99 of wall time for worker api-proxy?"
- "What's the count of requests by status code for worker cdn-router?"

### Invocation View
- "Find a request to worker api-proxy that resulted in a 500 error"
- "List successful requests for the image-resizer worker with status code 200"
`),
parameters: z.object({
datasets: z
.array(z.string())
Expand Down Expand Up @@ -348,22 +359,7 @@ export const zQueryRunRequest = z.object({
.describe(
'Use this limit to limit the number of events returned when the view is events. 5 is a sensible default'
),
view: zViews.optional().default('calculations').describe(`## Examples by View Type
### Events View
- "Show me all errors for the worker api-proxy in the last 30 minutes"
- "List successful requests for the image-resizer worker with status code 200"
- "Show events from worker auth-service where the path contains /login"

### Calculation View
- "What is the p99 of wall time for worker api-proxy?"
- "What's the count of requests by status code for worker cdn-router?"

### Invocation View
- "Find a request to worker api-proxy that resulted in a 500 error"
- "Find the slowest request to worker image-processor in the last hour"

TRACES AND PATTERNS ARE NOT CURRENTLY SUPPORTED
`),
dry: z.boolean().optional().default(true),
offset: z
.string()
Expand Down
Loading