MF

modesty/fluent-mcp

Developer tools
31 stars 8 forks 품질 85 트렌드 46MIT

MCP server for Fluent (ServiceNow SDK)

개요

An MCP server that brings ServiceNow Fluent SDK capabilities to AI-assisted development environments. Enables natural language interaction with ServiceNow SDK commands, API specifications, code snippets, and development resources. : Since v0.6.0 the server speaks MCP@2026-07-28 and MCP@2025-11-25 from one handler set — the stdio entry inspects the opening message and serves whichever era the client opens with. v0.5.1 is the last release built on the v1 MCP SDK (2025-11-25 only). - - sdk_info plus ServiceNow SDK command tools for init, build, install, dependencies, transform, download, clean, pack, explain, query, and cicd - - API specifications, instructions, and code snippets for - - explain_fluent_api returns SDK docs for any Fluent API or guide — no project required - - Detects and caches an auth profile only when an auth-requiring command or check_auth_status needs it - - Resolves each project command from its workingDirectory argument, the initialized session, or...

README

Fluent MCP Server

An MCP server that brings ServiceNow Fluent SDK capabilities to AI-assisted development environments. Enables natural language interaction with ServiceNow SDK commands, API specifications, code snippets, and development resources.

Built for @servicenow/[email protected].

Note : Since v0.6.0 the server speaks both MCP@2026-07-28 and MCP@2025-11-25 from one handler set — the stdio entry inspects the opening message and serves whichever era the client opens with. v0.5.1 is the last release built on the v1 MCP SDK (2025-11-25 only).

Key Features

  • SDK Command Tools - sdk_info plus ServiceNow SDK command tools for init, build, install, dependencies, transform, download, clean, pack, explain, query, and cicd
  • Rich Resources - API specifications, instructions, and code snippets for 75 ServiceNow metadata types
  • API Documentation Lookup - explain_fluent_api returns SDK docs for any Fluent API or guide — no project required
  • Lazy Auto-Authentication - Detects and caches an auth profile only when an auth-requiring command or check_auth_status needs it
  • Explicit Project Context - Resolves each project command from its workingDirectory argument, the initialized session, or FLUENT_MCP_WORKING_DIR, then fails with actionable guidance instead of guessing
  • MCPB Bundle - Builds a self-contained .mcpb distribution with the server, resources, and production dependencies
  • Client-Friendly Schemas - Optional inputs advertise their canonical value types while the enforced schema accepts null as an omitted-value compatibility form

This MCP server implements the Model Context Protocol specification with the following capabilities:

Core

  • Resources - 300+ packaged resource documents across 75 ServiceNow metadata types (API specs, instructions, snippets, prompts)
  • Tools - 13 ServiceNow SDK command tools plus 4 resource/auth tools (17 total), with full parameter validation. Read tools (get-api-spec, get-snippet, get-instruct, check_auth_status) declare an outputSchema and return structuredContent for programmatic consumers
  • Prompts - Development workflow templates for common ServiceNow tasks (coding_in_fluent, create_custom_ui)
  • Logging & Progress - Structured logs are written to stderr; progress notifications are sent for long-running commands (any command with a 30s or longer timeout — deploy, build, transform, download, dependencies, query, pack, cicd) when the client supplies a progress token

Project Context & Sessions

The server requires no client capabilities and issues no server→client requests: Roots, Sampling, and Elicitation are not used (MCP 2026-07-28 removed server-initiated requests, and all input arrives with the tools/call arguments). Automatic workspace detection through Roots is gone for every client, including MCPB hosts.

  • Session Management - Tracks the directory established by init_fluent_app for subsequent project commands
  • Working Directory Resolution - workingDirectory tool argument → initialized session → FLUENT_MCP_WORKING_DIR → actionable failure. Accepted paths are non-empty absolute paths other than the filesystem root. The server never guesses from its process cwd or installed package directory. Clients must pass workingDirectory or configure FLUENT_MCP_WORKING_DIR when no session directory exists.
  • Non-interactive init_fluent_app - Intent-specific arguments must be supplied with the call (creation: appName, packageName, scopeName, template; conversion: from); a missing argument fails with an error naming exactly what is absent. The tool does not prompt or elicit missing values.
  • Error Handling - Comprehensive error messages with actionable guidance
  • Type Safety - Full TypeScript implementation with strict typing

Protocol Behavior

  • Dual-era stdio on @modelcontextprotocol/[email protected]: a 2026-07-28 opening (per-request _meta envelope, server/discover) and a 2025-11-25 initialize are both served from the same handler set; the SDK entry point pins one era per connection.
  • The six cacheable results of 2026-07-28 (tools/list, prompts/list, resources/list, resources/templates/list, resources/read, server/discover) advertise ttlMs: 3600000 / cacheScope: 'public' — everything they return is static for the process lifetime.
  • The server advertises instructions during initialization; tools/list is a side-effect-free read that returns tools in deterministic name order.
  • Optional tool arguments advertise their canonical JSON types so clients render normal form fields. The enforced call schema additionally accepts null as an omitted value; workingDirectory also treats an empty string as omitted before applying the fallback chain.
  • Structured logs go to stderr, keeping stdout reserved for MCP protocol traffic. Runtime logging/setLevel and notifications/message are not used.
  • Resource misses use the standard JSON-RPC invalid-params code (-32602).
  • Closing stdin closes the connection and aborts in-flight commands. Clients must keep stdin open until they have read the responses they need.

See the MCP SDK 2.3.1 upgrade notes for changed, deprecated, and newly added APIs and compatibility checks.

Quick Start

# Test with MCP Inspector
npx -p @modelcontextprotocol/[email protected] mcp-inspector npx @modesty/fluent-mcp

# Build the optional self-contained MCPB distribution
npm run bundle

# Or use in your MCP client (see Configuration below)

MCPB Distribution

The optional npm run bundle command produces fluent-mcp-.mcpb. The bundle contains dist/, res/, and production dependencies, and its manifest.json declares all 17 tools. MCPB hosts expose these user-configurable values to the server:

  • FLUENT_MCP_WORKING_DIR — optional default project directory; otherwise pass workingDirectory on project-aware tool calls
  • SN_INSTANCE_URL — optional instance URL for lazy authentication validation
  • SN_AUTH_TYPE — authentication type (basic or oauth, default oauth)

The npm package remains the primary distribution channel. MCPB does not restore Roots-based workspace detection or interactive init_fluent_app prompting.

Example prompt:

Create a new Fluent app in ~/projects/time-off-tracker to manage employee PTO requests

Available Tools

SDK Command Tools (13)

Tool Description Key Parameters
sdk_info Get SDK version or help flag (-v/-h), command (optional for -h)
explain_fluent_api Look up Fluent SDK documentation for any API or guide. No Fluent project required. topic (optional API/guide name or tag keyword — required unless list=true), list (boolean — list topics), peek (boolean — brief summary), format (pretty|raw), source (optional project path override), debug (optional)
init_fluent_app Initialize or convert a ServiceNow app. Non-interactive: missing intent-specific arguments fail with an error naming them. intent, from (conversion), appName/packageName/scopeName/template (creation), auth, workingDirectory (required), debug
build_fluent_app Build the application workingDirectory, debug (optional)
deploy_fluent_app Deploy to a ServiceNow instance. SDK flow activation can be skipped. Installs run asynchronously by default since SDK v4.12.0. workingDirectory, auth (auto-injected), skipFlowActivation, async (set false to force a synchronous install), debug
fluent_transform Convert local XML to Fluent TypeScript (from, offline — cannot be combined with auth or id), or pull instance changes back into .now.ts files: the whole app (no from), or one record and its related records (table + id). table without id only filters local XML to those tables — it never downloads. workingDirectory, from, directory, auth (auto-injected; instance modes only), table, id (requires table), force (requires table), format (default true), timeoutSeconds (full-app instance transforms), debug
download_fluent_dependencies Download dependencies and type definitions workingDirectory, auth (auto-injected), debug
download_fluent_app Download metadata from an instance workingDirectory, directory (required), source, auth (auto-injected), incremental, timeoutSeconds, debug
clean_fluent_app Clean output directory workingDirectory, source (optional), debug
pack_fluent_app Create an installable artifact workingDirectory, source (optional), debug
query_fluent_records Read-only Table REST query against an instance; returns a JSON envelope workingDirectory, table (required), query (required encoded query), fields, limit, offset, displayValue, view, queryCategory, excludeReferenceLink, noCount, queryNoDomain, timeout, select, auth (auto-injected), debug
cicd_fluent_app Install, publish, or rollback an app via the ServiceNow CI/CD API (sn_cicd). Changes instance state. workingDirectory, action (required: install|publish|rollback), scope|appSysId, appVersion (required for rollback, and for install/publish outside a Fluent project), baseAppVersion, autoUpgradeBaseApp, devNotes, wait, pollTimeout, auth (auto-injected), output (json|raw), select, debug
cicd_fluent_test Run, watch, or fetch results and logs for ATF test suites and tests via the CI/CD API. run executes real ATF steps on the instance. No Fluent project required (and none accepted). target (required: testsuite|test), action (required: run|watch|result|logs — logs for test only), testSuiteSysId|testSuiteName, testSysId|testName, progressId (watch), resultId (result, logs), pattern, limit (logs), browserName, browserVersion, osName, osVersion, runInCloud, isPerformanceRun, captureNodeLogs, wait, pollTimeout, auth (auto-injected), output (json|raw), select, debug

Resource and Authentication Tools (4)

Tool Description Key Parameters
get-api-spec Get an API specification or list all available metadata types metadataType (optional; omit to list all)
get-snippet Get a Fluent code snippet; without id, returns the first available snippet and any additional snippet IDs metadataType (required), id (optional)
get-instruct Get authoring guidance, conventions, and common pitfalls for a metadata type metadataType (required)
check_auth_status Lazily validate configured ServiceNow authentication and return structured status information No arguments

Note: Authentication is validated lazily on the first auth-requiring command or check_auth_status, then cached for the session. Use init_fluent_app to establish project context, pass workingDirectory per call, or set FLUENT_MCP_WORKING_DIR. Any optional argument sent as null is treated as omitted; workingDirectory also treats an empty string as omitted and falls through to the next source.

Looking up Fluent APIs with explain_fluent_api

explain_fluent_api wraps now-sdk explain and returns SDK documentation for any Fluent API class or topic guide. It works from any directory — no Fluent project required.

Invocation Result
explain_fluent_api({ topic: 'BusinessRule' }) Full API reference for BusinessRule
explain_fluent_api({ topic: 'BusinessRule', peek: true }) Brief summary of BusinessRule
explain_fluent_api({ topic: 'BusinessRule', format: 'raw' }) Full API reference as plain markdown (good for piping into other tools)
explain_fluent_api({ list: true }) Full topic index (all APIs and guides)
explain_fluent_api({ list: true, topic: 'atf' }) Topic index filtered to entries matching atf

topic matches an API name (e.g. BusinessRule, Acl), a guide name (e.g. business-rule-guide, atf-guide), or a tag keyword (e.g. flow, atf, email). The SDK resolves by exact name first, then by tag.

Resources

Standardized URI patterns following MCP specification:

Resource Type URI Pattern Example Purpose
API Specs sn-spec://{type} sn-spec://business-rule API documentation and parameters
Instructions sn-instruct://{type} sn-instruct://script-include Best practices and guidance
Code Snippets sn-snippet://{type}/{id} sn-snippet://acl/0001 Practical code examples

Development guides are exposed through prompts/list and prompts/get (coding_in_fluent and create_custom_ui), and appear on the Inspector’s Prompts tab.

Supported Metadata Types

75 metadata types across the following categories:

Core Types: acl, application-menu, business-rule, client-script, cross-scope-privilege, data-policy, field-style, form, import-set, instance-scan, interceptor, list, property, role, scheduled-script, script-action, script-include, scripted-rest, sla, state-model, table, ui-action, ui-page, ui-policy, user-preference

Table Types: column, column-generic, database-view

Service Catalog: catalog-item, catalog-item-record-producer, catalog-ui-policy, catalog-client-script, catalog-variable, variable-set

Email: email-notification, inbound-email-action

Automation & Workflow: flow, custom-action, playbook

Integration & Connections: alias, alias-template, retry-policy, rest-message, data-lookup, graphql-api

AI & Now Assist: ai-agent, ai-agent-workflow, now-assist-skill-config

Service Portal: service-portal, sp-header-footer, sp-page-route-map

Workspace & Analytics: workspace, dashboard

Assessments: assessment, risk-assessment

ATF (Automated Test Framework): atf (the Test() container and family entry point — start here, then route to a step sub-type), atf-appnav, atf-catalog-action, atf-catalog-validation, atf-catalog-variable, atf-email, atf-form, atf-form-action, atf-form-declarative-action, atf-form-field, atf-form-sp, atf-list, atf-reporting, atf-rest-api, atf-rest-assert-payload, atf-server, atf-server-catalog-item, atf-server-record, atf-ui-test-script, test-suite

What’s new in 4.13.6

This release of the MCP server tracks @servicenow/sdk 4.13.6, covering everything shipped across 4.12.0–4.13.6. Only 4.12.0 and 4.13.0 published release notes (4.13.1, 4.13.2, 4.13.4 and 4.13.5 were never published to npm), so the surface was established by diffing the installed package — types, build plugins, and CLI flag declarations — against 4.11.2:

  • New metadata type: assessment (SDK v4.12.0+) — the Assessment API defines an assessment or survey (asmt_metric_type) with its categories, metrics, and metric definitions. Metrics are a discriminated union over 19 dataType values. A scored assessment also writes its scoring business rules, and a scheduled one a sys_trigger job that ships inactive.
  • New metadata type: risk-assessment (SDK v4.12.0+) — the RiskAssessment API defines a change risk assessment (change_risk_asmt) with its categories, metrics, and risk thresholds. It requires the Change Risk Assessment plugin, which the build cannot check — query sys_plugins with query_fluent_records first.
  • New metadata type: database-view (SDK v4.13.0+) — the DatabaseView API joins existing tables into a read-only reportable view (sys_db_view + sys_db_view_table + sys_db_view_table_field). name is the identity (no top-level $id) and must carry the u_ (global) or _ (x_ scope) prefix — both hard build errors.
  • New metadata type: interceptor (SDK v4.13.0+, absent from every release note) — the Interceptor API defines a guided-question wizard (sys_wizard + sys_wizard_answer) that routes a user to the right form or page; choices for multiple-choice answers go in the new sys_wizard_choice table via Record() + Now.ref.
  • Playbook variants, Go Back, and more (SDK v4.13.0+) — wfa.playbook.variant() with per-activity variant / variantOverrides (mutually exclusive) and evaluateVariantChildrenAfter; ActivityDefinitions.Core.GoBack (only as the last activity of a match_first branch, with a RUN_ALWAYS target); isIdealPath on decision branches; per-activity actionOverrides that replace the default buttons; publicAccess for unauthenticated execution from public pages; and wfa.playbook.automationPlan() pills in experience properties. Potentially breaking: NewRecordForm now requires table and ChecklistTask requires checklist_items, and interface … extends BaseActivityConfig now fails (TS2312).
  • Flow hoisting (SDK v4.13.0+) — tryCatch arms and doInParallel branches can return outputs, the catch arm receives tryOutputs, and endFlow is allowed inside either tryCatch arm. The old “datapills are not visible outside the block — use setFlowVariables” rule is retired. Give each exposed action an explicit string uuid.
  • Table — augment mode accepts index (SDK v4.13.0+), and new allowConfiguration / dbObjectId properties (SDK v4.13.3+). UrlColumn accepts relative URLs (SDK v4.12.0+), and column hint / help / plural now actually reach sys_documentation (SDK v4.12.1+).
  • ACL — three new AI-experience types (aiux_page, aiux_widget, aiux_experience, SDK v4.12.0+) that require name, and roles entries may carry a per-role protectionPolicy (SDK v4.13.6+).
  • ATF — the Service Portal clickUIAction step’s assert and searchForCatalogItem’s catalog / category became optional (SDK v4.13.0+), and the atf-server-catalog-item resources now use the real snake_case input and output names (catalog_item_id, request_item, request_id); the old camelCase names never built.
  • UI Action — form / list accept true (programmatic-only, UI26) and style adds 'primary-ai' / 'secondary-ai' (SDK v4.12.0+).
  • $meta on more APIs (SDK v4.13.0+) — EmailNotification, UiPolicy, ScriptOnlyCheck, TableCheck, CatalogClientScript, CatalogItemRecordProducer, and catalog variables now accept $meta.
  • Dashboard corrections — the new SDK dashboard guides exposed long-standing errors in this server’s dashboard resources: the grid is 48 columns wide (not 24), data is bound inline (dataSources + metrics + groupBy / trendBy) rather than by report sys_id, and filters are now documented.
  • Tool changes — cicd_fluent_test gains action: "logs" (a single test result’s captured logs, filtered by a case-insensitive regex pattern, with limit); deploy_fluent_app gains async (installs are asynchronous by default since SDK v4.12.0) and a 15-minute budget, because the CLI’s async install poll has no cap of its own; download_fluent_app and fluent_transform gain timeoutSeconds for the new CLI --timeout (an idle timeout in seconds, default 3600) and a 10-minute default budget. fluent_transform now also enforces the CLI’s own combination rules before spawning — from cannot be combined with auth or id, and id and force each require table — so a call that used to fail inside yargs after spawn (an explicit auth with from was forwarded) is rejected with a message naming the conflict, and it exposes the CLI’s long-standing force and format flags. The tool count is unchanged at 17.
  • Prompts aligned with now-sdk explain — coding_in_fluent is now TypeScript-first: server-side logic goes in TypeScript modules under src/server/ that import Glide APIs from @servicenow/glide, and JavaScript (a Now.include() file) is only the fallback for string-only script fields such as ScriptInclude and ClientScript. Server scripts default to ES2021, not ES5. Its syntax rules now cite the compiler’s real diagnostics (loops TS250, if TS245, + concatenation TS303) and warn that .map()-generated records build but are corrupt. It replaces get_sys_id(...), which is not an SDK API and fails a real build, with Now.ref. Two dozen capability bullets were corrected where the 4.13.6 docs or package disagreed with them, among them protectionPolicy’s two value sets, State Model enforcement, Now Assist provider selection, and Store-app augment prefixes. create_custom_ui gets an endpoint that actually builds, the React 18.2.0 dependency set (the templates scaffold 19.x), the clientDir / staticContent.paths trap, the UI Page guides’ required patterns, and their full limitations list. coding_in_fluent keeps Now.include() for scripts, CSS, and as-is HTML (Jelly pages, Service Portal templates) but exempts a bundled UI Page’s index.html, which must be imported: Now.include() there builds successfully yet leaves src="./main.tsx" unrewritten in the deployed page.
  • Not wrapped on purpose: the new now-sdk auth --print prints a live bearer or session token with the user’s full instance permissions. Exposing it as a tool would place that secret in model context and transcripts, where instance-sourced text could steer it into another tool, and the server already makes every instance call itself. Run it in your own terminal if you need a token.

Source-of-truth note: the installed package disagrees with the release notes and shipped docs in several places, each treated as a correction. Assessments have no “post-deployment steps” API (that phrase is a manual checklist in the risk guide), and the string form of displayedWhen / correctAnswerChoice is silently written empty. RiskAssessment has no table or evaluationMethod property. The 4.13.0 DatabaseView example does not compile, failing in six separate ways (it has a top-level $id, uses where instead of whereClause, and puts fields at the top level, among others). publicAccess is not a public API, and playbook “image attachments” are a transform round-trip, not an authoring feature. The package carries no @since tags, contrary to the “corrected @since versions” item. The CLI --timeout default is 3600 seconds, not 300. The developing-apps guide says transform --table scopes an instance pull, but without --id it only filters local XML (--from, or the project directory) and never downloads. The UI Page guide says a client tsconfig.json without skipLibCheck fails the build; that did not reproduce with @servicenow/react-components 0.1.8, so the prompt keeps the rule without the claim. Table augments need _ in every x_ scope — Store apps included — so this server’s earlier advice to use u_ for Store apps was wrong. The shipped flow-hoisting examples use shorthand returns that Fluent rejects. See .mosey/upgrade-sdk-4.13.6.md.

Previously (4.11.x)

Authoring-surface additions shipped across @servicenow/sdk 4.11.0 and 4.11.2 (4.11.1 was never published to npm, and 4.11.2 shipped no release notes — its surface was established by diffing the installed package):

  • New metadata type: test-suite — the TestSuite API groups existing ATF Test() records into a named, orderable, optionally nested suite, writing sys_atf_test_suite plus one sys_atf_test_suite_test membership row per entry. Run order comes from array position, not an authored field. It is authoring only: it never triggers or schedules a run — use ATF’s UI/scheduler or cicd_fluent_test.
  • New metadata type: graphql-api — the GraphQLApi API defines a scripted GraphQL API (sys_graphql_schema) with its resolvers, type resolvers, and two-tier security: schema-gate ACLs on the whole API plus standalone field-level Acl({ type: 'graphql' }) path ACLs. Resolver paths use Type:field; ACL names use the slash-delimited runtime query path.
  • New metadata type: field-style — sys_ui_style is now a supported Record() table, making conditional list/form field styling authorable in Fluent (there is no FieldStyle() constructor). style accepts any CSS property, so this is also the mechanism for list column width and text-align.
  • Flow do-while loop — wfa.flowLogic.doTheFollowing({ $id, label?, annotation? }, () => { ... }) repeats a body until wfa.flowLogic.until(''), called as the body’s last statement, is satisfied. The body always runs at least once and the condition may reference outputs of actions inside the same body, which makes it the right construct for polling and retries.
  • Playbook on-demand execution — executionType widened to 'record_driven' | 'on_demand'. A standalone playbook must omit triggers entirely, cannot set parentTable or reference params.parentRecord, may finally set allowAsNested: true, and must grant launch: true in at least one permission set or the build fails.
  • Playbook permissions — new permissions on argument 2 (a callback, so pills can reach params.parentRecord) and on each LaneConfig (a plain object), each grouping users/userGroups/roles/userCriterias. On a playbook set view is required and gates every other flag; on a lane set all four flags are independent. wfa.playbook.activityRef(Now.ID['x']) reaches an activity’s outputs from inside a permissions block.
  • Playbook optional activities — startRule: wfa.playbook.run.Manually() declares an activity a user starts by hand. It returns a ManualActivityReference with no outputs that is deliberately outside the dependency union: because it may never run, nothing can wait on it with run.After().
  • Playbook launcher and outputs — launcherTitle, launcherDescription, and launcherInputs configure the on-demand launcher; the record-form fields (launcherShowRecordForm, launcherRecordFormView, launcherTemplateFields) belong to record-driven playbooks. New OOB activity ActivityDefinitions.Core.SetPlaybookOutputs writes the playbook’s own declared outputs.
  • Playbook AI-agent activities — AI-agent configuration is exposed on the four OOB definitions that opted in (RecordForm, AutocompletingRecordForm, NewRecordForm, EmailForm). aiAgentObjective becomes mandatory once enableAiAgent is true. The SDK validates neither platform prerequisite (sn_genai_platform installed, sn_pa_designer.enable_agentic_playbooks true).
  • Dependent record inputs — UpdateRecord/CreateNewRecord now type-check a record pill against the sibling table_name input, and Action() carries rawInputs for the same purpose, so a wrong-table pill is a compile error rather than a runtime surprise.
  • Table.sizeClass and List.domain — Table accepts sizeClass?: number; List accepts domain?: string (the sys_domain applied to the list, defaulting to 'global').
  • 17 new Record()-addressable tables (176 → 193), including sys_ui_style, cmn_schedule_span (schedule entries), business_calendar_span, cmdb, sysrule_view_workspace, and sysevent_script_action.

Source-of-truth note: five release-note claims are not corroborated by the installed package and were treated as corrections. doTheFollowingUntil was not “reworked” — that identifier exists in neither 4.10.1 nor 4.11.2; the construct is new, and is authored as doTheFollowing + until. enforceAcl is not a secure-by-default boolean — it is an ACL reference array defaulting to empty, i.e. no schema gate (only the three requires* booleans and contextualAclMaxDepth are secure-by-default). The new-table claim under-reports: 17 tables were added, not 2. A GraphQL resolver script cannot be an inline function literal even though the type accepts a function. And the launcher* record-form fields are forbidden on executionType: 'on_demand', the opposite of what “On-Demand launcher configurations” suggests. Separately, the “Decimal inside FlowObject/FlowArray” item is a build-pipeline fix, not a type change — FlowTypes.d.ts and db/types/Decimal.d.ts are byte-identical to 4.10.1. See .mosey/upgrade-sdk-4.11.2.md.

Previously (4.10.x)

Authoring-surface additions shipped across @servicenow/sdk 4.10.0 and 4.10.1:

  • New metadata type: state-model — the StateModel API defines a table’s state machine (states, transitions, and the conditions that gate them) in a single call, writing sttrm_model/sttrm_state/sttrm_state_transition/sttrm_transition_condition records, or the chg_model/prb_model/prb_task_model subclass auto-selected from table. It can also edit out-of-box models in place by referencing their real sys_ids.
  • New metadata type: atf-list — the atf.list.* ATF steps (relatedListVisibility, applyFilterToList, recordPresentInList, openRecordInList, listUIActionVisibility, clickListUIAction) exercise list and related-list UI behavior.
  • New tools: cicd_fluent_app (install/publish/rollback an app through the sn_cicd API — changes instance state) and cicd_fluent_test (run, watch, or fetch results for ATF suites and tests), wrapping the new now-sdk cicd command. query_fluent_records gains select for the new --select path extractor.
  • $meta.useEsLatest — new cross-cutting flag that runs a record’s script field(s) at the latest ECMAScript version the platform supports. It reaches the APIs whose type carries $meta (BusinessRule, Acl, ScriptInclude, ScriptAction, ScheduledScript, UiPage, RestApi routes, SPWidget, SPMenu, and others) — not every API with a server-side script field: StateModel transition conditions are server-side scripts whose type accepts no $meta at all (see the source-of-truth note below).
  • Table actions object form — actions now accepts the exported TableActionAccess shape { read?, update?, delete?, create? }, where each action is three-state. The array form is deprecated: it is a complete enumeration, so actions: ['read'] also writes the other three as false. The SDK also no longer derives defaults for actions, allowClientScripts, allowNewFields, allowUiActions, allowWebServiceAccess, or maxLength.
  • Reference column mtom — creates a many-to-many relationship. Note the semantic split: referenceKey no longer means many-to-many, and now stores a field from the referenced table in place of sys_id.
  • UI Action icons — UiAction’s form and list objects both accept iconName and showIconOnly.
  • Form $meta — Form now honors $meta.installMethod to route its output folder (previously accepted but inert).
  • Playbook timerSchedule — startWithDelay can evaluate its delay against a cmn_schedule record instead of elapsed clock time, on all three variants.
  • Catalog dynamic default values — a variable’s dependentQuestion widened to accept a ReferenceVariable/RequestedForVariable in addition to a name string; CatalogUiPolicy actions accept variable, and CatalogClientScript accepts order.
  • $override on sys_* fields — $override can set sys_domain and most other sys_* columns on any table; sys_id, sys_scope, sys_update_name, and sys_domainpath remain framework-managed and error if overridden.
  • Service Portal — widget/page/instance CSS fields accept SCSS or CSS, widgetParameters now correctly serializes a plain object, SPInstance’s placeholder properties are functional rather than ignored, and urlSuffix accepts hyphens. The service-portal spec also gained the previously undocumented ServicePortal() (sp_portal) API.

Source-of-truth note: several release-note claims are not corroborated by the installed package and were treated as corrections — “dependent questions” are a dynamic default value, not visibility or option control (and the property is not new, only its type widened); runServerSideScript “surface support” already shipped in 4.9.0; and the add_message inference change is an internal transform fix with no authoring-surface change. The overview guide also lists StateModel, AliasTemplate, InboundEmailAction, CatalogItem, CatalogItemRecordProducer, and the instance-scan checks as accepting $meta.useEsLatest, but their declarations carry no $meta. See .mosey/upgrade-sdk-4.10.1.md.

Previously (4.9.x)

This release of the MCP server tracks @servicenow/sdk 4.9.0 — a maintenance and bug-fix release (Flow, ClientScript, ImportSet, SLA transform/build reliability) with select authoring-surface additions:

  • New metadata type: atf-ui-test-script — the atf.uiTestScript.runTest() ATF step runs a TestingLibrary test body in the client test runner to test custom UI components (Angular/React widgets, embedded SPAs, custom workspaces, now-* web components) that the standard atf.form.* / atf.catalog.* steps cannot reach.
  • Multi-language choice labels — a choice field’s choices value may be an array of ChoiceConfig objects, each with a language (BCP 47) key, producing one translated sys_choice record per language.
  • protectionPolicy on AI Agent & AI Agentic Workflow — AiAgent and AiAgenticWorkflow accept protectionPolicy: 'read' | 'protected' for post-install access control.
  • Role.federatedId — optional identifier to match a role to an externally federated role during identity federation.
  • Table index platform columns — a table index entry’s element may reference platform default columns (for example, sys_created_on).
  • Now Assist Skill Kit providers — new LLM providers selectable by name: Now LLM LTS Generic, Google Cloud Vertex AI, Amazon Bedrock.

Source-of-truth note: two release-note claims are not corroborated by the installed package and were treated as corrections — Form table_field.field is documented as a schema column name (not loosened to “any string”), and the four named NASK model strings appear nowhere in the package (model is a free string). See .mosey/upgrade-sdk-4.9.0.md.

Previously (4.8.x)

This release of the MCP server tracks @servicenow/sdk 4.8.0 and adds support for the following Fluent APIs and SDK enhancements:

  • New metadata type: playbook — the PlaybookDefinition API (sys_pd_process_definition, from @servicenow/sdk/automation) for guided, record-driven multi-step processes with lanes, activities, triggers, and inputs/outputs.
  • New metadata type: rest-message — the RestMessage API (sys_rest_message) for outbound HTTP integrations with shared auth/headers and callable functions.
  • New metadata types: alias and alias-template — the Alias (sys_alias) and AliasTemplate (sys_alias_templates) APIs for Connection & Credential aliases and reusable connection-setup templates.
  • New metadata type: retry-policy — the RetryPolicy API (sys_retry_policy) controlling transient-failure handling for connections (fixed-interval, exponential-backoff, or Retry-After).
  • New metadata type: data-lookup — the DataLookup API (dl_definition) that auto-copies field values from a matcher table to a source record.
  • Declarative deletion (Now.del()) — top-level statement to remove records by coalesce keys or sys_id.
  • Type enhancements — $override on DataPolicy/UserPreference; $meta.installMethod on Record/Acl/Alias/UserPreference; ACL field accepts known field names, system columns, or '*'; Table accessibleFrom now defaults to 'public'.
  • New CLI tool — query_fluent_records wraps now-sdk query for read-only Table REST queries (JSON envelope output).

Previously (4.7.x)

This release of the MCP server tracked @servicenow/sdk 4.7.x and added support for the following Fluent APIs and SDK enhancements:

  • New metadata type: data-policy — the DataPolicy API (sys_data_policy2) for server-side mandatory/read-only field enforcement that cannot be bypassed via API, import, or web service.
  • Flow error handling & parallelism — wfa.flowLogic.tryCatch, wfa.flowLogic.doInParallel, and wfa.flowLogic.appendToFlowVariables (append to Array.Object flow variables).
  • Flow stages — declare stages with FlowStage({ label, value, … }) and activate them in the body via wfa.stage(...) for progress tracking.
  • Table augments — add columns to an existing platform/cross-scope table via Table({ augments: '', schema }); added columns must use the current app’s ownership prefix: _ in an x_ scope (for example, x_acme_), or u_ in global — the build rejects anything else, so a Store app (always an x_ scope) uses its scope prefix.
  • AI Agent — new agentDescriptor; dataAccess accepts roleMap (role names) or roleList (role sys_ids).
  • NASK — securityControls accepts roleMap (role names) alongside roleRestrictions (role sys_ids).
  • Universal field override ($override) — escape hatch on Fluent constructors to set unmodeled columns by DB column name.
  • Protection policy — protectionPolicy documented on sys_policy-backed APIs (Action, Subflow, business rules, scripted REST, etc.).
  • CLI — fluent_transform gains --table/--id (transform by table hierarchy); init gains the typescript.vue template; OAuth client_credentials for CI/CD via SN_SDK_* env vars (see Configuration).
  • MCP — read tools now return structuredContent (with declared outputSchema); long-running commands emit progress notifications.

Previously (4.6.0)

Added custom-action, inbound-email-action, sp-header-footer, and sp-page-route-map metadata types; the declarative Form API; subflow-of-subflow and custom actions in flows; AIAF auto-ACL generation; NASK output/input-type enhancements; Table dictionary overrides; and a project-free explain command with tag search, --list, --peek, and --format=raw.

Configuration

Requirements: Node.js 22.23.2+, npm 10.9.8+, @servicenow/sdk 4.13.6 (the repository’s development toolchain is Node 22.23.3 per .nvmrc and npm 12.2.0)

MCP Client Setup

Add to your MCP client configuration file:

{
  "mcpServers": {
    "fluent-mcp": {
      "command": "npx",
      "args": ["-y", "@modesty/fluent-mcp"],
      "env": {
        "FLUENT_MCP_WORKING_DIR": "/absolute/path/to/your/fluent-project",
        "SN_INSTANCE_URL": "https://your-instance.service-now.com",
        "SN_AUTH_TYPE": "basic",
        "SN_USER_NAME": "local-username",
        "SN_PASSWORD": "local-password"
      }
    }
  }
}

Client-Specific Locations:

  • Claude Desktop / macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • VSCode Copilot: .vscode/mcp.json (use Command Palette: MCP: Add Server...)
  • Cursor: Settings → Features → MCP Settings
  • Windsurf: Settings → Cascade → MCP Servers → View raw config
  • Gemini CLI: ~/.gemini/settings.json

VSCode note: For VSCode, the JSON structure uses "mcp": { "servers": { ... } } instead of "mcpServers".

Environment Variables:

Variable Description Default
FLUENT_MCP_WORKING_DIR Absolute Fluent project path used after the per-call and initialized-session sources; when it is also absent, project commands fail with actionable guidance -
SN_INSTANCE_URL ServiceNow instance URL for auto-auth validation -
SN_AUTH_TYPE Authentication method: basic or oauth oauth
SN_USER_NAME Username for basic auth (informational) -
SN_PASSWORD Password for basic auth (informational) -
FLUENT_MCP_LOG_LEVEL Minimum stderr log severity (debug, info, notice, warning, error, etc.) info

Note: On the first auth-requiring command (or check_auth_status), the server detects an existing auth profile matching SN_INSTANCE_URL, stores it in the session, and auto-injects it. Concurrent first calls share one validation promise. A new profile is added automatically only when setup can complete non-interactively (basic auth with SN_USER_NAME/SN_USERNAME + SN_PASSWORD); otherwise the server emits a single notice with the manual auth --add command to run.

Logging

The server writes its complete structured log stream to stderr so stdout remains reserved for MCP protocol traffic. Configure the minimum severity before launch with FLUENT_MCP_LOG_LEVEL (default info; use debug to include raw SDK CLI output). Runtime logging/setLevel and notifications/message are intentionally not used.

CI/CD (non-interactive) authentication — SDK v4.7.0+

For headless pipelines, the ServiceNow SDK CLI reads credentials directly from SN_SDK_* environment variables (the MCP server inherits and passes these through to spawned commands — no extra configuration needed). Set SN_SDK_NODE_ENV=SN_SDK_CI_INSTALL to enable CI mode, then:

Variable Required Value
SN_SDK_NODE_ENV yes SN_SDK_CI_INSTALL
SN_SDK_AUTH_TYPE for oauth basic (default) or oauth
SN_SDK_INSTANCE_URL yes Full instance URL
SN_SDK_USER / SN_SDK_USER_PWD basic Username / password
SN_SDK_OAUTH_CLIENT_ID / SN_SDK_OAUTH_CLIENT_SECRET oauth OAuth client_credentials app credentials

OAuth uses the client_credentials grant against /oauth_token.do. See the SDK’s ci-integration guide (via explain_fluent_api) for instance setup details.

Note that these SN_SDK_* credentials take precedence over a stored alias, so the auth alias the server injects is ignored while they are set.

MFA-enforced basic auth — SDK v4.13.0+

The SDK CLI now answers an instance’s mfa_code_required challenge by prompting for a TOTP code — but only in an interactive terminal. The server spawns the CLI without a TTY, so for an MFA-enforced basic-auth user every instance-touching tool fails fast with “MFA code required but no interactive terminal is available” (it does not hang). Use an OAuth profile instead, or pre-authenticate in your own terminal with now-sdk auth --print --format env and export the resulting SN_SDK_INSTANCE_URL + SN_SDK_SESSION_* variables into the server’s environment; spawned commands inherit them.

SDK telemetry

The ServiceNow SDK CLI sends usage telemetry by default. As of SDK 4.13.6 it goes to a ServiceNow-hosted PostHog endpoint (4.11.2 used AppSee), and it includes a hashed user/host id, the instance hostname, and a coding-agent tag. Nearly every command the server spawns emits it (including the lazy auth --list check and missed explain topics). The server does not override the SDK default. Set NO_TELEMETRY=1 in the server’s environment to opt out, or FLUENT_TELEMETRY_FILE= to write the events to a local file instead; spawned commands inherit both. Neither variable is documented by the SDK itself; both were read from @servicenow/sdk-build-core’s telemetry factory.

Usage Examples

Typical Workflow

  1. Initialize Project

    Create a new Fluent app in ~/projects/asset-tracker for IT asset management
    
  2. Develop with Resources

    Show me the business-rule API specification and provide an example snippet
    
  3. Build and Deploy

    Build the app with debug output, then deploy it
    

Note: Authentication is validated lazily using SN_INSTANCE_URL and SN_AUTH_TYPE; those settings do not replace an SDK auth profile unless non-interactive setup can complete. If you need to set up a new profile, run: npx @servicenow/sdk auth --add --type --alias

Testing with MCP Inspector

The MCP Inspector provides a web interface for testing MCP servers.

Launch Inspector

# Test published package
npx -p @modelcontextprotocol/[email protected] mcp-inspector npx @modesty/fluent-mcp

# Or for local development (built server)
npm run build && npm run inspect

# Or against a development build (rebuilt before the inspector starts)
npm run inspect:dev

What to verify

  • The Tools tab shows all 17 tools in deterministic name order.
  • Optional parameters render with their normal types rather than as nullable union forms.
  • Structured server logs appear on the server process stderr/terminal output; stdout remains reserved for MCP protocol traffic.

Test Scenarios

Scenario 1: Explore Business Rule Resources

Objective: Access API specs and code snippets for business rules

Steps:

  1. Launch Inspector and wait for server connection
  2. Navigate to Resources tab
  3. Find and click sn-spec://business-rule in the resource list
  4. Review the API specification showing all available methods and parameters
  5. Go back and search for sn-snippet://business-rule/0001
  6. Click the snippet to view a complete TypeScript example
  7. Verify content includes proper imports and follows Fluent patterns

Expected Results:

  • API spec displays structured documentation with method signatures
  • Snippet shows runnable TypeScript code with ServiceNow metadata patterns
  • Content is properly formatted and readable

Scenario 2: Test SDK Info Command

Objective: Verify SDK version and help information retrieval

Steps:

  1. Navigate to Tools tab
  2. Select sdk_info from the tool list
  3. Test Version:
    • Set flag parameter to -v
    • Click Execute
    • Verify response shows the SDK version (e.g., 4.13.6)
  4. Test Help:
    • Set flag parameter to -h
    • Set command parameter to build
    • Click Execute
    • Verify response shows build command documentation with options
  5. Monitor the server process stderr/terminal output for command execution logs (set FLUENT_MCP_LOG_LEVEL=debug before launch for verbose output)

Expected Results:

  • Version command returns SDK version string
  • Help command returns detailed command documentation
  • List metadata (-lm) returns available Fluent metadata types
  • No unexpected protocol errors; command logs are emitted on stderr rather than through MCP notifications/message
  • Commands execute within 2-3 seconds

Development

Setup: Node.js 22.23.2 or later (.nvmrc pins 22.23.3) and npm 10.9.8 or later. Run npm ci from a fresh checkout.

Task Command
Build the server npm run build (cleans dist/ first)
Run the development build npm run dev (rebuilds, then runs dist/index.js)
Rebuild the development bundle on change npm run dev:watch
Lint and type-check npm run lint, npm run typecheck, npm run typecheck:test
Run all tests npm test
Run one test file node scripts/run-native-tests.mjs test/.test.ts
Coverage report npm run test:coverage (writes coverage/lcov.info)
Re-run tests on change npm run test:watch
Validate resources npm run validate:specs, npm run validate:instructs, npm run validate:snippets
Package the MCPB bundle npm run bundle

Tests use Node’s built-in test runner (node:test) with node:assert/strict. Module mocks are experimental in Node 22, so the test scripts enable --experimental-test-module-mocks for the test process only. Coverage reports only the source files a test loads.

License

MIT

View this README on GitHub

설치

npx -y @modesty/fluent-mcp

설정

{ "mcpServers": { "fluent-mcp": { "command": "npx", "args": ["-y", "@modesty/fluent-mcp"], "env": { "FLUENT_MCP_WORKING_DIR": "/absolute/path/to/your/fluent-project", "SN_INSTANCE_URL": "https://your-instance.service-now.com", "SN_AUTH_TYPE": "basic", "SN_USER_NAME": "local-username", "SN_PASSWORD": "local-password" } } } }