Sessions
Sessions are scoped connections to MCP servers that manage tool access, authentication, and usage tracking for AI agent commerce operations.
Sessions
@codespar/sdkv0.9.0A session is the core runtime primitive in CodeSpar. It represents a scoped, authenticated connection to one or more MCP servers, giving your AI agent access to commerce tools across payments, fiscal, logistics, and messaging providers in Latin America.
Sessions solve a fundamental problem: an AI agent needs to interact with dozens of commerce APIs, each with its own authentication, data format, and rate limits. Instead of wiring each provider individually, you create a session, specify which servers you need, and CodeSpar handles the rest.
Every tool call made through a session is metered for billing, scoped to your API key, and auditable through the dashboard.
Tenancy. Sessions are scoped to a user (userId) inside a project inside your organization. Pass x-codespar-project: prj_<16chars> on HTTP requests to target a specific project, or omit the header to fall back to your org's default project. Examples below use defaults -- see the Projects concept for when to scope explicitly.
Session lifecycle
Create -- Call codespar.create(userId, config) to open a session. CodeSpar authenticates with each requested server using your stored credentials and returns a session ready to accept tool calls. This typically completes in 200-400ms.
Use -- Drive the session with one of three patterns: (1) direct tool calls via session.execute(toolName, params), (2) natural-language messages via session.send(message) for a full agent loop, or (3) streaming with session.sendStream(message). All operations are scoped to the session's connected servers.
Close -- When the conversation or workflow is done, call session.close() to release resources. Open sessions are automatically closed after 30 minutes of inactivity. You are only billed for settled transactions, not for tool calls or session duration.
Creating a session
With explicit servers
import { } from "@codespar/sdk";
const = new ({ : .. });
const session = await .("user_123", { : ["stripe", "mercadopago", "correios"],
});
.(.); // "ses_abc123def456"
.(.); // "active"The first argument is your end-user identifier -- whatever string uniquely identifies the user on behalf of whom the agent is acting. It lets CodeSpar scope credentials, audit logs, and billing to the right user.
With curl
curl -X POST https://api.codespar.dev/v1/sessions \
-H "Authorization: Bearer csk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_123",
"servers": ["stripe", "mercadopago", "correios"]
}'Response:
{
"id": "ses_abc123def456",
"user_id": "user_123",
"status": "active",
"servers": [
{ "id": "stripe", "name": "Stripe", "status": "connected" },
{ "id": "mercadopago", "name": "Mercado Pago", "status": "connected" },
{ "id": "correios", "name": "Correios", "status": "connected" }
],
"created_at": "2026-04-15T10:30:00Z",
"expires_at": "2026-04-15T11:00:00Z"
}Session options
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
userId (1st arg) | string | Yes | -- | End-user identifier on behalf of whom the agent acts |
servers | string[] | Yes* | -- | List of MCP server identifiers to connect |
preset | string | No | -- | A named preset that bundles multiple servers |
manageConnections | object | No | -- | Controls whether to wait for servers to finish connecting |
projectId | string | No | org default | Target a specific project (prj_<16chars>) |
metadata | Record<string,string> | No | -- | Key-value metadata attached to every tool call |
*Required unless preset is specified.
Presets
Presets are named bundles of servers optimized for common commerce workflows. They reduce boilerplate and ensure you include all the servers a workflow typically needs.
// These are equivalent:
const session = await codespar.create("user_123", {
servers: ["stripe", "mercadopago", "asaas", "pagarme"],
});
const session = await codespar.create("user_123", {
preset: "brazilian",
});Country presets
| Preset | Use case |
|---|---|
brazilian | Full Brazilian commerce stack (payments, fiscal, logistics, messaging, banking, ERP) |
mexican | Mexican commerce stack (Conekta, Facturapi, Skydropx, STP/SPEI, Bind ERP) |
argentinian | Argentine commerce stack (payments, AFIP, Andreani, BCRA, Colppy) |
colombian | Colombian commerce stack (Wompi, Siigo, Coordinadora, Nequi, Alegra) |
all | Every server in the catalog |
Presets can be combined with explicit servers. The servers array is merged with the preset's server list and duplicates are removed automatically.
// Brazilian preset + an extra crypto server
const session = await codespar.create("user_123", {
preset: "brazilian",
servers: ["mercado-bitcoin"],
});Executing tools
Sessions expose three execution patterns. Pick the one that matches how your agent drives the session.
session.execute(toolName, params) -- direct tool call
Invoke a single tool by name and wait for its result. Use this when your code (or your own agent loop) has already decided which tool to call.
const result = await session.execute("codespar_pay", {
method: "pix",
amount: 9990,
currency: "BRL",
description: "Order #1234",
customer_email: "maria@example.com",
});
console.log(result);
// {
// "success": true,
// "data": {
// "payment_id": "pay_abc123",
// "status": "pending",
// "pix_code": "00020126580014br.gov.bcb.pix...",
// "qr_code_url": "https://api.codespar.dev/qr/pay_abc123.png",
// "expires_at": "2026-04-15T11:00:00Z"
// },
// "server": "stripe",
// "tool": "codespar_pay",
// "duration": 347
// }session.send(message) -- natural-language agent loop
Hand CodeSpar a message in natural language; it runs a Claude tool-use loop on the backend, calling whichever tools the agent decides it needs, and returns the final response plus every tool call along the way. Use this when you want the simplest possible integration -- no framework, no tool orchestration code.
const result = await session.send(
"Charge R$150 via Pix for order #5678 and send a WhatsApp confirmation to the customer",
);
console.log(result.message); // Final agent response text
console.log(result.tool_calls); // Every tool the agent called
console.log(result.iterations); // How many model turns it tooksession.sendStream(message) -- streaming agent loop
Same as send() but yields events as they happen -- useful when you want to show progress to the user or stream the response through your UI.
for await (const event of session.sendStream("Charge R$150 via Pix")) {
if (event.type === "assistant_text") {
process.stdout.write(event.content);
}
if (event.type === "tool_use") {
console.log(`→ calling ${event.name}`);
}
if (event.type === "done") {
console.log("\nDone:", event.result.message);
}
}execute, send, and sendStream all route through the CodeSpar API for audit and billing. Only settled transactions count toward your bill -- read-only tool calls (quotes, lookups, discovery) are free.
Structured workflows with session.loop()
For deterministic multi-step workflows where you know the tool sequence in advance, session.loop() runs a list of steps in order with access to previous results. Unlike send(), there is no LLM in the middle -- you define the exact sequence.
const result = await session.loop({
steps: [
{
tool: "codespar_pay",
params: { method: "pix", amount: 15000, currency: "BRL" },
},
{
tool: "codespar_invoice",
params: (prev) => ({ payment_id: prev[0].data.payment_id }),
},
{
tool: "codespar_notify",
params: (prev) => ({
channel: "whatsapp",
template: "order_confirmation",
variables: { invoice_url: prev[1].data.pdf_url },
}),
},
],
abortOnError: true,
});
console.log(result.success); // true if all steps completed
console.log(result.completedSteps); // 3
console.log(result.results); // ToolResult[] for each stepMCP integration via session.mcp
For IDE-based workflows (Claude Desktop, Cursor, Windsurf), every session exposes an MCP endpoint as a property. Any MCP-compatible client can connect to it and get access to all the session's tools.
console.log(session.mcp);
// {
// "url": "https://api.codespar.dev/mcp/ses_abc123def456",
// "headers": { "Authorization": "Bearer csk_live_..." }
// }Add the returned URL and headers to your MCP client configuration and all session tools become available directly in your IDE.
Listing tools
Once a session is active, retrieve all available tools:
const tools = await session.tools();
for (const tool of tools) {
console.log(`${tool.name}: ${tool.description}`);
}
// codespar_discover: Find available commerce tools by domain
// codespar_checkout: Create a checkout session for a product or service
// codespar_pay: Process payments via Pix, boleto, card, or wallet
// ...plus server-specific tools from connected serversOr search by intent:
const matches = await session.findTools("process a Pix payment");
// Tools ranked by relevance to the querysession.tools() is async -- it fetches the current tool list from the connected servers. Always await it. The response includes both meta-tools and server-specific tools.
Managing connections
Some MCP servers require user-level authentication (e.g., connecting a merchant's own Stripe account via OAuth). Use session.authorize() to start an OAuth flow and session.connections() to inspect status.
const session = await codespar.create("user_123", {
servers: ["stripe", "mercadopago"],
});
const auth = await session.authorize("mercadopago");
if (!auth.connected && auth.redirectUrl) {
// Redirect user to OAuth consent screen
console.log(`Connect Mercado Pago: ${auth.redirectUrl}`);
}
const connections = await session.connections();
for (const conn of connections) {
console.log(`${conn.id}: ${conn.connected ? "connected" : "pending"}`);
}curl https://api.codespar.dev/v1/sessions/ses_abc123/connections \
-H "Authorization: Bearer csk_live_..."Response:
{
"connections": [
{
"id": "stripe",
"name": "Stripe",
"connected": true,
"connected_at": "2026-04-15T10:31:00Z"
},
{
"id": "mercadopago",
"name": "Mercado Pago",
"connected": false,
"redirectUrl": "https://codespar.dev/connect/mercadopago?session=ses_abc123"
}
]
}The user visits the redirectUrl, authenticates with the provider, and the connection status transitions to connected: true. Subsequent tool calls to that server will use the user's own credentials.
Session states
| State | Description | Transitions to |
|---|---|---|
pending | Session is being created; servers are connecting | active, error |
active | Session is open and ready for tool calls | closed |
closed | Session has been closed (manually or by 30-min timeout) | Terminal |
error | Session creation failed (check server availability) | Terminal |
Closing a session
try {
// use session...
} finally {
await session.close();
}curl -X DELETE https://api.codespar.dev/v1/sessions/ses_abc123 \
-H "Authorization: Bearer csk_live_..."Sessions not explicitly closed are automatically terminated after 30 minutes of inactivity. You are billed only for settled transactions, not for tool calls or session duration.
Best practices
- Scope sessions narrowly. Only connect the servers you need. Fewer servers means faster session creation, a smaller tool list for the LLM to parse, and lower token costs in the context window.
- Close sessions when done. Especially in serverless environments (Vercel, AWS Lambda) where the process may be recycled before the 30-minute timeout. Prefer
try { ... } finally { await session.close(); }. - Reuse sessions across turns. In a multi-turn conversation, create the session once and reuse it for all turns. Do not create a new session per message.
- Pick the right primitive. Use
execute()when your code decides the tool,send()for the simplest agent loop,sendStream()for UI streaming, andloop()for deterministic multi-step workflows. - Use presets for common patterns. They reduce boilerplate and are maintained by CodeSpar as new servers are added to a category.
- Handle connection errors gracefully. If a server fails to connect, the session still becomes
activewith the remaining servers. Checksession.connections()to verify which connections succeeded.
Next steps
Last updated on
Concepts
The small set of primitives that make CodeSpar make sense — sessions, tools, projects, triggers, authentication. Read these once and the rest of the docs clicks into place.
Projects
Projects are the second level of CodeSpar's 2-level tenancy model -- an isolation boundary inside an organization for API keys, connections, triggers, sessions, and events.