Skip to content
Open
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
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Naftiko Framework

Welcome to Naftiko Framework, the 1st Open Source project for **Spec-Driven AI Integration**. It reinvents API integration for the AI era with governed and versatile capabilities that streamline API sprawl from massive SaaS and microservices growth.

Each capability is a coarse piece of domain that consumes existing HTTP-based APIs, converts data formats like Protocol Buffer, XML, YAML, CSV and Avro into JSON, enabling better Context Engineering and API reusability critical to AI integration.

<img src="https://naftiko.github.io/docs/images/technology/architecture_capability.png" width="600">

Capabilities are declared using **YAML** files, configuring the Naftiko Engine provided as a **Docker** container. Clients can then consume the capability via the **MCP** or **API** servers exposed.

While the framework itself is developed in Java and can be extended to support new protocols, developers just need to know YAML, JSONPath and Mustache templates to take full advantage of it.

- :rowboat: [Installation](https://github.com/naftiko/framework/wiki/Installation)
- :sailboat: [Tutorial](https://github.com/naftiko/framework/wiki/Tutorial)
- :ship: [Use cases](https://github.com/naftiko/framework/wiki/Use-Cases)
- :anchor: [Specification](https://github.com/naftiko/framework/wiki/Specification)
- :mega: [Releases](https://github.com/naftiko/framework/wiki/Releases)
- :telescope: [Roadmap](https://github.com/naftiko/framework/wiki/Roadmap)
- :nut_and_bolt: [Contribute](https://github.com/naftiko/framework/wiki/Contribute)
- :ocean: [FAQ](https://github.com/naftiko/framework/wiki/FAQ)

Please join the community of users and contributors in [this GitHub Discussion forum!](https://github.com/orgs/naftiko/discussions).

<img src="https://naftiko.github.io/docs/images/navi/navi_hello.svg" width="50">

Welcome to Naftiko Framework, the first Open Source project for **Spec-Driven AI Integration**. It reinvents API integration for the AI era with a governed and versatile platform based on capabilities that streamlines API sprawl created by the massive SaaS growth and microservices.

Each capability is a coarse piece of domain that consumes existing HTTP-based APIs, converts into JSON data formats like Protocol Buffer, XML, YAML, CSV and Avro, enabling better Context Engineering and API reusability critical to AI integration.
Expand All @@ -19,6 +42,7 @@ While the framework itself is developed in Java and can be extended to support n
- :nut_and_bolt: [Contribute](https://github.com/naftiko/framework/wiki/Contribute)
- :ocean: [FAQ](https://github.com/naftiko/framework/wiki/FAQ)


Please join the community of users and contributors in [this GitHub Discussion forum!](https://github.com/orgs/naftiko/discussions).

<img src="https://naftiko.github.io/docs/images/navi/navi_hello.svg" width="50">
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,42 @@ capability:
namespace: "weather-api"
baseUri: "https://api.weather.com/v1/"
resources:
- path: "forecast/{{location}}"
- name: "forecast"
path: "forecast/{{location}}"
inputParameters:
- name: "location"
in: "path"
operations:
- method: "GET"
name: "get-forecast"
outputParameters:
- name: "forecast"
type: "object"
value: "$.forecast"

- type: "http"
namespace: "geocoding-api"
baseUri: "https://geocode.example.com/"
resources:
- path: "resolve/{{query}}"
- name: "resolve"
path: "resolve/{{query}}"
inputParameters:
- name: "query"
in: "path"
operations:
- method: "GET"
name: "resolve-location"
outputParameters:
- name: "coordinates"
type: "object"
value: "$.coordinates"
properties:
lat:
type: "number"
value: "$.lat"
lon:
type: "number"
value: "$.lon"

exposes:
# API adapter — owns tool execution via REST
Expand All @@ -139,9 +162,18 @@ capability:
operations:
- method: "GET"
name: "get-forecast"
inputParameters:
- name: "city"
in: "path"
type: "string"
description: "City name (e.g. 'London', 'New York')"
call: "weather-api.get-forecast"
with:
location: "{{city}}"
outputParameters:
- name: "forecast"
type: "object"
mapping: "$.forecast"

# MCP adapter — owns tool execution via MCP protocol
- type: "mcp"
Expand All @@ -152,6 +184,10 @@ capability:
tools:
- name: "resolve-and-forecast"
description: "Resolve a place name to coordinates, then fetch forecast"
inputParameters:
- name: "place"
type: "string"
description: "Place name to resolve"
steps:
- type: "call"
name: "geo"
Expand All @@ -163,10 +199,16 @@ capability:
call: "weather-api.get-forecast"
with:
location: "{{geo.coordinates.lat}},{{geo.coordinates.lon}}"
inputParameters:
- name: "place"
type: "string"
description: "Place name to resolve"
mappings:
- targetName: "location"
value: "$.geo.coordinates"
- targetName: "forecast"
value: "$.weather.forecast"
outputParameters:
- name: "location"
type: "object"
- name: "forecast"
type: "object"

# Skill adapter — metadata/catalog layer (no execution)
- type: "skill"
Expand All @@ -189,16 +231,16 @@ capability:
- name: "get-forecast"
description: "Get weather forecast for a city"
from:
namespace: "weather-rest" # Sibling API adapter
action: "get-forecast" # Operation name
sourceNamespace: "weather-rest" # Sibling API adapter
action: "get-forecast" # Operation name
- name: "resolve-and-forecast"
description: "Resolve a place name to coordinates, then fetch forecast"
from:
namespace: "weather-mcp" # Sibling MCP adapter
action: "resolve-and-forecast" # Tool name
sourceNamespace: "weather-mcp" # Sibling MCP adapter
action: "resolve-and-forecast" # Tool name
- name: "interpret-weather"
description: "Guide for reading and interpreting weather data"
instruction: "interpret-weather.md" # Local file in location dir
instruction: "interpret-weather.md" # Local file in location dir
```

**How agents use this:**
Expand Down Expand Up @@ -259,18 +301,18 @@ skills:
- name: "list-orders"
description: "List all customer orders"
from:
namespace: "public-api"
sourceNamespace: "public-api"
action: "list-orders"
- name: "create-order"
description: "Create a new customer order"
from:
namespace: "public-api"
sourceNamespace: "public-api"
action: "create-order"
# Derived from sibling MCP adapter
- name: "summarize-order"
description: "Generate an AI summary of an order"
from:
namespace: "assistant-mcp"
sourceNamespace: "assistant-mcp"
action: "summarize-order"
# Local file instruction
- name: "order-policies"
Expand All @@ -283,7 +325,7 @@ skills:
A tool with `from` references a specific operation or tool in a sibling adapter:

**Tool declaration rules:**
1. `from.namespace` must resolve to a sibling `exposes[]` entry of type `api` or `mcp`
1. `from.sourceNamespace` must resolve to a sibling `exposes[]` entry of type `api` or `mcp`
2. `from.action` must match an operation name (api) or tool name (mcp) in the resolved adapter
3. Adapter type is inferred from the resolved target
4. Each derived tool includes an `invocationRef` in the response so agents can invoke the source adapter directly
Expand Down Expand Up @@ -356,12 +398,12 @@ skills:
- name: "run-analysis"
description: "Run a full data analysis"
from:
namespace: "analytics-rest"
sourceNamespace: "analytics-rest"
action: "run-analysis"
- name: "quick-stats"
description: "Run quick statistical analysis"
from:
namespace: "analytics-mcp"
sourceNamespace: "analytics-mcp"
action: "quick-stats"
- name: "interpret-data"
description: "Guide for interpreting analysis results"
Expand Down Expand Up @@ -414,7 +456,7 @@ skills:
- name: "get-forecast"
description: "Get weather forecast"
from:
namespace: "weather-rest"
sourceNamespace: "weather-rest"
action: "get-forecast"
- name: "interpret-weather"
description: "Guide for interpreting weather data"
Expand Down Expand Up @@ -494,10 +536,7 @@ The SKILL.md file at the location can contain the same frontmatter properties as
"description": "A skill definition. Declares tools derived from sibling api or mcp adapters or defined as local file instructions. Can also stand alone as purely descriptive (no tools). Supports full Agent Skills Spec frontmatter metadata. Skills describe tools — they do not execute them.",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$",
"minLength": 1,
"maxLength": 64,
"$ref": "#/$defs/IdentifierKebab",
"description": "Skill identifier (kebab-case)"
},
"description": {
Expand All @@ -521,6 +560,7 @@ The SKILL.md file at the location can contain the same frontmatter properties as
},
"allowed-tools": {
"type": "string",
"maxLength": 1024,
"description": "Space-delimited list of pre-approved tool names (Agent Skills Spec)"
},
"argument-hint": {
Expand Down Expand Up @@ -563,10 +603,7 @@ The SKILL.md file at the location can contain the same frontmatter properties as
"description": "A tool declared within a skill. Derived from a sibling api or mcp adapter via 'from', or defined as a local file instruction.",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$",
"minLength": 1,
"maxLength": 64,
"$ref": "#/$defs/IdentifierKebab",
"description": "Tool identifier (kebab-case)"
},
"description": {
Expand All @@ -577,7 +614,7 @@ The SKILL.md file at the location can contain the same frontmatter properties as
"type": "object",
"description": "Derive this tool from a sibling api or mcp adapter.",
"properties": {
"namespace": {
"sourceNamespace": {
"type": "string",
"description": "Sibling exposes[].namespace (must be type api or mcp)"
},
Expand All @@ -586,7 +623,7 @@ The SKILL.md file at the location can contain the same frontmatter properties as
"description": "Operation name (api) or tool name (mcp) in the source adapter"
}
},
"required": ["namespace", "action"],
"required": ["sourceNamespace", "action"],
"additionalProperties": false
},
"instruction": {
Expand Down Expand Up @@ -950,6 +987,9 @@ capability:
resources:
- path: "forecast/{{location}}"
name: "forecast"
inputParameters:
- name: "location"
in: "path"
operations:
- method: "GET"
name: "get-forecast"
Expand All @@ -964,13 +1004,23 @@ capability:
resources:
- path: "search/{{query}}"
name: "search"
inputParameters:
- name: "query"
in: "path"
operations:
- method: "GET"
name: "resolve-location"
outputParameters:
- name: "coordinates"
type: "object"
value: "$.result"
value: "$.coordinates"
properties:
lat:
type: "number"
value: "$.lat"
lon:
type: "number"
value: "$.lon"

exposes:
# API adapter — executes the forecast tool via REST
Expand All @@ -983,14 +1033,18 @@ capability:
operations:
- method: "GET"
name: "get-forecast"
call: "weather-api.get-forecast"
with:
location: "{{city}}"
inputParameters:
- name: "city"
in: "path"
type: "string"
description: "City name (e.g. 'London', 'New York')"
call: "weather-api.get-forecast"
with:
location: "{{city}}"
outputParameters:
- name: "forecast"
type: "object"
mapping: "$.forecast"

# MCP adapter — executes multi-step tools via MCP protocol
- type: "mcp"
Expand Down Expand Up @@ -1049,12 +1103,12 @@ capability:
- name: "get-forecast"
description: "Get weather forecast for a city"
from:
namespace: "weather-rest"
sourceNamespace: "weather-rest"
action: "get-forecast"
- name: "resolve-and-forecast"
description: "Resolve a place name to coordinates, then fetch forecast"
from:
namespace: "weather-mcp"
sourceNamespace: "weather-mcp"
action: "resolve-and-forecast"
- name: "interpret-weather"
description: "Guide for reading and interpreting weather data"
Expand Down Expand Up @@ -1243,17 +1297,17 @@ capability:
- name: "list-orders"
description: "List all customer orders"
from:
namespace: "public-api"
sourceNamespace: "public-api"
action: "list-orders"
- name: "get-order"
description: "Get details of a specific order"
from:
namespace: "public-api"
sourceNamespace: "public-api"
action: "get-order"
- name: "create-order"
description: "Create a new customer order"
from:
namespace: "public-api"
sourceNamespace: "public-api"
action: "create-order"

- name: "order-admin"
Expand All @@ -1263,7 +1317,7 @@ capability:
- name: "cancel-order"
description: "Cancel an existing order"
from:
namespace: "public-api"
sourceNamespace: "public-api"
action: "cancel-order"
```

Expand Down Expand Up @@ -1380,12 +1434,12 @@ capability:
- name: "run-analysis"
description: "Run a full data analysis via REST"
from:
namespace: "analytics-rest"
sourceNamespace: "analytics-rest"
action: "run-analysis"
- name: "quick-stats"
description: "Run quick statistical analysis via MCP"
from:
namespace: "analytics-mcp"
sourceNamespace: "analytics-mcp"
action: "quick-stats"
- name: "analysis-methodology"
description: "Guide for choosing the right analysis approach"
Expand Down Expand Up @@ -1537,8 +1591,8 @@ spec:

1. `tools` is optional — a skill can be purely descriptive (metadata + `location` only, no tools)
2. Each tool must specify exactly one source: `from` (derived) or `instruction` (local file)
3. For derived tools (`from`), `namespace` must resolve to exactly one sibling `exposes[].namespace` of type `api` or `mcp`
4. Referencing a `skill`-type adapter from `from.namespace` is invalid (no recursive derivation)
3. For derived tools (`from`), `sourceNamespace` must resolve to exactly one sibling `exposes[].namespace` of type `api` or `mcp`
4. Referencing a `skill`-type adapter from `from.sourceNamespace` is invalid (no recursive derivation)
5. For derived tools, `action` must exist as an operation name (api) or tool name (mcp) in the resolved adapter
6. For instruction tools, the skill must have a `location` configured — the instruction path is resolved relative to it
7. Tool `name` values must be unique within a skill
Expand Down
File renamed without changes.
Loading