Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Fluent (ServiceNow SDK) MCP bridges ServiceNow development tools with modern AI-

Key capabilities include:

- All ServiceNow SDK CLI commands: `version`, `help`, `debug`, `upgrade`, `auth`, `init`, `build`, `install`, `transform`, `dependencies`
- ServiceNow authentication via `@servicenow/sdk auth --add <instance>`
- All ServiceNow SDK CLI commands: `version`, `help`, `auth`, `init`, `build`, `install`, `upgrade`, `dependencies`, `transform`
- ServiceNow instance authentication via `npx now-sdk auth --add <instance>`
- API specifications for metadata types like `acl`, `business-rule`, `client-script`, `table`, `ui-action` and more
- Code snippets and examples for different metadata types
- Instructions for creating and modifying metadata types
Expand All @@ -30,7 +30,6 @@ Note: Use `init` command to switch to a working directory for existing Fluent pr
| -------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `version` | Get ServiceNow SDK version information | None |
| `help` | Get help information about ServiceNow SDK commands | `command`: (Optional) The specific command to get help for |
| `debug` | Enable debug mode for ServiceNow SDK commands | `command`: The command to run with debug mode enabled |
| `upgrade` | Upgrade ServiceNow SDK to the latest version | `check`: (Optional) Only check for updates without upgrading, `debug`: (Optional) Enable debug - **disabled for now** |
| `auth` | Authenticate to a ServiceNow instance | `add`: (Optional) Instance URL to add, `type`: (Optional) Authentication method, `alias`: (Optional) Alias for the instance |
| `init` | Initialize a new ServiceNow application | `from`: (Optional) sys_id or path, `appName`: App name, `packageName`: Package name, `scopeName`: Scope name, `auth`: (Optional) Authentication alias |
Expand Down
330 changes: 165 additions & 165 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@modesty/fluent-mcp",
"version": "0.0.12",
"version": "0.0.13",
"description": "MCP server for Fluent (ServiceNow SDK)",
"keywords": [
"Servicenow SDK",
Expand Down Expand Up @@ -63,11 +63,11 @@
"@rollup/plugin-typescript": "^12.1.4",
"@types/jest": "^30.0.0",
"@types/node": "^24.3.0",
"@typescript-eslint/eslint-plugin": "^8.39.1",
"@typescript-eslint/parser": "^8.39.1",
"@typescript-eslint/eslint-plugin": "^8.40.0",
"@typescript-eslint/parser": "^8.40.0",
"eslint": "^9.33.0",
"jest": "^30.0.5",
"rollup": "^4.46.2",
"rollup": "^4.46.3",
"rollup-plugin-node-builtins": "^2.1.2",
"rollup-plugin-sourcemaps": "^0.6.3",
"ts-jest": "^29.4.1",
Expand Down
4 changes: 2 additions & 2 deletions src/tools/commands/authCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { SessionFallbackCommand } from './sessionFallbackCommand.js';
* Handles adding, listing, deleting, and selecting auth profiles
*/
export class AuthCommand extends SessionFallbackCommand {
name = 'prepare_fluent_auth';
description = 'Generate shell command to manage Fluent (ServiceNow SDK) authentication to <instance_url> with credential profiles, including create new auth alias, list /show existing ones, delete or use an existing one';
name = 'manage_fluent_auth';
description = 'Manage Fluent (ServiceNow SDK) authentication to instance with credential profiles, use this to add, list, delete, or switch between authentication profiles';
arguments: CommandArgument[] = [
{
name: 'add',
Expand Down
4 changes: 2 additions & 2 deletions src/tools/commands/buildCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { SessionAwareCLICommand } from './sessionAwareCommand.js';
* Uses the session's working directory
*/
export class BuildCommand extends SessionAwareCLICommand {
name = 'fluent_build';
description = "Build the Fluent (ServiceNow SDK) application in the current session's working directory";
name = 'build_fluent_app';
description = 'Build the Fluent (ServiceNow SDK) application located in the current working directory.';
arguments: CommandArgument[] = [
{
name: 'debug',
Expand Down
41 changes: 2 additions & 39 deletions src/tools/commands/dependenciesCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,9 @@ import { SessionAwareCLICommand } from './sessionAwareCommand.js';
* Uses the session's working directory
*/
export class DependenciesCommand extends SessionAwareCLICommand {
name = 'fluent_dependencies';
description = "Manage dependencies for the Fluent (ServiceNow SDK) application in the current session's working directory";
name = 'download_fluent_dependencies';
description = 'Download configured dependencies in now.config.json and TypeScript type definitions for use in the application';
arguments: CommandArgument[] = [
{
name: 'add',
type: 'boolean',
required: false,
description: 'Add dependencies',
},
{
name: 'install',
type: 'boolean',
required: false,
description: 'Install dependencies',
},
{
name: 'list',
type: 'boolean',
required: false,
description: 'List dependencies',
},
{
name: 'packageName',
type: 'string',
required: false,
description: 'Name of the package to add',
},
{
name: 'auth',
type: 'string',
Expand All @@ -51,23 +27,10 @@ export class DependenciesCommand extends SessionAwareCLICommand {
const sdkArgs = ['now-sdk', 'dependencies'];

// Add optional arguments if provided
if (args.add) {
sdkArgs.push('--add');

if (args.packageName) {
sdkArgs.push(args.packageName as string);
}
} else if (args.install) {
sdkArgs.push('--install');
} else if (args.list) {
sdkArgs.push('--list');
}

if (args.auth) {
sdkArgs.push('--auth', args.auth as string);
}

// Add debug flag if specified
if (args.debug) {
sdkArgs.push('--debug');
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/commands/helpCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { SessionFallbackCommand } from './sessionFallbackCommand.js';
*/
export class HelpCommand extends SessionFallbackCommand {
name = 'get_fluent_help';
description = 'Get help information about Fluent (ServiceNow SDK) commands';
description = 'Provides help and usage information for any Fluent (ServiceNow SDK) command.';
arguments: CommandArgument[] = [
{
name: 'command',
Expand Down
16 changes: 8 additions & 8 deletions src/tools/commands/initCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,44 @@ import logger from '../../utils/logger.js';
* Implements the init command with validation of prerequisites
*/
export class InitCommand extends BaseCLICommand {
name = 'prepare_fluent_init';
description = "Generate the Shell command to initialize a Fluent (ServiceNow SDK) application: If specified working directory has no Fluent (ServiceNow SDK) application, it will create a new one. If it has a Fluent (ServiceNow SDK) application, it will save the directory as the working directory for future commands, including build, install, transform and dependencies.\nWhen converting an existing ServiceNow application, use the 'from' argument to specify the system ID or path to initialize from. \nNote, if the specified directory has no package-lock.json file, run `npm install` first.\nNote, This command will not execute the initialization but prepare the shell command to be run later.";
name = 'init_fluent_app';
description = 'Initialize a new ServiceNow custom application or convert a legacy ServiceNow application from an instance or directory within the current directory';
arguments: CommandArgument[] = [
{
name: 'from',
type: 'string',
required: false,
description: 'convert existing scoped app to Fluent by sys_id or path to initialize from',
description: 'convert existing scoped app to Fluent by sys_id or file path to initialize from',
},
{
name: 'appName',
type: 'string',
required: true,
description: 'The name of the application, this is the user friendly name that will be displayed in ServiceNow UI.',
description: 'The name of the application.',
},
{
name: 'packageName',
type: 'string',
required: true,
description: "The NPM package name for the application, usually it's the snake-case of appName in lowercase.",
description: "The NPM package name for the application, usually it's the snake-case of appName in lowercase with company prefix.",
},
{
name: 'scopeName',
type: 'string',
required: true,
description: "The scope name for the application in <prefix>_<scope_name> format. For localhost development, it should be in the format of 'sn_<scope_name>'. This is required to create a new Fluent (ServiceNow SDK) application, no spaces allowed.",
description: "The scope name for the application in <prefix>_<scope_name> format. For localhost development, it should be in the format of 'sn_<scope_name>'. No spaces allowed, no greater than 18 characters.",
},
{
name: 'auth',
type: 'string',
required: false,
description: "The authentication alias to use. If not provided, the default authentication alias will be used. You can set up authentication using the 'auth' command.",
description: "The authentication alias to use. If not provided, the default authentication alias will be used. You can set up authentication using the 'manage_fluent_auth' tool.",
},
{
name: 'workingDirectory',
type: 'string',
required: false,
description: "The directory where the Fluent (ServiceNow SDK) application will be created. If not provided, a new directory will be created in the user's home directory.",
description: "The directory where the Fluent (ServiceNow SDK) application will be created. If not provided, a new directory will be created in the project root if exists or the user's home directory.",
},
{
name: 'debug',
Expand Down
4 changes: 2 additions & 2 deletions src/tools/commands/installCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { SessionAwareCLICommand } from './sessionAwareCommand.js';
* Uses the session's working directory
*/
export class InstallCommand extends SessionAwareCLICommand {
name = 'install_fluent_app';
description = "Install / Deploy the Fluent (ServiceNow SDK) application in the current session's working directory to a ServiceNow instance";
name = 'deploy_fluent_app';
description = 'Deploy the Fluent (ServiceNow SDK) application to a ServiceNow instance by auth alias or default auth';
arguments: CommandArgument[] = [
{
name: 'auth',
Expand Down
27 changes: 18 additions & 9 deletions src/tools/commands/transformCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,25 @@ import { SessionAwareCLICommand } from './sessionAwareCommand.js';
*/
export class TransformCommand extends SessionAwareCLICommand {
name = 'fluent_transform';
description = "Transform files in the Fluent (ServiceNow SDK) application in the current session's working directory";
description = 'Download and convert XML records from instance or from a local path into Fluent source code';
arguments: CommandArgument[] = [
{
name: 'source',
name: 'from',
type: 'string',
required: false,
description: 'Source file or directory to transform',
description: 'Path to local XML file(s)/directory to transform',
},
{
name: 'destination',
name: 'directory',
type: 'string',
required: false,
description: 'Destination file or directory for transformed output',
description: 'Path to "package.json", default to current working directory',
},
{
name: 'preview',
type: 'boolean',
required: false,
description: 'Preview fluent output and any transform errors without saving, default false',
},
{
name: 'debug',
Expand All @@ -33,14 +39,17 @@ export class TransformCommand extends SessionAwareCLICommand {
const sdkArgs = ['now-sdk', 'transform'];

// Add optional arguments if provided
if (args.source) {
sdkArgs.push('--source', args.source as string);
if (args.from) {
sdkArgs.push('--from', args.from as string);
}

if (args.destination) {
sdkArgs.push('--destination', args.destination as string);
if (args.directory) {
sdkArgs.push('--directory', args.directory as string);
}

if (args.preview) {
sdkArgs.push('--preview', args.preview as string);
}
// Add debug flag if specified
if (args.debug) {
sdkArgs.push('--debug');
Expand Down
2 changes: 1 addition & 1 deletion src/tools/commands/versionCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SessionFallbackCommand } from './sessionFallbackCommand.js';
*/
export class VersionCommand extends SessionFallbackCommand {
name = 'get_fluent_version';
description = 'Get Fluent (ServiceNow SDK) version information';
description = 'Retrieves the version number of the installed Fluent (ServiceNow SDK)';
arguments: CommandArgument[] = [];

constructor(commandProcessor: CommandProcessor) {
Expand Down
8 changes: 4 additions & 4 deletions src/tools/resourceTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export abstract class BaseResourceCommand implements CLICommand {
*/
export class GetApiSpecCommand extends BaseResourceCommand {
name = 'get-api-spec';
description = 'Get API specification for a ServiceNow metadata type';
description = 'Fetches the Fluent API specification for a given ServiceNow metadata type (e.g., "business-rule", "acl", etc.).';
resourceType = ResourceType.SPEC;
}

Expand All @@ -122,7 +122,7 @@ export class GetApiSpecCommand extends BaseResourceCommand {
*/
export class GetSnippetCommand extends BaseResourceCommand {
name = 'get-snippet';
description = 'Get code snippet for a ServiceNow metadata type';
description = 'Fetches the Fluent code snippet for a given ServiceNow metadata type';
resourceType = ResourceType.SNIPPET;

/**
Expand Down Expand Up @@ -200,7 +200,7 @@ export class GetSnippetCommand extends BaseResourceCommand {
*/
export class GetInstructCommand extends BaseResourceCommand {
name = 'get-instruct';
description = 'Get instructions for a ServiceNow metadata type';
description = 'Retrieves instructions of Fluent API usage for a given ServiceNow metadata type';
resourceType = ResourceType.INSTRUCT;
}

Expand All @@ -209,7 +209,7 @@ export class GetInstructCommand extends BaseResourceCommand {
*/
export class ListMetadataTypesCommand implements CLICommand {
name = 'list-metadata-types';
description = 'List all available ServiceNow metadata types';
description = 'List all available ServiceNow metadata types that currently supported by Fluent (ServiceNow SDK)';
arguments: CommandArgument[] = [];

private resourceLoader: ResourceLoader;
Expand Down
2 changes: 2 additions & 0 deletions src/tools/toolsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export class ToolsManager {

commands.forEach((command) => {
this.commandRegistry.register(command);
// Register each CLI command as an MCP tool
this.registerToolFromCommand(command);
});

// Register resource tools
Expand Down
Loading