Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
63d8953
chore(docs): use top-level-await in example snippets
stainless-app[bot] Jun 4, 2025
604d380
chore(internal): fix readablestream types in node 20
stainless-app[bot] Jun 4, 2025
bec8bea
feat(mcp): implement support for binary responses
stainless-app[bot] Jun 6, 2025
8a16797
chore: avoid type error in certain environments
stainless-app[bot] Jun 7, 2025
43d4446
chore(mcp): provides high-level initMcpServer function and exports kn…
stainless-app[bot] Jun 11, 2025
6805e78
fix: publish script — handle NPM errors correctly
stainless-app[bot] Jun 14, 2025
03358ec
chore(internal): add pure annotations, make base APIResource abstract
stainless-app[bot] Jun 14, 2025
db4bb4f
feat(mcp): set X-Stainless-MCP header
stainless-app[bot] Jun 14, 2025
301c341
chore(client): refactor imports
stainless-app[bot] Jun 17, 2025
5f69f71
feat(client): add support for endpoint-specific base URLs
stainless-app[bot] Jun 17, 2025
840289e
chore(ci): enable for pull requests
stainless-app[bot] Jun 17, 2025
2413a0e
chore(readme): update badges
stainless-app[bot] Jun 18, 2025
35f22a6
chore(readme): use better example snippet for undocumented params
stainless-app[bot] Jun 19, 2025
0112989
fix(client): explicitly copy fetch in withOptions
stainless-app[bot] Jun 21, 2025
02f5170
fix(ci): release-doctor — report correct token name
stainless-app[bot] Jun 27, 2025
d2e9558
fix(client): get fetchOptions type more reliably
stainless-app[bot] Jun 27, 2025
cf544d1
chore(ci): only run for pushes and fork pull requests
stainless-app[bot] Jun 28, 2025
0c8d6f0
chore(client): improve path param validation
stainless-app[bot] Jul 1, 2025
16b7822
chore: add docs to RequestOptions type
stainless-app[bot] Jul 3, 2025
d763165
chore: make some internal functions async
stainless-app[bot] Jul 10, 2025
8d0556f
feat(mcp): support filtering tool results by a jq expression
stainless-app[bot] Jul 11, 2025
1627904
fix(mcp): relax input type for asTextContextResult
stainless-app[bot] Jul 11, 2025
391d825
fix(mcp): support jq filtering on cloudflare workers
stainless-app[bot] Jul 16, 2025
6d55f27
chore(mcp): rework imports in tools
stainless-app[bot] Jul 16, 2025
d0b6815
chore(ts): reorder package.json imports
stainless-app[bot] Jul 17, 2025
62ef41e
chore(mcp): formatting
stainless-app[bot] Jul 17, 2025
d7e791b
fix(mcp): include required section for top-level properties and suppo…
stainless-app[bot] Jul 18, 2025
bda7719
chore(internal): codegen related update
stainless-app[bot] Jul 24, 2025
94bd11e
release: 0.11.0
stainless-app[bot] Jul 24, 2025
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
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ on:
- 'integrated/**'
- 'stl-preview-head/**'
- 'stl-preview-base/**'
pull_request:
branches-ignore:
- 'stl-preview-head/**'
- 'stl-preview-base/**'

jobs:
lint:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/isaacus-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4

Expand All @@ -31,6 +36,7 @@ jobs:
timeout-minutes: 5
name: build
runs-on: ${{ github.repository == 'stainless-sdks/isaacus-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
permissions:
contents: read
id-token: write
Expand Down Expand Up @@ -66,6 +72,7 @@ jobs:
timeout-minutes: 10
name: test
runs-on: ${{ github.repository == 'stainless-sdks/isaacus-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4

Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.10.0"
".": "0.11.0"
}
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
# Changelog

## 0.11.0 (2025-07-24)

Full Changelog: [v0.10.0...v0.11.0](https://github.com/isaacus-dev/isaacus-typescript/compare/v0.10.0...v0.11.0)

### Features

* **client:** add support for endpoint-specific base URLs ([5f69f71](https://github.com/isaacus-dev/isaacus-typescript/commit/5f69f71f60b25ce1559a244ab666042b944533b0))
* **mcp:** implement support for binary responses ([bec8bea](https://github.com/isaacus-dev/isaacus-typescript/commit/bec8beac1c9e9187aa3cbeb6ba49764763530277))
* **mcp:** set X-Stainless-MCP header ([db4bb4f](https://github.com/isaacus-dev/isaacus-typescript/commit/db4bb4f568df5883c148250104123900466b2f05))
* **mcp:** support filtering tool results by a jq expression ([8d0556f](https://github.com/isaacus-dev/isaacus-typescript/commit/8d0556f619b94473c24c362e72cbc4eaba644374))


### Bug Fixes

* **ci:** release-doctor — report correct token name ([02f5170](https://github.com/isaacus-dev/isaacus-typescript/commit/02f5170723293eda6ae0995673136e3528c39f8c))
* **client:** explicitly copy fetch in withOptions ([0112989](https://github.com/isaacus-dev/isaacus-typescript/commit/01129895de3a6d135186e75817f75c8512084985))
* **client:** get fetchOptions type more reliably ([d2e9558](https://github.com/isaacus-dev/isaacus-typescript/commit/d2e9558832362fff02e3ffd5f5a950b609bdbd0c))
* **mcp:** include required section for top-level properties and support naming transformations ([d7e791b](https://github.com/isaacus-dev/isaacus-typescript/commit/d7e791bb7a3afbe7d8bf6a2c48a010fd091ada8d))
* **mcp:** relax input type for asTextContextResult ([1627904](https://github.com/isaacus-dev/isaacus-typescript/commit/1627904fcb3474757ba2a29f940b5a4ce067b053))
* **mcp:** support jq filtering on cloudflare workers ([391d825](https://github.com/isaacus-dev/isaacus-typescript/commit/391d8252818ab34f67f7ca02119a6660cdbe5520))
* publish script — handle NPM errors correctly ([6805e78](https://github.com/isaacus-dev/isaacus-typescript/commit/6805e78dc985503dd1f84a8de227aedd5dddf99d))


### Chores

* add docs to RequestOptions type ([16b7822](https://github.com/isaacus-dev/isaacus-typescript/commit/16b7822028f977b12a1c262e6b0a6602fb1ce8dd))
* avoid type error in certain environments ([8a16797](https://github.com/isaacus-dev/isaacus-typescript/commit/8a167970c0102371267194262318788f07dafc1d))
* **ci:** enable for pull requests ([840289e](https://github.com/isaacus-dev/isaacus-typescript/commit/840289ede6ef0e034cf1b72a4d3a324d467cf43e))
* **ci:** only run for pushes and fork pull requests ([cf544d1](https://github.com/isaacus-dev/isaacus-typescript/commit/cf544d1ae1cc37bb2cfd13189652bb2b0a2ab92e))
* **client:** improve path param validation ([0c8d6f0](https://github.com/isaacus-dev/isaacus-typescript/commit/0c8d6f0123f808d8bc950936c45fbf7dfbe7ce07))
* **client:** refactor imports ([301c341](https://github.com/isaacus-dev/isaacus-typescript/commit/301c34137a10f732d62218fedf0614a068acd997))
* **docs:** use top-level-await in example snippets ([63d8953](https://github.com/isaacus-dev/isaacus-typescript/commit/63d895384acdadbeee292f951d524df90508c9b2))
* **internal:** add pure annotations, make base APIResource abstract ([03358ec](https://github.com/isaacus-dev/isaacus-typescript/commit/03358ec382f8c487656f80e5679a73aa54e8a867))
* **internal:** codegen related update ([bda7719](https://github.com/isaacus-dev/isaacus-typescript/commit/bda771936be7dd0db83239b898a9fb8e8fd4a6ce))
* **internal:** fix readablestream types in node 20 ([604d380](https://github.com/isaacus-dev/isaacus-typescript/commit/604d380c9062489e279a76750b8cbf3707f16ecd))
* make some internal functions async ([d763165](https://github.com/isaacus-dev/isaacus-typescript/commit/d76316597b31c533754260474bee660e515fbffc))
* **mcp:** formatting ([62ef41e](https://github.com/isaacus-dev/isaacus-typescript/commit/62ef41ef9a61df100c684bb7cc694c299a84daf9))
* **mcp:** provides high-level initMcpServer function and exports known clients ([43d4446](https://github.com/isaacus-dev/isaacus-typescript/commit/43d44461cf592c7a93277cc6b939ffaf23da2342))
* **mcp:** rework imports in tools ([6d55f27](https://github.com/isaacus-dev/isaacus-typescript/commit/6d55f27f2157499c3ba7e5e137f821909269d5df))
* **readme:** update badges ([2413a0e](https://github.com/isaacus-dev/isaacus-typescript/commit/2413a0e5a09e1aff4490aef3f27eff77fb1e5c0b))
* **readme:** use better example snippet for undocumented params ([35f22a6](https://github.com/isaacus-dev/isaacus-typescript/commit/35f22a6f4288fe6736ea39e20870b59adfc91e58))
* **ts:** reorder package.json imports ([d0b6815](https://github.com/isaacus-dev/isaacus-typescript/commit/d0b6815a17366c5f67372cd44c4e43a4977cc3dc))

## 0.10.0 (2025-06-03)

Full Changelog: [v0.9.0...v0.10.0](https://github.com/isaacus-dev/isaacus-typescript/compare/v0.9.0...v0.10.0)
Expand Down
75 changes: 31 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Isaacus TypeScript API Library

[![NPM version](https://img.shields.io/npm/v/isaacus.svg)](https://npmjs.org/package/isaacus) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/isaacus)
[![NPM version](<https://img.shields.io/npm/v/isaacus.svg?label=npm%20(stable)>)](https://npmjs.org/package/isaacus) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/isaacus)

This library provides convenient access to the Isaacus REST API from server-side TypeScript or JavaScript.

Expand All @@ -26,17 +26,13 @@ const client = new Isaacus({
apiKey: process.env['ISAACUS_API_KEY'], // This is the default and can be omitted
});

async function main() {
const universalClassification = await client.classifications.universal.create({
model: 'kanon-universal-classifier',
query: 'This is a confidentiality clause.',
texts: ['I agree not to tell anyone about the document.'],
});

console.log(universalClassification.classifications);
}
const universalClassification = await client.classifications.universal.create({
model: 'kanon-universal-classifier',
query: 'This is a confidentiality clause.',
texts: ['I agree not to tell anyone about the document.'],
});

main();
console.log(universalClassification.classifications);
```

### Request & Response types
Expand All @@ -51,17 +47,13 @@ const client = new Isaacus({
apiKey: process.env['ISAACUS_API_KEY'], // This is the default and can be omitted
});

async function main() {
const params: Isaacus.Classifications.UniversalCreateParams = {
model: 'kanon-universal-classifier',
query: 'This is a confidentiality clause.',
texts: ['I agree not to tell anyone about the document.'],
};
const universalClassification: Isaacus.Classifications.UniversalClassification =
await client.classifications.universal.create(params);
}

main();
const params: Isaacus.Classifications.UniversalCreateParams = {
model: 'kanon-universal-classifier',
query: 'This is a confidentiality clause.',
texts: ['I agree not to tell anyone about the document.'],
};
const universalClassification: Isaacus.Classifications.UniversalClassification =
await client.classifications.universal.create(params);
```

Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
Expand All @@ -74,25 +66,21 @@ a subclass of `APIError` will be thrown:

<!-- prettier-ignore -->
```ts
async function main() {
const universalClassification = await client.classifications.universal
.create({
model: 'kanon-universal-classifier',
query: 'This is a confidentiality clause.',
texts: ['I agree not to tell anyone about the document.'],
})
.catch(async (err) => {
if (err instanceof Isaacus.APIError) {
console.log(err.status); // 400
console.log(err.name); // BadRequestError
console.log(err.headers); // {server: 'nginx', ...}
} else {
throw err;
}
});
}

main();
const universalClassification = await client.classifications.universal
.create({
model: 'kanon-universal-classifier',
query: 'This is a confidentiality clause.',
texts: ['I agree not to tell anyone about the document.'],
})
.catch(async (err) => {
if (err instanceof Isaacus.APIError) {
console.log(err.status); // 400
console.log(err.name); // BadRequestError
console.log(err.headers); // {server: 'nginx', ...}
} else {
throw err;
}
});
```

Error codes are as follows:
Expand Down Expand Up @@ -262,9 +250,8 @@ parameter. This library doesn't validate at runtime that the request matches the
send will be sent as-is.

```ts
client.foo.create({
foo: 'my_param',
bar: 12,
client.classifications.universal.create({
// ...
// @ts-expect-error baz is not yet public
baz: 'undocumented option',
});
Expand Down
2 changes: 1 addition & 1 deletion bin/check-release-environment
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
errors=()

if [ -z "${NPM_TOKEN}" ]; then
errors+=("The ISAACUS_NPM_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets")
errors+=("The NPM_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets")
fi

lenErrors=${#errors[@]}
Expand Down
34 changes: 27 additions & 7 deletions bin/publish-npm
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,35 @@ npm config set '//registry.npmjs.org/:_authToken' "$NPM_TOKEN"
yarn build
cd dist

# Get package name and version from package.json
PACKAGE_NAME="$(jq -r -e '.name' ./package.json)"
VERSION="$(jq -r -e '.version' ./package.json)"

# Get latest version from npm
#
# If the package doesn't exist, yarn will return
# {"type":"error","data":"Received invalid response from npm."}
# where .data.version doesn't exist so LAST_VERSION will be an empty string.
LAST_VERSION="$(yarn info --json 2> /dev/null | jq -r '.data.version')"

# Get current version from package.json
VERSION="$(node -p "require('./package.json').version")"
# If the package doesn't exist, npm will return:
# {
# "error": {
# "code": "E404",
# "summary": "Unpublished on 2025-06-05T09:54:53.528Z",
# "detail": "'the_package' is not in this registry..."
# }
# }
NPM_INFO="$(npm view "$PACKAGE_NAME" version --json 2>/dev/null || true)"

# Check if we got an E404 error
if echo "$NPM_INFO" | jq -e '.error.code == "E404"' > /dev/null 2>&1; then
# Package doesn't exist yet, no last version
LAST_VERSION=""
elif echo "$NPM_INFO" | jq -e '.error' > /dev/null 2>&1; then
# Report other errors
echo "ERROR: npm returned unexpected data:"
echo "$NPM_INFO"
exit 1
else
# Success - get the version
LAST_VERSION=$(echo "$NPM_INFO" | jq -r '.') # strip quotes
fi

# Check if current version is pre-release (e.g. alpha / beta / rc)
CURRENT_IS_PRERELEASE=false
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "isaacus",
"version": "0.10.0",
"version": "0.11.0",
"description": "The official TypeScript library for the Isaacus API",
"author": "Isaacus <support@isaacus.com>",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -30,7 +30,6 @@
"@swc/jest": "^0.2.29",
"@types/jest": "^29.4.0",
"@types/node": "^20.17.6",
"typescript-eslint": "8.31.1",
"@typescript-eslint/eslint-plugin": "8.31.1",
"@typescript-eslint/parser": "8.31.1",
"eslint": "^9.20.1",
Expand All @@ -42,9 +41,10 @@
"publint": "^0.2.12",
"ts-jest": "^29.1.0",
"ts-node": "^10.5.0",
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz",
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.8/tsc-multi.tgz",
"tsconfig-paths": "^4.0.0",
"typescript": "5.8.3"
"typescript": "5.8.3",
"typescript-eslint": "8.31.1"
},
"imports": {
"isaacus": ".",
Expand Down
6 changes: 1 addition & 5 deletions packages/mcp-server/build
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,10 @@ PKG_JSON_PATH=../../packages/mcp-server/package.json node ../../scripts/utils/ma
node scripts/postprocess-dist-package-json.cjs

# build to .js/.mjs/.d.ts files
npm exec tsc-multi
./node_modules/.bin/tsc-multi

cp tsconfig.dist-src.json dist/src/tsconfig.json

# Add proper Node.js shebang to the top of the file
sed -i.bak '1s;^;#!/usr/bin/env node\n;' dist/index.js
rm dist/index.js.bak

chmod +x dist/index.js

DIST_PATH=./dist PKG_IMPORT_PATH=isaacus-mcp/ node ../../scripts/utils/postprocess-files.cjs
9 changes: 5 additions & 4 deletions packages/mcp-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "isaacus-mcp",
"version": "0.10.0",
"version": "0.11.0",
"description": "The official MCP Server for the Isaacus API",
"author": "Isaacus <support@isaacus.com>",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -28,10 +28,11 @@
},
"dependencies": {
"isaacus": "file:../../dist/",
"@modelcontextprotocol/sdk": "^1.6.1",
"@modelcontextprotocol/sdk": "^1.11.5",
"jq-web": "https://github.com/stainless-api/jq-web/releases/download/v0.8.2/jq-web.tar.gz",
"yargs": "^17.7.2",
"@cloudflare/cabidela": "^0.2.4",
"zod": "^3.24.4",
"zod": "^3.25.20",
"zod-to-json-schema": "^3.24.5"
},
"bin": {
Expand All @@ -49,7 +50,7 @@
"ts-jest": "^29.1.0",
"ts-morph": "^19.0.0",
"ts-node": "^10.5.0",
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz",
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.8/tsc-multi.tgz",
"tsconfig-paths": "^4.0.0",
"typescript": "5.8.3"
},
Expand Down
40 changes: 40 additions & 0 deletions packages/mcp-server/src/compat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,46 @@ export const defaultClientCapabilities: ClientCapabilities = {
toolNameLength: undefined,
};

export type ClientType = 'openai-agents' | 'claude' | 'claude-code' | 'cursor';

// Client presets for compatibility
// Note that these could change over time as models get better, so this is
// a best effort.
export const knownClients: Record<ClientType, ClientCapabilities> = {
'openai-agents': {
topLevelUnions: false,
validJson: true,
refs: true,
unions: true,
formats: true,
toolNameLength: undefined,
},
claude: {
topLevelUnions: true,
validJson: false,
refs: true,
unions: true,
formats: true,
toolNameLength: undefined,
},
'claude-code': {
topLevelUnions: false,
validJson: true,
refs: true,
unions: true,
formats: true,
toolNameLength: undefined,
},
cursor: {
topLevelUnions: false,
validJson: true,
refs: false,
unions: false,
formats: false,
toolNameLength: 50,
},
};

/**
* Attempts to parse strings into JSON objects
*/
Expand Down
Loading