Demo Walkthrough
The fastest way to understand MAP: run the demo server and watch a payment agent get gated in real time.
Start the demo server
git clone https://github.com/SidianLabs/micro-agent-protocol.git
cd micro-agent-protocol
npm install
# Start the demo server (includes example agents)
npm run dev:demo-server
# MAP demo server listening on http://localhost:8787
# In another terminal, run a demo
npm run demo:payment
npm run demo:db-readWhat's in the demo
demo/
server.ts # Demo server entry point (starts MAP with example agents)
demo-payment.ts # Payment flow demo script (acts like an AI assistant's SDK)
demo-db-read.ts # Database read demo script
agents/
payment-agent.ts # Example: PaymentAgent (how to build a payment micro-agent)
dbread-agent.ts # Example: DBReadAgent (how to build a database micro-agent)
generic-agent.ts # Example: GenericAgent (template for any custom agent)The core idea: you only write execute()
MAP provides everything up to BaseMicroAgent. You only write execute() - your actual business logic. The framework handles auth, policy, signing, receipts, audit, and lifecycle.
MAP FRAMEWORK (we provide)
Server, Orchestrator, Policy, Auth,
Signing, Delegation, Queue, Audit
BaseMicroAgent (abstract class)
| extend this
YOUR COMPANY AGENTS
class MyPaymentAgent extends BaseMicroAgent
-> Write execute() with YOUR logic
-> Call YOUR internal APIsBuild your own agent
Step 1: Extend BaseMicroAgent
Framework agents live in the reference tree (
src/runtime/micro-agent.ts) - clone the repo to build on them.execute()receives the full task envelope and delegation token; keep itprotectedand the framework calls it after policy passes.
import { BaseMicroAgent } from '../../src/runtime/micro-agent.js';
class MyPaymentAgent extends BaseMicroAgent {
readonly descriptor = {
agent_id: 'my-payment-agent-v1',
organization: 'example-corp',
version: '1.0.0',
domain: 'payments',
capabilities: ['payment.execute'],
risk_level: 'high',
};
protected async execute(envelope: TaskEnvelope, token: DelegationToken) {
// YOUR business logic runs here, after policy already approved it.
// Helpers available: this.assertAuthorized(), this.buildReceipt(), this.buildResult()
const charge = await stripe.charges.create({ amount: 5000 });
return this.buildResult(envelope, 'completed', { charge_id: charge.id });
}
}Step 2: Register it
For function handlers, register directly on the instance:
const agent = map({ policy: [...] });
agent.can('payment.execute', async (input) => {
return await stripe.charges.create({ amount: input.amount });
});
const result = await agent.run('payment.process', {
amount: 5000,
vendor: 'vendor_abc',
});For BaseMicroAgent subclasses, the server registers their descriptors (createExampleAgents() returns [new PaymentAgent().descriptor, ...]), and execution dispatches to execute() server-side.
Policy, signing, receipts, audit, retries, and the approval lifecycle are all handled for you.
The bank example
The demo README walks a complete MyBankPaymentAgent: a bank wraps its own fraud-check service and payment rail behind MAP. The task lifecycle the demo exercises:
accepted -> proposed -> denied | awaiting_approval -> running -> completed / failed / revokedBatch payments at scale
The async examples show a 1,500-transaction batch payment with progress polling (25% -> 50% -> 75% -> 100%, 47,500.00 total processed) and per-region revenue aggregation across 4 regions (84,532 rows processed) - the shape of real back-office workloads.
Multi-party approval
High-value actions can require more than one human. A CRM update to a high-value customer returns:
{
"required_approvals": ["manager_approval", "compliance_approval"],
"escalation_reason": "CRM updates to high-value customers require manager and compliance approval"
}Both approvals must land before execution proceeds.