Skip to content

@memberjunction/core-actions

The @memberjunction/core-actions package provides a comprehensive library of 100+ pre-built actions for the MemberJunction Actions framework. These actions cover AI integration, CRUD operations, communication, data transformation, file handling, visualization, workflow control, web interaction, and more. Each action is registered via @RegisterClass(BaseAction, ...) so it can be discovered and invoked by AI agents, workflow engines, and automation systems at runtime.

For background on when and how to use Actions vs. direct class imports, and the “thin wrapper” design philosophy, see the parent Actions CLAUDE.md.

Server-side only — this package depends on Node.js APIs, database access, and server-side MJ infrastructure. Do not import it from Angular or other client-side code.

Terminal window
npm install @memberjunction/core-actions

This package is part of the MemberJunction monorepo. When working inside the monorepo, add the dependency to your package’s package.json and run npm install at the repository root.

The package is organized into two layers: hand-written custom actions grouped by domain, and generated actions produced by the MJ CodeGen system. Both extend BaseAction from @memberjunction/actions and register themselves with the MJ class factory.

graph TD
    subgraph CoreActions["@memberjunction/core-actions"]
        direction TB
        IDX["index.ts\n(re-exports all actions)"]

        subgraph Custom["src/custom/ -- hand-written"]
            direction LR
            AI["ai/"]
            COMM["communication/"]
            CRUD["crud/"]
            DATA["data/"]
            FILES["files/"]
            INT["integration/"]
            LISTS["lists/"]
            MCP["mcp/"]
            SEC["security/"]
            UM["user-management/"]
            UTIL["utilities/"]
            VIZ["visualization/"]
            WEB["web/"]
            WF["workflow/"]
            DEMO["demo/"]
            CE["code-execution/"]
        end

        GEN["src/generated/\naction_subclasses.ts"]
        CFG["config.ts\n(API key loading)"]
    end

    subgraph Deps["Framework packages"]
        BASE["@memberjunction/actions-base"]
        ENG["@memberjunction/actions"]
        CORE["@memberjunction/core"]
        GLOBAL["@memberjunction/global"]
    end

    IDX --> Custom
    IDX --> GEN
    Custom --> ENG
    Custom --> BASE
    GEN --> ENG
    GEN --> BASE
    ENG --> BASE
    BASE --> CORE
    BASE --> GLOBAL

    style CoreActions fill:#2d6a9f,stroke:#1a4971,color:#fff
    style Custom fill:#2d8659,stroke:#1a5c3a,color:#fff
    style Deps fill:#64748b,stroke:#475569,color:#fff
    style GEN fill:#7c5295,stroke:#563a6b,color:#fff
    style CFG fill:#b8762f,stroke:#8a5722,color:#fff

Several abstract base classes reduce duplication across related actions:

Base ClassLocationPurpose
BaseRecordMutationActioncrud/base-record-mutation.action.tsShared parameter extraction, entity loading, error analysis for Create/Update/Delete
BaseFileStorageActionfiles/base-file-storage.action.tsCommon storage-provider resolution for all File Storage: * actions
BaseFileHandlerActionutilities/base-file-handler.tsMulti-source file loading (Storage, URL, direct data)
BaseUserScopedCommunicationActionai/user-scoped-communication.action.tsMailbox security gate and provider resolution for the Chief of Staff * My * email/calendar actions; pins every mailbox operation to ContextUser.Email

The file src/generated/action_subclasses.ts contains actions produced by the MJ CodeGen system from natural-language UserPrompt descriptions stored in the database. Generated actions use a composition pattern — they always extend BaseAction (never their parent action class) and invoke the parent action via ActionEngineServer.Instance.RunAction() at runtime. See the parent README for details on the generated/child action architecture.

Scheduled Geocoding (Scheduled Geocoding action)

Section titled “Scheduled Geocoding (Scheduled Geocoding action)”

src/custom/geo/scheduled-geocoding.action.ts is a safety-net maintenance action that finds records in geo-enabled entities (Entity.SupportsGeoCoding = 1) missing a RecordGeoCode row, retries failed geocoding attempts, and cleans up orphaned RecordGeoCode rows. Live geocoding-on-save runs inline via BaseEntity.OnSaveCompleted — this scheduled action is only needed to catch records inserted via bulk SQL imports or direct DB writes that bypass BaseEntity.Save().

The “find missing records” phase uses keyset (seek) pagination when the target entity has a single-column orderable PK (the common case for MJ entities). This keeps each page O(log N) regardless of how deep the iteration goes — important on multi-million-row entities like Tax Returns. Composite-PK entities fall back to StartRow-based OFFSET pagination automatically. See KEYSET_PAGINATION_GUIDE.md for the pattern.

Default cadence is Saturday 2 AM UTC (configured in metadata/scheduled-jobs/.geocoding-maintenance-job.json). Administrators can adjust the CronExpression per environment.

External API keys used by certain actions (Perplexity, Google Custom Search, Gamma, Tavily) are loaded from mj.config.cjs or environment variables via the config.ts module:

mj.config.cjs
module.exports = {
perplexityApiKey: 'pk-...', // or PERPLEXITY_API_KEY env var
gammaApiKey: 'sk-gamma-...', // or GAMMA_API_KEY env var
tavilyApiKey: 'tvly-...', // or TAVILY_API_KEY env var
google: {
customSearch: {
apiKey: 'AIza...', // or GOOGLE_CUSTOM_SEARCH_API_KEY
cx: '017...', // or GOOGLE_CUSTOM_SEARCH_CX
}
}
};

Agents that do web research (Research Agent, Sage, the Web Research skill) are granted both the Perplexity Search and Google Custom Search actions, and are instructed to prefer Perplexity and fall back if one returns a missing-API-key error. Credential whichever you have:

CredentialsAvailability
Perplexity Search (recommended)perplexityApiKey — one key, no engine IDOpen to new customers
Google Custom Searchgoogle.customSearch.apiKey and .cxClosed to new customers; existing customers are served until 2027-01-01, after which the Custom Search JSON API is discontinued

New deployments should configure perplexityApiKey. Google’s stated successor, Vertex AI Search, is not a drop-in: it uses service-account auth against a data store over your own content and does not return public web results, so it produces neither of the two values this config expects and there is no MJ action for it. Deployments that already have Custom Search access can keep using it through 2026 and add perplexityApiKey whenever convenient — configuring both is supported.

All 100+ actions organized by category. Each action is registered with @RegisterClass(BaseAction, "<name>").

Actions for prompt execution, agent discovery, image generation, and content summarization.

Registration NameClassDescription
Execute AI PromptExecuteAIPromptActionRun a named MJ AI prompt with variable substitution and optional model/temperature overrides
SummarizeContentActionSummarizeContentActionSummarize text content using AI
Find Candidate AgentsFindCandidateAgentsActionDiscover AI agents suitable for a task
Find Candidate ActionsFindCandidateActionsActionDiscover actions suitable for a task
Find Best AgentFindBestAgentActionSelect the single best agent for a task
Find Best ActionFindBestActionActionSelect the single best action for a task
Load Agent SpecLoadAgentSpecActionLoad full specification for an AI agent
Generate ImageGenerateImageActionGenerate images using AI models

Chief of Staff / agent governance (8 actions)

Section titled “Chief of Staff / agent governance (8 actions)”

Actions used by the Chief of Staff agent (and other autonomous agents) to manage their own policy, schedule, coordination and user-scoped communication. All of them bind to ContextUser — an agent can only act on, and read for, the calling user. The four * My * actions extend BaseUserScopedCommunicationAction and are also registered under a __-prefixed alias (for example __ManageMyEmailInbox).

Registration NameClassDescription
Configure Agent User PolicyConfigureAgentUserPolicyActionCreate or update the caller’s MJ: AI Agent User Policies row for an agent (channel modes, coordination mode, action and entity rules); always bound to ContextUser.ID
Schedule Next Agent WakeScheduleNextAgentWakeActionUpsert the agent’s next AgentWake row in MJ: User Routines, keyed by (UserID, TargetID, WorkstreamKey); one-shot or cron schedule
Send Inter-Agent RequestSendInterAgentRequestActionSend a structured follow-up to another user, or that user’s Chief of Staff, as an MJ: AI Agent Requests row; checks both users’ coordination policy
Prepare Outbound Call BriefPrepareOutboundCallBriefActionValidate PhoneChannelMode and approval rules, then build a locked outbound-call brief with mandatory upfront AI disclosure
Verify My Communication CapabilitiesVerifyMyCommunicationCapabilitiesActionPreflight: reports the enterprise communication posture, active providers, the caller’s channel permissions, utility mailboxes and external scheduling connectors
Get My Calendar Events and AvailabilityGetMyCalendarAndAvailabilityActionRead the caller’s events, free/busy, meeting-time suggestions, or HubSpot/Calendly availability
Manage My Calendar EventManageMyCalendarEventActionCreate, update, respond to or cancel an event on the caller’s calendar, or create a Calendly single-use link; enforces CalendarChannelMode
Manage My Email Inbox and DraftsManageMyEmailInboxActionRead, search and draft/reply/forward in the caller’s own mailbox or dedicated utility mailbox; enforces EmailChannelMode; never accepts a From or Mailbox parameter

The mailbox actions run through the enterprise provider’s app-level credential (Microsoft Graph or Gmail) and the gate in BaseUserScopedCommunicationAction: the caller’s email domain must match the provider’s AllowedEmailDomains, the provider’s EnterpriseScopeMode must allow personal mailboxes (otherwise the action falls back to the user’s MJ: AI Bridge Agent Identities utility inbox), and the provider’s mailbox-access preflight must succeed. The per-user OAuth service described below is a separate, not-yet-wired path to the same mailboxes.

Send messages via the MJ Communication Framework or webhook integrations.

Registration NameClassDescription
__SendSingleMessageSendSingleMessageActionSend a single message through any configured provider (email, SMS, etc.)
Slack WebhookSlackWebhookActionPost messages to Slack via incoming webhooks
Teams WebhookTeamsWebhookActionPost messages to Microsoft Teams via incoming webhooks

Entity record create, read, update, and delete operations. The mutation actions share logic through BaseRecordMutationAction.

Registration NameClassDescription
CreateRecordActionCreateRecordActionCreate a new entity record
GetRecordActionGetRecordActionRetrieve a single entity record by primary key
GetRecordsActionGetRecordsActionRetrieve multiple entity records with filtering
UpdateRecordActionUpdateRecordActionUpdate an existing entity record
DeleteRecordActionDeleteRecordActionDelete an entity record by primary key

Parse, transform, aggregate, and explore structured data.

Registration NameClassDescription
CSV ParserCSVParserActionParse CSV with configurable delimiters, headers, and type coercion
JSON TransformJSONTransformActionTransform JSON using JSONPath queries
XML ParserXMLParserActionParse XML to JSON with namespace and attribute control
Aggregate DataAggregateDataActionGroup-by aggregation (sum, avg, count, min, max) with having clauses
Data MapperDataMapperActionMap fields between data structures using template expressions
Explore Database SchemaExploreDatabaseSchemaActionRetrieve entity metadata and schema information
Run Ad-hoc QueryRunAdhocQueryActionExecute ad-hoc SQL queries against entity data

Document generation, parsing, compression, and spreadsheet I/O.

Registration NameClassDescription
PDF GeneratorPDFGeneratorActionGenerate PDFs from HTML or Markdown content
PDF ExtractorPDFExtractorActionExtract text and metadata from PDF files
Excel ReaderExcelReaderActionRead data from Excel files with multi-sheet support
Excel WriterExcelWriterActionCreate formatted Excel files from structured data
File CompressFileCompressActionCompress files into ZIP archives
File Storage: Get File ContentGetFileContentActionRead file content from MJ storage
List Storage AccountsListStorageAccountsActionList available storage provider accounts
Search Storage FilesSearchStorageFilesActionSearch across storage providers by name or metadata

Granular cloud storage operations for Azure Blob, AWS S3, Google Cloud Storage, Google Drive, Dropbox, Box.com, and SharePoint. All extend BaseFileStorageAction.

Registration NameClassDescription
File Storage: List ObjectsListObjectsActionList objects in a container/bucket
File Storage: Get ObjectGetObjectActionDownload an object from storage
File Storage: Get Object MetadataGetMetadataActionRetrieve object metadata
File Storage: Get Download URLGetDownloadUrlActionGenerate a download URL (SAS/presigned)
File Storage: Get Upload URLGetUploadUrlActionGenerate an upload URL
File Storage: Check Object ExistsObjectExistsActionCheck if an object exists
File Storage: Check Directory ExistsDirectoryExistsActionCheck if a directory/prefix exists
File Storage: Copy ObjectCopyObjectActionCopy an object within or across containers
File Storage: Move ObjectMoveObjectActionMove an object (copy + delete)
File Storage: Delete ObjectDeleteObjectActionDelete an object from storage
File Storage: Create DirectoryCreateDirectoryActionCreate a directory/prefix
File Storage: Delete DirectoryDeleteDirectoryActionDelete a directory/prefix

HTTP, GraphQL, OAuth, rate limiting, and third-party service integrations.

Registration NameClassDescription
HTTP RequestHTTPRequestActionMake HTTP requests with auth, headers, and body support
GraphQL QueryGraphQLQueryActionExecute GraphQL queries and mutations
OAuth FlowOAuthFlowActionHandle OAuth 2.0 authorization flows
API Rate LimiterAPIRateLimiterActionRate-limit outbound API calls
Gamma Generate PresentationGammaGeneratePresentationActionGenerate presentations via the Gamma API

Manage MJ lists and list membership for entities.

Registration NameClassDescription
Add Records to ListAddRecordsToListActionAdd one or more records to a list
Remove Records from ListRemoveRecordsFromListActionRemove records from a list
Create ListCreateListActionCreate a new list with optional initial records
Get List RecordsGetListRecordsActionRetrieve records from a list with filtering
Get Record List MembershipGetRecordListMembershipActionFind which lists contain a specific record
Update List Item StatusUpdateListItemStatusActionBulk-update status on list items

Interact with external Model Context Protocol (MCP) servers.

Registration NameClassDescription
Execute MCP ToolExecuteMCPToolActionExecute a tool on a connected MCP server
List MCP ToolsListMCPToolsActionList available tools from MCP servers
Sync MCP ToolsSyncMCPToolsActionSynchronize MCP tool definitions to MJ metadata
Test MCP ConnectionTestMCPConnectionActionTest connectivity to an MCP server
MCPToolActionMCPToolActionGeneric MCP tool invocation wrapper
Registration NameClassDescription
Password StrengthPasswordStrengthActionEvaluate password strength using zxcvbn
Registration NameClassDescription
CreateUserActionCreateUserActionCreate a new MJ user
CreateEmployeeActionCreateEmployeeActionCreate a new employee record
AssignUserRolesActionAssignUserRolesActionAssign roles to a user
CheckUserPermissionActionCheckUserPermissionActionCheck if a user has a specific permission
ValidateEmailUniqueActionValidateEmailUniqueActionValidate that an email address is unique

Miscellaneous server-side utilities.

Registration NameClassDescription
__VectorizeEntityVectorizeEntityActionCreate AI vector embeddings for entity records
__RunExternalChangeDetectionExternalChangeDetectionActionDetect changes in external data sources
__BusinessDaysCalculatorBusinessDaysCalculatorActionCalculate business days between dates
__IPGeolocationIPGeolocationActionLook up geographic location by IP address
__CensusDataLookupCensusDataLookupActionQuery US Census Bureau data
__QRCodeQRCodeActionGenerate QR code images

Generate SVG charts, diagrams, and infographics using D3 and Rough.js. All produce self-contained SVG markup suitable for embedding in HTML or saving as files.

Registration NameClassDescription
__CreateSVGChartCreateSVGChartActionBar, line, pie, scatter, and area charts via D3
__CreateSVGDiagramCreateSVGDiagramActionFlowcharts and process diagrams
__CreateSVGWordCloudCreateSVGWordCloudActionWord cloud visualizations via d3-cloud
__CreateSVGNetworkCreateSVGNetworkActionForce-directed network graphs via d3-force
__CreateSVGInfographicCreateSVGInfographicActionMulti-section infographics with icons and data
__CreateSVGSketchDiagramCreateSVGSketchDiagramActionHand-drawn style diagrams via Rough.js
__CreateMermaidDiagramCreateMermaidDiagramActionRender Mermaid diagram definitions to SVG

Create Mermaid Diagram renders in headless Chromium, which the playwright dependency does not install. Install one on the host with npx playwright install chromium, or set MJ_CHROMIUM_EXECUTABLE_PATH to an existing binary. Without one the action returns BROWSER_UNAVAILABLE.

Search the web, extract page content, and validate URLs.

Registration NameClassDescription
__WebSearchWebSearchActionSearch the web via DuckDuckGo with rate limiting
__WebPageContentWebPageContentActionExtract content from a web page
__URLLinkValidatorURLLinkValidatorActionValidate that a URL is reachable
__URLMetadataExtractorURLMetadataExtractorActionExtract OpenGraph/meta tags from a URL
Perplexity SearchPerplexitySearchActionAI-powered search via Perplexity API
Google Custom SearchGoogleCustomSearchActionSearch via Google Custom Search API
Tavily SearchTavilySearchActionWeb search built for AI consumption — cleaned page content and an optional synthesised answer
Read RSS FeedReadRSSFeedActionRead one or more RSS/Atom feeds, filtered by age and keywords

Orchestrate action execution with branching, iteration, parallelism, and retry logic.

Registration NameClassDescription
ConditionalConditionalActionBranch execution based on a JavaScript condition
LoopLoopActionIterate over collections or numeric ranges
Parallel ExecuteParallelExecuteActionRun multiple actions concurrently
RetryRetryActionRetry a failed action with configurable attempts and backoff
DelayDelayActionPause execution for a specified duration
Registration NameClassDescription
__ExecuteCodeExecuteCodeActionExecute sandboxed code snippets

The lifecycle for runtime-author entity forms (form-role ComponentSpec + EntityFormOverride). See /plans/interactive-forms/phase-2-runtime-loop.md for the full architecture and security model. Mutation actions enforce ownership checks (User → caller, Role → membership, Global → admin).

Registration NameClassDescription
__GetEntitySchemaForFormGetEntitySchemaForFormActionRead-only: returns the curated form-relevant schema for an entity (FKs resolved, value lists annotated, audit fields stripped).
__GetDefaultFormScaffoldForEntityGetDefaultFormScaffoldForEntityActionRead-only: produces a working form-role ComponentSpec mirroring the CodeGen Angular default layout. The agent’s baseline.
__GetActiveFormForEntityGetActiveFormForEntityActionRead-only: returns the resolved Active override + full applicable-variants list for the (entity, calling-user) pair.
__CreateInteractiveFormCreateInteractiveFormActionNet-new only. Inserts Component v1.0.0 + Active User-scope Override. Fails ALREADY_EXISTS if the user already has an Active override for the entity.
__ModifyInteractiveFormModifyInteractiveFormActionBranches on the pointed-to Component status: Pending → modify in place; Active → new Pending Component v(N+1) + sibling Pending Override. Always User-scope-clamped.
__ActivateInteractiveFormVersionActivateInteractiveFormVersionActionPromotes a Pending override to Active; atomically demotes the prior sibling Active.
__RevertInteractiveFormRevertInteractiveFormActionRe-points an Active override at an older Component row in the same Name lineage. Pure UPDATE; no new rows.

Reference implementations useful for testing and learning.

Registration NameClassDescription
__GetWeatherGetWeatherActionRetrieve weather data for a location
__GetStockPriceGetStockPriceActionLook up stock price information
__CalculateExpressionCalculateExpressionActionEvaluate mathematical expressions
__ColorConverterColorConverterActionConvert between color formats (hex, RGB, HSL)
__TextAnalyzerTextAnalyzerActionAnalyze text for word count, readability, etc.
__UnitConverterUnitConverterActionConvert between measurement units

AI-generated entity-specific child actions. These are maintained by CodeGen and should not be manually edited.

Registration NameClassDescription
Create Conversation RecordCreate_Conversation_Record_ActionCreate a Conversations entity record (child of Create Record)
Get AI Model CostGet_AI_Model_Cost_ActionLook up cost information for an AI model (child of Get Record)

Per-user OAuth 2.0 (3LO) service — prototype

Section titled “Per-user OAuth 2.0 (3LO) service — prototype”

CommunicationUserOAuthService (src/custom/ai/communication-oauth-service.ts) is a BaseSingleton that lets an individual user connect their own Microsoft Graph or Google Workspace mailbox to MJ through three-legged OAuth, instead of the app-level credential the mailbox actions above use today. It is not an action; it is a service a host (MJServer route, test harness) drives directly.

Status: prototype, off by default. Gates 1 to 3 are administrator settings on MJ: Communication Providers: AllowUserDelegatedOAuth (bit, default 0), AllowedEmailDomains and AllowedOAuthTenantIDs (both comma-separated, optional). ReadProviderUserOAuthGates(providerEntity) lifts them into the gate fields of a ProviderUserOAuthPolicyConfig; the caller adds the OAuth client settings (endpoints, client id, redirect URI, scopes), which are not yet stored anywhere. Unless an administrator sets AllowUserDelegatedOAuth = 1 on a provider, no user can initiate a personal OAuth flow. See “Current limitations” below before relying on it.

sequenceDiagram
    participant Host as Host (route / caller)
    participant Svc as CommunicationUserOAuthService
    participant IdP as Microsoft / Google
    participant Store as IUserDelegatedCredentialStore

    Host->>Svc: InitiateAuthorizationFlow(policy, contextUser)
    Svc->>Svc: Gate 1, Gate 2 (contextUser.Email)
    Svc-->>Host: AuthorizationUrl + State (PKCE S256, 10-minute session)
    Host->>IdP: redirect user, user consents
    IdP-->>Host: code + state
    Host->>Svc: HandleOAuthCallback({ state, code, policy, contextUser, transport })
    Svc->>Svc: state valid, same user, Gate 1 again
    Svc->>IdP: transport.ExchangeAuthorizationCode (code + code_verifier)
    Svc->>Svc: Gate 2 (token email), Gate 3, Gate 4
    Svc->>Store: StoreUserDelegatedCredential(...)
    Svc-->>Host: OAuthCallbackResult (CredentialID, PrincipalEmail)
  1. Initiate — InitiateAuthorizationFlow(policy, contextUser) checks Gates 1 and 2, generates a PKCE S256 verifier/challenge pair (GeneratePkcePair) and a random state, keeps them in an in-memory session for 10 minutes, and returns an OAuthInitiateResult whose AuthorizationUrl includes code_challenge, code_challenge_method=S256 and login_hint.
  2. Consent — the host redirects the browser to AuthorizationUrl; the identity provider redirects back with code and state.
  3. Callback — HandleOAuthCallback(params) consumes the session (one use), rejects an expired or unknown state (INVALID_OR_EXPIRED_STATE) or a different calling user (STATE_USER_MISMATCH), exchanges the code through the injected IOAuthTokenTransport, runs Gates 2 through 4 against the verified token identity, and stores the result.
  4. Store — the credential is written through IUserDelegatedCredentialStore.StoreUserDelegatedCredential under the name UserOAuth3LO:<provider>:<ownerUserId> with ownerUserId inside the encrypted values. See @memberjunction/credentials for the owner-binding rules.
  5. Disconnect — DisconnectAndRevokeUserOAuth(params) revokes the refresh (or access) token at the provider when the transport implements RevokeToken, then deactivates the stored credential and wipes its token values. Revocation failure at the provider is reported in RevokedAtProvider but does not stop the local deactivation.
GateChecked atRuleResult code on failure
1initiate and callbackpolicy.AllowUserDelegatedOAuth === trueGATE_1_USER_OAUTH_DISABLED
2initiate (on contextUser.Email) and callback (on the token’s verified email)domain is in policy.AllowedEmailDomains (comma-separated; empty means any)GATE_2_DOMAIN_MISMATCH
3callbacktoken’s tenant (tid for Azure AD, hd for Google Workspace) is in policy.AllowedOAuthTenantIDs (empty means any)GATE_3_TENANT_MISMATCH
4callbackthe authenticated principal’s email equals contextUser.Email, case-insensitive — a user cannot link a personal or someone else’s mailbox to their MJ identityGATE_4_PRINCIPAL_EMAIL_MISMATCH

Gates 2 and 3 are opt-in narrowing; Gates 1 and 4 always apply. All result codes are the CommunicationOAuthResultCode union.

  • ProviderUserOAuthPolicyConfig — the caller builds this: ProviderName, the four gate fields, ClientId/ClientSecret, AuthorizationEndpoint, TokenEndpoint, optional RevocationEndpoint, RedirectUri, Scopes.
  • IOAuthTokenTransport (required on callback) — ExchangeAuthorizationCode must return a VerifiedOAuthTokenExchangeResult whose PrincipalEmail and TenantID come from a verified source (id_token claims or the provider’s userinfo endpoint), because Gates 2 to 4 trust them. RevokeToken is optional.
  • IUserDelegatedCredentialStore (optional) — defaults to CredentialEngine.Instance from @memberjunction/credentials, which owns credential naming (UserOAuth3LO:<provider>:<ownerUserId>), owner binding, the required credential type, encryption and audit logging. Inject another store only for tests.
  • No stored OAuth client settings and no admin UI beyond the generated form. The gate fields live on MJ: Communication Providers (editable through its generated Explorer form), but ClientId, ClientSecret, endpoints, RedirectUri and Scopes still come from the caller.
  • No built-in transport and no routes. IOAuthTokenTransport has no shipped implementation. The file header mentions /api/v1/communication-oauth/initiate and /callback, but no MJServer routes exist yet; a host must build them with ApiRoute() and call the service.
  • No consumer of the stored token. The Microsoft Graph and Gmail communication providers still authenticate with app-level credentials; a connected 3LO credential is stored but not yet used by any mailbox action.
  • Pending sessions are process-local. The initiate/callback session map lives in memory, so both calls must reach the same process, and a restart drops in-flight authorizations.
import { ActionEngineServer } from '@memberjunction/actions';
const engine = ActionEngineServer.Instance;
// Send an email
const result = await engine.RunAction({
ActionName: '__SendSingleMessage',
Params: [
{ Name: 'Provider', Value: 'SendGrid' },
{ Name: 'MessageType', Value: 'Email' },
{ Name: 'From', Value: 'noreply@example.com' },
{ Name: 'To', Value: 'user@example.com' },
{ Name: 'Subject', Value: 'Hello' },
{ Name: 'Body', Value: '<p>Hello from MJ</p>' }
],
ContextUser: currentUser
});
// Create a record
const createResult = await engine.RunAction({
ActionName: 'CreateRecordAction',
Params: [
{ Name: 'EntityName', Value: 'Contacts' },
{ Name: 'Fields', Value: { FirstName: 'Jane', LastName: 'Doe', Email: 'jane@example.com' } }
],
ContextUser: currentUser
});
// Get a record
const getResult = await engine.RunAction({
ActionName: 'GetRecordAction',
Params: [
{ Name: 'EntityName', Value: 'Contacts' },
{ Name: 'PrimaryKey', Value: { ID: 'abc-123' } }
],
ContextUser: currentUser
});
const aiResult = await engine.RunAction({
ActionName: 'Execute AI Prompt',
Params: [
{ Name: 'PromptName', Value: 'Summarize Text' },
{ Name: 'Variables', Value: { text: 'Long article content...' } },
{ Name: 'TemperatureOverride', Value: 0.3 }
],
ContextUser: currentUser
});
// Conditional branching
const condResult = await engine.RunAction({
ActionName: 'Conditional',
Params: [
{ Name: 'Condition', Value: 'amount > 1000' },
{ Name: 'Context', Value: { amount: 1500 } },
{ Name: 'TrueAction', Value: { ActionName: 'Slack Webhook', Params: { /* ... */ } } },
{ Name: 'FalseAction', Value: { ActionName: 'Delay', Params: { Duration: 5000 } } }
],
ContextUser: currentUser
});
// Parallel execution
const parallelResult = await engine.RunAction({
ActionName: 'Parallel Execute',
Params: [
{ Name: 'Actions', Value: ['Action1', 'Action2', 'Action3'] }
],
ContextUser: currentUser
});
// Parse CSV
const csvResult = await engine.RunAction({
ActionName: 'CSV Parser',
Params: [
{ Name: 'CSVData', Value: 'Name,Age\nAlice,30\nBob,25' },
{ Name: 'HasHeaders', Value: true }
],
ContextUser: currentUser
});
// Aggregate data
const aggResult = await engine.RunAction({
ActionName: 'Aggregate Data',
Params: [
{ Name: 'Data', Value: [{ dept: 'Eng', salary: 100000 }, { dept: 'Eng', salary: 120000 }] },
{ Name: 'GroupBy', Value: 'dept' },
{ Name: 'Aggregations', Value: { avgSalary: 'avg:salary', count: 'count:*' } }
],
ContextUser: currentUser
});

The following diagram illustrates how an action invocation flows from caller through the engine to this package’s registered classes.

sequenceDiagram
    participant Caller as Caller (Agent / Workflow)
    participant Engine as ActionEngineServer
    participant Factory as MJGlobal.ClassFactory
    participant Action as CoreAction subclass
    participant Service as Underlying Service

    Caller->>Engine: RunAction({ ActionName, Params, ContextUser })
    Engine->>Factory: Resolve registered class for ActionName
    Factory-->>Engine: Action instance
    Engine->>Action: InternalRunAction(params)
    Action->>Action: Extract & validate parameters
    Action->>Service: Delegate to service / framework class
    Service-->>Action: Result
    Action->>Action: Build ActionResultSimple + output params
    Action-->>Engine: { Success, Message, ResultCode }
    Engine-->>Caller: ActionResult

    note over Action,Service: Actions are thin wrappers.<br/>Business logic lives in service classes.
PackagePurpose
@memberjunction/actionsBaseAction class and ActionEngineServer
@memberjunction/actions-baseActionResultSimple, RunActionParams, ActionParam types
@memberjunction/coreMetadata, RunView, BaseEntity, logging utilities
@memberjunction/globalRegisterClass decorator
@memberjunction/aiAI model abstraction layer
@memberjunction/ai-promptsAIPromptRunner for prompt execution
@memberjunction/ai-core-plusAIPromptParams, AIPromptEntityExtended
@memberjunction/aiengineAIEngine singleton for model/prompt discovery
@memberjunction/communication-engineMessage sending infrastructure
@memberjunction/communication-typesMessage type definitions
@memberjunction/storageCloud storage provider abstraction
@memberjunction/export-engineData export utilities
@memberjunction/ai-vector-syncVector embedding synchronization
@memberjunction/ai-mcp-clientMCP server communication
@memberjunction/code-executionSandboxed code execution
@memberjunction/external-change-detectionExternal change tracking
@memberjunction/content-autotaggingContent categorization
LibraryUsed By
d3-scale, d3-shape, d3-cloud, d3-force, d3-hierarchyVisualization actions (SVG charts, word clouds, networks)
roughjsSketch-style diagram rendering
mermaid, playwrightMermaid diagram rendering (in headless Chromium)
pdfkitPDF generation
pdf-parsePDF text extraction
exceljsExcel read/write
papaparseCSV parsing
xml2js, xpath, @xmldom/xmldomXML parsing
marked, turndownMarkdown/HTML conversion
jsdomServer-side DOM for web content extraction
mammothWord document conversion
archiver, unzipperFile compression
axiosHTTP requests
jsonpath-plus, jmespathJSON querying
nunjucksTemplate rendering
zxcvbnPassword strength analysis
zodConfiguration schema validation
cosmiconfigConfig file loading