Skip to content

Add simple media agent MCP server with spec compliance#2

Merged
bokelley merged 11 commits into
mainfrom
bokelley/media-agent-mcp
Oct 31, 2025
Merged

Add simple media agent MCP server with spec compliance#2
bokelley merged 11 commits into
mainfrom
bokelley/media-agent-mcp

Conversation

@bokelley
Copy link
Copy Markdown
Collaborator

Summary

Implement a fully functional simple media agent as an MCP server that can be called by the Scope3 platform. This agent:

  • Fetches products from all registered sales agents via multi-agent discovery
  • Proposes simple "passthrough" tactics based on floor prices
  • Allocates budget with configurable overallocation (default 40%)
  • Creates media buys when assigned a tactic

Key Changes

  • Schema Sync: Pull media-agent-openapi.yaml from docs.agentic.scope3.com with npm run update-schemas
  • Spec Alignment: Budget structure fixed (number, not nested object), ManageTacticResponse now returns only required fields
  • Client Cleanup: Improved Scope3Client.disconnect() to properly close HTTP transport
  • Algorithm: N cheapest products selected where N ensures minimum daily budget requirements
  • Error Handling: Fails gracefully if no products available or media buy creation fails

Testing

Implementation Details

  • get_proposed_tactics: Lists all products from sales agents, returns single tactic proposal
  • manage_tactic: Allocates budget to N cheapest products, creates media buys
  • Budget Math:
    • Takes total budget, applies overallocation multiplier
    • Divides equally among N products where daily budget ≥ min threshold
    • Example: $25k budget + 40% overallocation = $35k total / N products

Files Added/Modified

  • src/simple-media-agent.ts - MCP server class
  • src/simple-media-agent/ - Tool implementations (separate files)
  • src/client.ts - Improved disconnect method
  • package.json - Schema sync script
  • test-media-agent.ts - Direct testing script
  • Generated types from latest spec

🤖 Generated with Claude Code

bokelley and others added 11 commits October 20, 2025 13:35
Implements MCP (Model Context Protocol) server that provides tools
to interact with media agents implementing the Media Agent Protocol.

Features:
- TypeScript types generated from OpenAPI spec
- 5 MCP tools matching protocol endpoints
- Standalone executable via npx
- Programmatic API for embedding
- Example media agent implementation
- Tests and documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Replace low-level @modelcontextprotocol/sdk with fastmcp, a higher-level
TypeScript framework that simplifies MCP server creation.

Changes:
- Replace Server/Transport setup with FastMCP class
- Use Zod schemas for tool parameter validation
- Simplify tool registration with addTool()
- Update method from run() to start()
- Add transformIgnorePatterns to Jest config
- Mock fastmcp in tests to avoid ESM import issues

Benefits:
- Less boilerplate code (~170 lines vs ~300 lines)
- Better type safety with Zod
- Cleaner API surface

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implements a basic passthrough media agent that:
- Fetches products from all registered sales agents
- Proposes tactics based on floor prices
- Allocates budget to N cheapest products
- Creates media buys when tactic is assigned
- Listens for daily reporting to trigger reallocation

Algorithm:
- Sorts products by floor price
- Calculates N where daily budget >= min daily budget ($100)
- Divides total budget equally among N products

Features:
- CLI entry point: npx simple-media-agent
- Programmatic API
- Implements full Media Agent Protocol
- Webhook for daily reporting complete
- Extensible for custom strategies

This is a reference implementation for building custom media agents.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Apply configurable overallocation (default 40%) to media buy budgets
to ensure campaign delivery targets are met even with underdelivery.

Changes:
- Add overallocationPercent config option (default: 40%)
- Apply multiplier in calculateBudgetAllocation()
- Add OVERALLOCATION_PERCENT env var
- Update documentation with example

Example: For $10,000 campaign with 40% overallocation, allocate
$14,000 across media buys to hit $10,000 spend target.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
You're right! The media agent SHOULD be the MCP server directly,
not need a proxy layer.

Two deployment models:
1. simple-media-agent (HTTP) - Called BY Scope3 platform
2. simple-media-agent-mcp (MCP) - Called BY brand agents via MCP

The generic MCP proxy (scope3-media-agent) is only needed for
third-party HTTP-only media agents.

Architecture:
- HTTP Model: Scope3 → HTTP POST → Express server
- MCP Model: Brand Agent → MCP stdio → FastMCP server
- Both: → Scope3 API

Files:
- src/simple-media-agent.ts - HTTP server (Express)
- src/simple-media-agent-with-mcp.ts - MCP server (FastMCP)
- src/simple-media-agent-mcp-server.ts - MCP CLI entry point
- ARCHITECTURE.md - Explains both models clearly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Scope3 platform calls media agents via MCP, not HTTP.
Remove all HTTP and proxy layers - media agent IS the MCP server.

Changes:
- Remove HTTP-based simple-media-agent (Express)
- Remove generic MCP proxy (scope3-media-agent)
- Rename simple-media-agent-with-mcp → simple-media-agent
- Single binary: npx simple-media-agent (MCP stdio)
- Update documentation for MCP-only architecture

Architecture:
Scope3 Platform → MCP (stdio) → Media Agent → Scope3 API

The media agent exposes MCP tools directly:
- get_proposed_tactics
- manage_tactic

No HTTP server, no proxy, just MCP!

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Addresses code review comments:
1. Overallocation is now per media buy (not global config)
2. Removed unused name/version config fields
3. Use MediaBuyProduct from ADCP client library
4. MediaBuyAllocation extends MediaBuyProduct

Changes:
- Remove overallocationPercent from config
- Each MediaBuyAllocation has its own overallocationPercent (40%)
- Use MediaBuyProduct interface from ./resources/media-buys
- Pass full allocation (MediaBuyProduct) when creating media buys
- Update documentation to reflect per-buy overallocation

This allows per-buy customization and better delivery control.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Addresses all code review comments:
1. Overallocation is now sum of all media buy budgets (not per-buy)
2. Each tool in its own file for cleanliness
3. Remove 'any' types - use proper types from Scope3 client
4. Remove metadata from spec response

File structure:
- src/simple-media-agent/types.ts - Shared types
- src/simple-media-agent/get-proposed-tactics.ts - Proposal logic
- src/simple-media-agent/manage-tactic.ts - Budget allocation logic
- src/simple-media-agent.ts - Main MCP server class

Changes to overallocation:
- Applied to TOTAL budget, not per media buy
- allocatedTotalBudget = totalBudget * (1 + overallocationPercent/100)
- Each media buy gets: allocatedTotalBudget / N
- Sum of all media buy budgets = overallocated total

Type improvements:
- Check Array.isArray() for all responses
- Explicitly type product arrays
- No more 'any' types

Spec compliance:
- Removed metadata field from proposed tactics response

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Provides ways to test the media agent:
- Direct test script (test-media-agent.ts)
- Claude Desktop integration instructions
- MCP Inspector instructions
- Debugging tips

No live testing has been done yet - use these to verify
the implementation works correctly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Sync schemas from docs.agentic.scope3.com (media-agent-openapi.yaml now published)
- Fix budget structure: tacticContext.budget is number, not nested object
- Fix ManageTacticResponse: return only acknowledged + optional reason per spec
- Improve Scope3Client disconnect: properly close MCP client and HTTP transport
- Add npm run update-schemas script for future schema syncing
- Update test script to use correct budget structure

The simple media agent implementation now matches the merged PR #136 spec exactly.
Ready for real-world testing against Scope3 platform.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@bokelley bokelley merged commit 1827aef into main Oct 31, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant