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
16 changes: 5 additions & 11 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,16 @@ labels: bug
assignees: ''
---

**Describe the bug**
A clear description of what the bug is.
**Describe the bug** A clear description of what the bug is.

**To Reproduce**
Steps to reproduce:
1.
2.
3.
**To Reproduce** Steps to reproduce: 1. 2. 3.

**Expected behavior**
What you expected to happen.
**Expected behavior** What you expected to happen.

**Environment**

- Node.js version:
- Package version:
- OS:

**Additional context**
Any other context about the problem.
**Additional context** Any other context about the problem.
12 changes: 4 additions & 8 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,10 @@ labels: enhancement
assignees: ''
---

**Is your feature request related to a problem?**
A clear description of the problem.
**Is your feature request related to a problem?** A clear description of the problem.

**Describe the solution you'd like**
What you want to happen.
**Describe the solution you'd like** What you want to happen.

**Alternatives considered**
Any alternative solutions you've considered.
**Alternatives considered** Any alternative solutions you've considered.

**Additional context**
Any other context or screenshots.
**Additional context** Any other context or screenshots.
2 changes: 1 addition & 1 deletion .github/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ We will acknowledge receipt within 48 hours and aim to release a fix within 7 da
## Supported Versions

| Version | Supported |
|---------|-----------|
| ------- | --------- |
| 1.0.x | Yes |
30 changes: 15 additions & 15 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: "weekly"
interval: 'weekly'
groups:
development-dependencies:
dependency-type: "development"
dependency-type: 'development'
ignore:
# @typescript-eslint/eslint-plugin peers on typescript ">=4.8.4 <6.1.0".
# A major bump to TS 7 makes `npm ci` fail with ERESOLVE. Revisit when
# typescript-eslint ships TS 7 support.
- dependency-name: "typescript"
update-types: ["version-update:semver-major"]
- dependency-name: 'typescript'
update-types: ['version-update:semver-major']
# graphql 17 is not yet supported by the surrounding ecosystem:
# graphql-request peers on "14 - 16", graphql-yoga on "^15.2.0 || ^16.0.0".
# Revisit once those ship v17-compatible releases.
- dependency-name: "graphql"
update-types: ["version-update:semver-major"]
- dependency-name: 'graphql'
update-types: ['version-update:semver-major']
commit-message:
prefix: "fix"
prefix-development: "chore"
- package-ecosystem: "github-actions"
directory: "/"
prefix: 'fix'
prefix-development: 'chore'
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: "weekly"
interval: 'weekly'
groups:
github-actions:
patterns:
- "*"
- '*'
commit-message:
prefix: "chore"
prefix: 'chore'
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ jobs:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run lint
- name: Ultracite check
run: npm run lint
- run: npm run typecheck
- run: npm test
- run: npm run build
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ on:
workflow_dispatch:
inputs:
bump:
description: "Semver bump"
description: 'Semver bump'
required: true
default: "patch"
default: 'patch'
type: choice
options:
- patch
Expand All @@ -29,7 +29,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 22
registry-url: "https://registry.npmjs.org"
registry-url: 'https://registry.npmjs.org'
- name: Upgrade npm (OIDC trusted publishing needs npm >= 11.5; pin 11)
run: npm install -g npm@11
- name: Install
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AGENTS.md
7 changes: 0 additions & 7 deletions .prettierrc

This file was deleted.

123 changes: 123 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Ultracite Code Standards

This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.

## Quick Reference

- **Format code**: `npm exec -- ultracite fix`
- **Check for issues**: `npm exec -- ultracite check`
- **Diagnose setup**: `npm exec -- ultracite doctor`

ESLint + Prettier + Stylelint (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.

---

## Core Principles

Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity.

### Type Safety & Explicitness

- Use explicit types for function parameters and return values when they enhance clarity
- Prefer `unknown` over `any` when the type is genuinely unknown
- Use const assertions (`as const`) for immutable values and literal types
- Leverage TypeScript's type narrowing instead of type assertions
- Use meaningful variable names instead of magic numbers - extract constants with descriptive names

### Modern JavaScript/TypeScript

- Use arrow functions for callbacks and short functions
- Prefer `for...of` loops over `.forEach()` and indexed `for` loops
- Use optional chaining (`?.`) and nullish coalescing (`??`) for safer property access
- Prefer template literals over string concatenation
- Use destructuring for object and array assignments
- Use `const` by default, `let` only when reassignment is needed, never `var`

### Async & Promises

- Always `await` promises in async functions - don't forget to use the return value
- Use `async/await` syntax instead of promise chains for better readability
- Handle errors appropriately in async code with try-catch blocks
- Don't use async functions as Promise executors

### React & JSX

- Use function components over class components
- Call hooks at the top level only, never conditionally
- Specify all dependencies in hook dependency arrays correctly
- Use the `key` prop for elements in iterables (prefer unique IDs over array indices)
- Nest children between opening and closing tags instead of passing as props
- Don't define components inside other components
- Use semantic HTML and ARIA attributes for accessibility:
- Provide meaningful alt text for images
- Use proper heading hierarchy
- Add labels for form inputs
- Include keyboard event handlers alongside mouse events
- Use semantic elements (`<button>`, `<nav>`, etc.) instead of divs with roles

### Error Handling & Debugging

- Remove `console.log`, `debugger`, and `alert` statements from production code
- Throw `Error` objects with descriptive messages, not strings or other values
- Use `try-catch` blocks meaningfully - don't catch errors just to rethrow them
- Prefer early returns over nested conditionals for error cases

### Code Organization

- Keep functions focused and under reasonable cognitive complexity limits
- Extract complex conditions into well-named boolean variables
- Use early returns to reduce nesting
- Prefer simple conditionals over nested ternary operators
- Group related code together and separate concerns

### Security

- Add `rel="noopener"` when using `target="_blank"` on links
- Avoid `dangerouslySetInnerHTML` unless absolutely necessary
- Don't use `eval()` or assign directly to `document.cookie`
- Validate and sanitize user input

### Performance

- Avoid spread syntax in accumulators within loops
- Use top-level regex literals instead of creating them in loops
- Prefer specific imports over namespace imports
- Avoid barrel files (index files that re-export everything)
- Use proper image components (e.g., Next.js `<Image>`) over `<img>` tags

### Framework-Specific Guidance

**Next.js:**
- Use Next.js `<Image>` component for images
- Use `next/head` or App Router metadata API for head elements
- Use Server Components for async data fetching instead of async Client Components

**React 19+:**
- Use ref as a prop instead of `React.forwardRef`

**Solid/Svelte/Vue/Qwik:**
- Use `class` and `for` attributes (not `className` or `htmlFor`)

---

## Testing

- Write assertions inside `it()` or `test()` blocks
- Avoid done callbacks in async tests - use async/await instead
- Don't use `.only` or `.skip` in committed code
- Keep test suites reasonably flat - avoid excessive `describe` nesting

## When ESLint + Prettier + Stylelint Can't Help

ESLint + Prettier + Stylelint's linter will catch most issues automatically. Focus your attention on:

1. **Business logic correctness** - ESLint + Prettier + Stylelint can't validate your algorithms
2. **Meaningful naming** - Use descriptive names for functions, variables, and types
3. **Architecture decisions** - Component structure, data flow, and API design
4. **Edge cases** - Handle boundary conditions and error states
5. **User experience** - Accessibility, performance, and usability considerations
6. **Documentation** - Add comments for complex logic, but prefer self-documenting code

---

Most formatting and common issues are automatically fixed by ESLint + Prettier + Stylelint. Run `npm exec -- ultracite fix` before committing to ensure compliance.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0] - 2026-02-15

### Added

- Schema introspection and parsing via `fetchSchema` and `parseSchema`
- Operation builder with configurable depth via `buildOperation`
- MCP server generation with `createAgentToolkitServer` and `createToolsFromSchema`
Expand Down
12 changes: 2 additions & 10 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.

## Our Standards

Expand All @@ -29,10 +24,7 @@ Examples of unacceptable behavior:

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the project maintainers. All complaints will be reviewed and
investigated and will result in a response that is deemed necessary and
appropriate to the circumstances.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the project maintainers. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.

## Attribution

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ npm run lint # Run ESLint
## Reporting Bugs

Please open an issue with:

- Steps to reproduce
- Expected behavior
- Actual behavior
Expand Down
25 changes: 9 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
</p>

---

Turn any GraphQL API into AI-agent-ready tools -- MCP servers, LangChain tools, and framework adapters.

**graphql-agent-toolkit** introspects a GraphQL endpoint, generates typed operations, and exposes them as tools that AI agents can discover and call. It supports the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) out of the box, so you can connect any MCP-compatible AI client to any GraphQL API in seconds.
Expand Down Expand Up @@ -149,8 +150,8 @@ import { summarizeResponse, formatForLLM } from 'graphql-agent-toolkit';

// Summarize a large response
const { summary, metadata } = summarizeResponse(largeResponse, {
maxItems: 5, // max array items to include
maxDepth: 3, // max nesting depth
maxItems: 5, // max array items to include
maxDepth: 3, // max nesting depth
maxStringLength: 200, // truncate long strings
includeMetadata: true, // add _meta with counts
});
Expand Down Expand Up @@ -223,9 +224,9 @@ import { generateMockData, createMockExecutor } from 'graphql-agent-toolkit';

// Generate mock data for a specific type
const mockUser = generateMockData(schema, 'User', {
seed: 42, // deterministic output
arrayLength: 3, // items per list field
maxDepth: 3, // max recursion depth
seed: 42, // deterministic output
arrayLength: 3, // items per list field
maxDepth: 3, // max recursion depth
});
console.log(mockUser);
// { id: 'id_id_0', name: 'mock_name', posts: [...] }
Expand All @@ -234,10 +235,7 @@ console.log(mockUser);
const mockExecutor = createMockExecutor(schema, { seed: 42 });

// Use it anywhere a GraphQLExecutor is expected
const result = await mockExecutor.execute(
'query { user(id: "1") { id name } }',
{ id: '1' }
);
const result = await mockExecutor.execute('query { user(id: "1") { id name } }', { id: '1' });
```

Use the `@mock()` directive in field descriptions for custom values:
Expand Down Expand Up @@ -283,12 +281,7 @@ Add to your MCP client configuration (e.g., Claude Desktop):
"mcpServers": {
"my-graphql-api": {
"command": "npx",
"args": [
"graphql-agent-toolkit",
"serve",
"--endpoint",
"https://your-api.com/graphql"
]
"args": ["graphql-agent-toolkit", "serve", "--endpoint", "https://your-api.com/graphql"]
}
}
}
Expand All @@ -299,7 +292,7 @@ Add to your MCP client configuration (e.g., Claude Desktop):
The `AgentToolkitConfig` object accepts:

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| --- | --- | --- | --- |
| `endpoint` | `string` | (required) | GraphQL endpoint URL |
| `headers` | `Record<string, string>` | `{}` | HTTP headers for requests |
| `operationDepth` | `number` | `2` | Max depth for generated selection sets |
Expand Down
Loading