A modular toolkit for creating and managing API connections with a Next.js-based server interface. This project provides a framework for building extensible API connectors that can interact with various services like Google Calendar, Gmail, Drive, Tasks, and Contacts.
The project is organized into four main modules:
- server/ - Next.js web application with UI for managing connections
- connections/ - Connector implementations (e.g., Google services)
- types/ - Shared TypeScript type definitions
- prisma/ - Database schema and client for storing connection configurations
- Extensible connector architecture for integrating with any API
- Built-in Google connector with support for:
- Gmail (send, search, list, read emails)
- Google Calendar (create, edit, view, delete events)
- Google Drive (create, update, move, delete, list files)
- Google Tasks (create, update, delete, list tasks)
- Google Contacts (create, update, delete contacts)
- SQLite database for storing connection configurations
- Next.js-based UI with React components
- TypeScript support throughout
- Node.js 22 or higher
- Yarn package manager
- Nix (optional, for development environment)
If you have Nix with flakes enabled:
# Enter the development environment
nix develop
# The shell will automatically set up DATABASE_PATH-
Clone the repository
git clone https://github.com/danhab99/open-api-toolkit.git cd open-api-toolkit -
Set up environment variables
# Create a database path for Prisma export DATABASE_PATH="file:$(pwd)/db"
-
Install dependencies
# Install dependencies for all modules cd types && yarn install && cd .. cd prisma && yarn install && cd .. cd connections/google && yarn install && cd ../.. cd server && yarn install && cd ..
-
Initialize the database
cd prisma yarn build cd ..
This will:
- Generate the Prisma client
- Create the SQLite database
- Apply the schema migrations
cd server
yarn devThe server will start on http://localhost:3000 with hot-reloading enabled.
cd server
yarn build
yarn startIn the server/ directory:
yarn dev- Start development server with Turbopackyarn build- Create production buildyarn start- Start production serveryarn lint- Run ESLintyarn storybook- Start Storybook on port 6006yarn build-storybook- Build Storybook
The project uses a modular connector architecture. Here's how to create a new connector based on the existing Google connector:
mkdir -p connections/your-service/src
cd connections/your-serviceCreate package.json:
{
"name": "@open-api-connection/your-service",
"version": "1.0.0",
"main": "src/index.ts",
"license": "MIT",
"dependencies": {
"open-api-connection-types": "link:../../types",
"open-api-prisma": "link:../../prisma",
"typescript": "^5.8.3"
}
}Create tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}Create src/index.ts:
import { OpenAPIConnectionDefinition, Tool } from "open-api-connection-types";
// Define your connection with configuration parameters
export const Connection: OpenAPIConnectionDefinition = {
id: "your-service",
displayName: "Your Service",
userDescription: "Connects to Your Service API",
aiDescription: "Allows tools to interact with Your Service on behalf of the user",
configurationArguments: [
{
id: "apiKey",
displayName: "API Key",
userDescription: "Your Service API key",
aiDescription: "Authentication key for Your Service API",
type: "string",
},
{
id: "apiUrl",
displayName: "API URL",
userDescription: "Base URL for Your Service API",
aiDescription: "Base endpoint URL for API requests",
type: "string",
},
],
};
// Export array of tools
export const Tools: Tool[] = [
// Your tools will go here
];Create src/lib.ts for shared utility functions:
import { KVP } from "open-api-connection-types";
export function getClient(config: KVP) {
const { apiKey, apiUrl } = config;
// Initialize and return your API client
// Example:
// return new YourServiceClient({
// apiKey,
// baseUrl: apiUrl,
// });
}Create tool files in subdirectories (e.g., src/resources/create_item.ts):
import { Tool } from "open-api-connection-types";
import { getClient } from "../lib";
export const createItem: Tool = {
id: "createItem",
displayName: "Create Item",
userDescription: "Creates a new item in Your Service",
aiDescription: "Creates an item with specified properties",
arguments: [
{
id: "name",
displayName: "Name",
type: "string",
userDescription: "Name of the item to create",
aiDescription: "Item name",
},
{
id: "description",
displayName: "Description",
type: "string",
userDescription: "Description of the item",
aiDescription: "Item description",
},
],
async handler(config, args) {
const client = getClient(config);
const { name, description } = args;
try {
const result = await client.createItem({
name,
description,
});
return {
results: {
id: result.id,
success: true,
},
log: {
message: `Item created successfully: ${name}`,
data: result,
},
};
} catch (error) {
return {
results: {
success: false,
},
log: {
message: "Failed to create item",
data: error,
},
};
}
},
};Update src/index.ts to export your tools:
import { createItem } from "./resources/create_item";
import { listItems } from "./resources/list_items";
// ... import other tools
export const Tools: Tool[] = [
createItem,
listItems,
// ... add other tools
];Add your connector to the server's package.json:
{
"dependencies": {
"@open-api-connection/your-service": "file:../connections/your-service"
}
}Then install:
cd server
yarn installImport and use your connector in the server application where connections are managed.
open-api-toolkit/
βββ connections/ # Connector implementations
β βββ google/ # Google services connector
β βββ src/
β β βββ calendar/ # Calendar tools
β β βββ contacts/ # Contacts tools
β β βββ drive/ # Drive tools
β β βββ gmail/ # Gmail tools
β β βββ tasks/ # Tasks tools
β β βββ index.ts # Connection definition
β β βββ lib.ts # Shared utilities
β βββ package.json
βββ types/ # Shared TypeScript types
β βββ src/
β βββ types.ts # Core type definitions
β βββ index.ts
βββ prisma/ # Database schema and client
β βββ prisma/
β β βββ schema.prisma # Database schema
β βββ src/
β βββ index.ts
βββ server/ # Next.js web application
β βββ src/
β β βββ app/ # Next.js app router pages
β β βββ components/ # React components
β β βββ lib/ # Utilities and helpers
β βββ package.json
βββ flake.nix # Nix development environment
βββ README.md # This file
The project uses SQLite for storing connection configurations. The database path is controlled by the DATABASE_PATH environment variable.
Schema:
- Connection - Stores API connection configurations (credentials, settings)
- AuditLog - Logs of connection activities and tool executions
DATABASE_PATH- Path to SQLite database file (e.g.,file:./db)
The project uses a strongly-typed system for defining connections and tools:
- OpenAPIConnectionDefinition - Defines a connector with configuration parameters
- Tool - Defines an API operation with arguments and handler
- ConfigDef - Configuration parameter definition
- ToolResult - Standardized return type for tool handlers
- Create a new file in the appropriate subdirectory (e.g.,
connections/google/src/calendar/) - Define the tool following the
Tooltype - Implement the
handlerfunction - Export the tool from
connections/google/src/index.ts
Example:
export const myNewTool: Tool = {
id: "myNewTool",
displayName: "My New Tool",
userDescription: "Description for users",
aiDescription: "Description for AI",
arguments: [/* ... */],
async handler(config, args) {
// Implementation
},
};model Connection {
id Int @id @default(autoincrement())
connectionID String
config String // JSON-encoded configuration
enable Boolean
userDescription String
aiDescription String
displayName String
auditLog AuditLog[]
}
model AuditLog {
id Int @id @default(autoincrement())
connection Connection @relation(fields: [connectionID], references: [id])
connectionID Int
timestamp DateTime @default(now())
message String
data String // JSON-encoded data
}- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT
- Built with Next.js
- UI components from Radix UI
- Database with Prisma
- Google APIs integration via googleapis