Code Execution
Integration Guide
Connect AI to Open Banking financial data using progressive disclosure. This guide explains how AI clients integrate with the OpenAgent Core ecosystem using the code execution approach — reducing token usage by 98%+ in typical workflows.
Why Code Execution with MCP?
When AI agents connect to MCP servers via direct tool calls, two critical problems emerge at scale.
Context Window Overload
Loading 34+ tool definitions upfront consumes hundreds of thousands of tokens before the agent can process a single request. This makes direct tool calls impractical at scale.
Excessive Token Consumption
Large datasets — thousands of transactions, account histories — flow through the model multiple times, dramatically increasing cost and latency with every round-trip.
The Solution: The code execution approach presents MCP tools as code APIs instead of direct tool calls. The agent writes code to interact with the server, loading only the tools it needs and processing data in the execution environment — reducing token usage by 98%+.
MCP Server Tool Categories
The OpenAgent Core provides access to open banking financial data through 7 core tool categories.
| Category | Tools | Purpose |
|---|---|---|
| User Management | create_user, get_user, update_user, list_users, search_user_by_email | Basiq user lifecycle |
| Consent | generate_consent_url, check_consent_status, explain_consent_flow | CDR-compliant bank authorization |
| Connections | create_connection, get_connections, get_connection, sync_connection, get_job_status, search_institutions | Bank account linking |
| Accounts | get_accounts, get_account, list_accounts, get_account_summary | Balances and account metadata |
| Transactions | get_transactions, get_transaction, list_transactions, get_transaction_summary | Transaction history and filtering |
| Enrichment | enrich_transaction, get_categorization_summary, get_institution | Merchant and category data |
| Insights | generate_insight, get_insights, get_insight, analyze_spending_patterns, get_financial_health_score | AI-powered financial analysis |
Progressive Disclosure Resources
basiq://first-time-setup
6-step onboarding workflow
basiq://consent-flow-guide
CDR consent flow documentation
basiq://tool-prerequisites
Dependency map for tools
basiq://quick-reference
Common workflows & troubleshooting
Connection Setup
Everything you need before connecting an AI client to the MCP server.
Endpoint
https://your-mcp-server.workers.dev/mcpAuthentication
Authorization: Bearer <TENANT_API_KEY>Protocol
- MCP JSON-RPC 2.0
- initialize • tools/list • tools/call
- resources/list • resources/read
- prompts/list • prompts/get
Progressive Disclosure
Instead of loading all tool definitions, tools are presented as importable code files — loaded only when needed.
Present Tools as Code APIs
Generate a file tree of available tools — the agent explores categories and reads only what it needs.
servers/
└── basiq-financial/
├── users/
│ ├── create_user.ts
│ ├── get_user.ts
│ ├── update_user.ts
│ ├── list_users.ts
│ └── search_user_by_email.ts
├── consent/
│ ├── generate_consent_url.ts
│ ├── check_consent_status.ts
│ └── explain_consent_flow.ts
├── connections/
│ ├── create_connection.ts
│ ├── get_connections.ts
│ ├── get_connection.ts
│ ├── sync_connection.ts
│ ├── get_job_status.ts
│ └── search_institutions.ts
├── accounts/
│ ├── get_accounts.ts
│ ├── get_account.ts
│ ├── list_accounts.ts
│ └── get_account_summary.ts
├── transactions/
│ ├── get_transactions.ts
│ ├── get_transaction.ts
│ ├── list_transactions.ts
│ └── get_transaction_summary.ts
├── enrichment/
│ ├── enrich_transaction.ts
│ ├── get_categorization_summary.ts
│ └── get_institution.ts
├── insights/
│ ├── generate_insight.ts
│ ├── get_insights.ts
│ ├── get_insight.ts
│ ├── analyze_spending_patterns.ts
│ └── get_financial_health_score.ts
└── index.tsTool File Pattern
Each tool corresponds to a typed file that wraps the MCP tools/call method.
import { callMCPTool } from "../../mcp-client.js";
interface CreateUserInput {
email?: string;
mobile?: string;
}
interface CreateUserResponse {
userId: string;
message: string;
}
/** Create a Basiq user. First step in the financial data workflow. */
export async function createUser(input: CreateUserInput): Promise<CreateUserResponse> {
return callMCPTool<CreateUserResponse>("create_user", input);
}MCP Client Implementation
The shared client handles JSON-RPC communication, authentication, and response parsing.
const MCP_URL = process.env.MCP_SERVER_URL || "https://your-mcp-server.workers.dev/mcp";
const TENANT_API_KEY = process.env.TENANT_API_KEY;
export async function callMCPTool<T>(toolName: string, args: Record<string, unknown>): Promise<T> {
const response = await fetch(MCP_URL, {
method: "POST",
headers: {
"Authorization": `Bearer ${TENANT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0",
id: crypto.randomUUID(),
method: "tools/call",
params: {
name: toolName,
arguments: args,
},
}),
});
const result = await response.json();
if (result.error) {
throw new Error(result.error.message || "MCP tool call failed");
}
return result.result?.content?.[0]?.text
? JSON.parse(result.result.content[0].text)
: result.result;
}Instructions for AI Clients
Five steps for efficient tool discovery, data processing, and workflow execution.
Discover Tools On-Demand
Do not load all 34+ tool definitions upfront. Instead, explore the directory structure and read only the tools needed for the current task.
List the directory structure — Explore ./servers/basiq-financial/ to find tool categories.
Read only the tools needed — For "create a user and get consent URL", read create_user.ts and generate_consent_url.ts only.
Use search if available — Search for "consent" or "transactions" to load only relevant definitions.
Use Resources for Workflow Discovery
Before executing tools, read MCP resources to understand workflows. Resources are small and provide structured guidance — load them instead of inferring from tool descriptions.
// Read first-time setup guide (avoids trial-and-error)
const setupGuide = await readMCPResource(
"basiq://first-time-setup"
);
// Check tool prerequisites before calling
const prerequisites = await readMCPResource(
"basiq://tool-prerequisites"
);Filter & Transform Data in Code
Avoid passing large datasets through the model. Process data in the execution environment and return only what's needed — summaries, filtered results, or aggregated values.
// Filter in code, return only what's needed
import * as transactions
from "./servers/basiq-financial/transactions";
const all = await transactions.getTransactions({
userId: "usr_abc123",
from: "2025-01-01",
to: "2025-01-31"
});
const groceries = all.filter(t =>
t.category?.toLowerCase().includes("groceries")
);
const total = groceries.reduce(
(sum, t) => sum + Math.abs(t.amount), 0
);
console.log(`Groceries: $${total.toFixed(2)}`);
console.log(groceries.slice(0, 5)); // Top 5 onlyChain Operations Without Context Bloat
Data flows between tools in the execution environment — intermediate results never enter the model's context unless explicitly returned.
import * as users from "./servers/.../users";
import * as consent from "./servers/.../consent";
import * as accounts from "./servers/.../accounts";
import * as insights from "./servers/.../insights";
const user = await users.createUser(
{ email: "user@example.com" }
);
const { url } = await consent.generateConsentUrl(
{ userId: user.userId }
);
console.log("Authorize:", url);
// Later — no full account list passed to model
const accts = await accounts.getAccounts(
{ userId: user.userId }
);
const health = await insights.getFinancialHealthScore(
{ userId: user.userId }
);
console.log(`Health score: ${health.score}/100`);Use Control Flow in Code
Loops, conditionals, and retries execute in the code environment — no model round-trips needed for polling or retry logic.
// Poll for consent completion
let complete = false;
while (!complete) {
const status = await consent.checkConsentStatus(
{ jobId }
);
complete =
status.status === "success" ||
status.status === "failed";
if (!complete) {
await new Promise(
r => setTimeout(r, 5000) // 5s backoff
);
}
}
console.log("Consent flow complete");Complete First-Time User Setup
An end-to-end workflow: create a user, authorize consent, fetch accounts, and generate spending insights.
import * as users from "./servers/basiq-financial/users";
import * as consent from "./servers/basiq-financial/consent";
import * as connections from "./servers/basiq-financial/connections";
import * as accounts from "./servers/basiq-financial/accounts";
import * as transactions from "./servers/basiq-financial/transactions";
import * as insights from "./servers/basiq-financial/insights";
async function onboardUserAndAnalyzeSpending(email: string) {
// 1. Create user
const user = await users.createUser({ email });
console.log(`Created user: ${user.userId}`);
// 2. Generate consent URL
const { consentUrl } = await consent.generateConsentUrl({
userId: user.userId,
callbackUrl: "https://yourapp.com/callback"
});
console.log(`User must authorize: ${consentUrl}`);
// 3. (User completes consent in browser — out of band)
// 4. Poll for completion (in production, use webhooks)
// ... polling logic ...
// 5. Fetch accounts and transactions
const accountsList = await accounts.getAccounts({ userId: user.userId });
const txns = await transactions.getTransactions({
userId: user.userId,
from: "2025-01-01",
to: "2025-01-31"
});
// 6. Filter and aggregate in code — don't pass 1000s of rows to model
const byCategory = txns.reduce((acc, t) => {
const cat = t.category || "Uncategorized";
acc[cat] = (acc[cat] || 0) + Math.abs(t.amount);
return acc;
}, {} as Record<string, number>);
// 7. Return summary only
console.log("Spending by category:", byCategory);
// 8. Get AI insight (server-side, returns concise summary)
const insight = await insights.analyzeSpendingPatterns({ userId: user.userId });
console.log(insight.summary);
}Privacy, Security & Skills
Data isolation, PII handling, and reusable skill patterns for production deployments.
Data Isolation
Intermediate results stay in the execution environment. Data flows between tools without entering the model's context unless explicitly logged or returned.
PII Tokenization
Sensitive data — emails, account numbers — can be tokenized before reaching the model. The MCP client untokenizes when passing to downstream tools.
Deterministic Rules
Define explicit data flow boundaries — e.g. Basiq API → your database, never directly to model context. Data routing is controlled at the execution layer.
State Persistence & Skills
Agents can persist intermediate results and build reusable skills. Add a SKILL.md for structured skill references the model can discover.
import * as transactions
from "../servers/basiq-financial/transactions";
import fs from "fs";
export async function saveTransactionsAsCsv(
userId: string,
from: string,
to: string
) {
const txns = await transactions.getTransactions(
{ userId, from, to }
);
const csv = txns
.map(t => [t.date, t.description, t.amount, t.category].join(","))
.join("\n");
const path =
`./workspace/transactions-${userId}-${from}-${to}.csv`;
await fs.writeFile(path, csv);
return path;
}Best Practices
Key patterns for building efficient, cost-effective AI integrations with the MCP server.
Load Tools On-Demand
Reduces context from ~150K to ~2K tokens by importing only the tools needed for the current task.
Read Resources First
Use basiq://first-time-setup and basiq://tool-prerequisites before executing tool calls.
Filter in Code
Aggregate and filter datasets locally. Avoid passing thousands of rows through model context.
Chain Operations
Data stays in the execution environment between tool calls — no intermediate context bloat.
Control Flow in Code
Polling, retries, and loops execute in code. No model round-trips for operational logic.
Persist State to Files
Save intermediate results to disk. Resume work across sessions and build reusable skills.
Further Reading
Code Execution with MCP
Anthropic's original approach and rationale for the code execution pattern.
Read moreMCP Protocol for AI Clients
Standard MCP connection details and protocol specification.
Coming soonAI Client Integration
Authentication, endpoints, and client configuration guide.
Coming soonQuick Start v2
Resources, prompts, and workflows to get started fast.
Coming soonDocument Version 1.0 • Last Updated February 2025 • For OpenAgent Core Documentation