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
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jupiterone/jupiterone-mcp",
"version": "0.0.12",
"version": "0.1.0",
"description": "Model Context Protocol server for JupiterOne account rules and rule details",
"main": "dist/index.js",
"bin": {
Expand All @@ -15,8 +15,7 @@
"test": "jest",
"test-connection": "node test-connection.js",
"lint": "eslint src/**/*.ts",
"format": "prettier --write src/**/*.ts",
"prepare": "npm run build"
"format": "prettier --write src/**/*.ts"
},
"keywords": [
"mcp",
Expand Down Expand Up @@ -61,4 +60,4 @@
"publishConfig": {
"access": "public"
}
}
}
15 changes: 0 additions & 15 deletions src/client/graphql/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,18 +664,3 @@ export const GET_ENTITY_COUNTS = `
}
}
`;

// Get properties for a specific entity type
export const QUERY_PROPERTIES = `
query QueryProperties($entity: String) {
queryProperties(entity: $entity) {
id
accountId
entity
name
valueType
count
__typename
}
}
`;
4 changes: 0 additions & 4 deletions src/client/jupiterone-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,4 @@ export class JupiterOneClient {
async listEntityTypes() {
return this.j1qlService.listEntityTypes();
}

async listEntityProperties(entityType: string) {
return this.j1qlService.listEntityProperties(entityType);
}
}
21 changes: 1 addition & 20 deletions src/client/services/j1ql-service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GraphQLClient } from 'graphql-request';
import { CreateJ1qlFromNaturalLanguageResponse } from '../../types/jupiterone.js';
import { CREATE_J1QL_FROM_NATURAL_LANGUAGE } from '../graphql/mutations.js';
import { QUERY_V2, GET_ENTITY_COUNTS, QUERY_PROPERTIES } from '../graphql/queries.js';
import { QUERY_V2, GET_ENTITY_COUNTS } from '../graphql/queries.js';
import { getEnv } from '../../utils/getEnv.js';

export class J1qlService {
Expand Down Expand Up @@ -117,23 +117,4 @@ export class J1qlService {
types: response.getEntityCounts.types,
};
}

/**
* List properties for a specific entity type
*/
async listEntityProperties(entityType: string): Promise<any[]> {
const response = await this.client.request<{
queryProperties: Array<{
id: string;
accountId: string;
entity: string;
name: string;
valueType: string;
count: number;
__typename: string;
}>;
}>(QUERY_PROPERTIES, { entity: entityType });

return response.queryProperties;
}
}
69 changes: 0 additions & 69 deletions src/descriptions/list-entity-properties.md

This file was deleted.

93 changes: 20 additions & 73 deletions src/generated/description-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -839,8 +839,8 @@ Unified entities typically also have additional enrichment making them valuable

\`\`\`
FIND UnifiedIdentity AS identity
THAT IS << User
THAT RELATES TO AS rel (Device|Host)
THAT IS << User
THAT RELATES TO AS rel (Device|Host)
THAT IS >> UnifiedDevice AS device
RETURN identity.displayName, rel._class, device.displayName
\`\`\`
Expand Down Expand Up @@ -1141,7 +1141,7 @@ Before running any J1QL query, verify:
#### Most Common Errors (Quick Reference)

1. **Missing quotes**: \`name = john\` → \`name = 'john'\`
2. **Wrong quotes**: \`name = "john"\` → \`name = 'john'\`
2. **Wrong quotes**: \`name = "john"\` → \`name = 'john'\`
3. **Alias placement**: \`AS u WITH active = true\` → \`WITH active = true AS u\`
4. **WHERE needs alias**: \`WHERE active = true\` → \`AS u WHERE u.active = true\`
5. **Undefined alias**: \`FIND User RETURN u.name\` → \`FIND User AS u RETURN u.name\`
Expand Down Expand Up @@ -1177,7 +1177,23 @@ Before running any J1QL query, verify:
- LIMIT to prevent timeouts
- Proper capitalization for classes

**Remember**: The execute-j1ql-query tool now provides enhanced error messages with specific suggestions. Always test queries here first!`,
**Remember**: The execute-j1ql-query tool now provides enhanced error messages with specific suggestions. Always test queries here first!

#### 📌 IMPORTANT: Query Results URL

When this tool returns query results, it includes a \`url\` field that provides a direct link to view the results in the JupiterOne UI. **Always share this URL with users when presenting query results** - it allows them to:
- View the data in an interactive table format
- Export results to CSV or other formats
- Save the query for future use
- Share results with team members
- Further refine the query in the JupiterOne UI

Example response:
\`\`\`json
{
"data": [...query results...],
"url": "https://your-account.apps.us.jupiterone.io/home/results?search=..."
}`,
"get-dashboard-details.md": `# Get Dashboard Details Tool

Get detailed information about a specific JupiterOne dashboard including its widgets, layout, and configuration.
Expand Down Expand Up @@ -1398,75 +1414,6 @@ Request the first 5 active alerts:
"limit": 5
}
\`\`\``,
"list-entity-properties.md": `# JupiterOne Entity Properties Discoverer

**Purpose**: Lists all available properties for a specific entity type in your JupiterOne account. This tool is essential for understanding what data fields are available to query for a given entity type.

This tool should be used AFTER running \`list-entity-types\` to discover available entity types, and BEFORE writing J1QL queries that need to access specific properties.

## Features
- Returns all properties available for a specific entity type
- Shows property names, value types, and usage counts
- Helps you understand the data model for specific entities
- Essential for writing accurate J1QL queries with property filters

## Parameters
- \`entityType\`: The entity type to get properties for (e.g., \`aws_instance\`, \`okta_user\`, \`github_user\`)

## Example Usage

### Get properties for AWS instances:
\`\`\`
entityType: "aws_instance"
\`\`\`

### Get properties for Okta users:
\`\`\`
entityType: "okta_user"
\`\`\`

## Response Format
Returns an array of property objects, each containing:
- \`id\`: Unique identifier for the property
- \`accountId\`: The account ID
- \`entity\`: The entity type this property belongs to
- \`name\`: The property name (use this in J1QL queries)
- \`valueType\`: The data type of the property (e.g., "string", "number", "boolean")
- \`count\`: Number of entities that have this property

Example response:
\`\`\`json
[
{
"id": "123456",
"accountId": "j1dev",
"entity": "okta_user",
"name": "email",
"valueType": "string",
"count": 150
},
{
"id": "123457",
"accountId": "j1dev",
"entity": "okta_user",
"name": "active",
"valueType": "boolean",
"count": 150
}
]
\`\`\`

## Use Cases
- **Query Preparation**: Discover available properties before writing J1QL queries
- **Data Exploration**: Understand what data is available for specific entity types
- **Filter Development**: Find properties to use in WHERE clauses and WITH filters
- **Schema Understanding**: Learn about the data model of integrated services

## Workflow Integration
This tool is typically used as part of a three-step process:
1. Run \`list-entity-types\` to discover available entity types
2. Run \`list-entity-properties\` for relevant entity types
3. Write J1QL queries using the discovered types and properties`,
"list-entity-types.md": `# JupiterOne Entity Types Discoverer

**Purpose**: Discovers all entity classes and types in your JupiterOne account. This tool helps you find relevant entity types when building queries or exploring your data model.
Expand Down
32 changes: 0 additions & 32 deletions src/server/mcp-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1958,38 +1958,6 @@ export class JupiterOneMcpServer {
},
});

// Tool: List entity properties
this.registerTool({
name: 'list-entity-properties',
description: loadDescription('list-entity-properties.md'),
schema: {
entityType: z
.string()
.describe('The entity type to get properties for (e.g., "aws_instance", "okta_user")'),
},
handler: async ({ entityType }, client) => {
try {
const results = await client.listEntityProperties(entityType);
return {
content: [
{
type: 'text' as const,
text: JSON.stringify(results, null, 2),
},
],
};
} catch (error) {
return {
content: [
{
type: 'text' as const,
text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
},
});
}

// Helper methods for validation
Expand Down