# Forgium Agent public integration documentation — full source pack Manifest version: 12 Contract version: 2.0.0 --- BEGIN docs/integration/use-with-an-agent.md --- # Use Forgium Agent with an agent This is the single public entrypoint for a coding agent integrating a host application with Forgium Agent. The public documentation is the canonical contract. The optional Skill is not currently distributed as an installable package; use this protocol unless your runtime already supports a verified local `SKILL.md`. ## Machine-readable discovery An agent can discover the complete public contract without guessing URLs: - [Agent manifest](/agent-manifest.json) — canonical resources, versions, routes, required environment variables, and stop conditions. - [Agent index](/agent-index.json) — generated resource index and hashes. - [LLM index](/llms.txt) — concise reading order and route summary. - [Raw OpenAPI contract](api.openapi.yaml) — exact public request and response schemas. - [Contract retrieval](contract-retrieval.md) — direct download, validation, and blocker reporting when an agent cannot locate the contract. - [HTTP integration reference](reference-implementation.md) — server-side adapter pattern and production checklist. The same resources are available from the public site at: ```text https://docs.forgium.dev/agent-manifest.json https://docs.forgium.dev/agent-index.json https://docs.forgium.dev/llms.txt https://docs.forgium.dev/docs/integration/api.openapi.yaml ``` Use only links published by the manifest or this page. Do not guess or enumerate undocumented `openapi.json`, `swagger.json`, or API paths. ## Decision protocol 1. Read the [agent manifest](/agent-manifest.json), this page, the [Overview](overview.md), and [Environments](environments.md). 2. Determine the goal: - **Connectivity test only:** do not inspect or modify an unrelated repository; use [Getting started](getting-started.md) to send the first HTTP message. - **Code integration:** identify the host application's repository and where the integration belongs. Before running repository commands, confirm the working directory with `pwd` and change to the host repository explicitly. Do not assume a data source, tunnel, framework, or deployment model. 3. For a code integration, choose the smallest applicable route: - **HTTP:** the host application needs a synchronous agent response. - **Capabilities:** the agent needs approved live data or actions from the host application. Capabilities may coexist with HTTP, but are not required for a basic message integration. 4. When a real API call is needed, confirm the target environment's `FORGIUM_AGENT_BASE_URL` and `FORGIUM_AGENT_API_KEY`. If either is missing, [request access](request-access.md); continue only with local work or mocks, and do not claim an end-to-end result. 5. Read the [OpenAPI contract](api.openapi.yaml) and, if discovery fails, follow [Contract retrieval](contract-retrieval.md) before writing calls. For an HTTP code integration, use the [HTTP integration reference](reference-implementation.md) as a pattern only; implement only what the repository needs. 6. Run the applicable local or authenticated smoke test. For a code integration, also run the host repository's tests. For capabilities, follow the complete lifecycle in [Self-service business capabilities](capability-handoff.md). 7. Report what changed, the evidence that passed, and every concrete blocker with its next action. Do not collapse multiple blockers into an artificial single blocker. ## Stop conditions Stop the integration and report the blocker instead of guessing or probing when: - the canonical OpenAPI contract or selected route guide cannot be reached through the published links; use [Contract retrieval](contract-retrieval.md) once, then report the exact HTTP status and content type instead of probing; - `FORGIUM_AGENT_BASE_URL` or `FORGIUM_AGENT_API_KEY` is missing for a real API call; - the access bundle does not identify the requested environment; - the endpoint URL, credential, or capability manifest is a placeholder, unauthenticated, or belongs to another environment; or - a contract test, activation, or final chat verification fails. A missing Git repository is not by itself an integration failure. Only run Git commands when the host repository uses Git or when version-control evidence was specifically requested. ## Route reference | Goal | Read first | Completion evidence | |---|---|---| | Connectivity | [HTTP quickstart](getting-started.md) | First HTTP message returns an assistant response | | HTTP code integration | [Overview](overview.md), [HTTP reference](reference-implementation.md), and [OpenAPI](api.openapi.yaml) | Host tests plus authenticated smoke test | | Host data or actions | [Capabilities lifecycle](capability-handoff.md) | Import, contract test, activation, and chat verification | ## Copy this prompt ```text You are integrating my application with Forgium Agent. Use only the official public integration documentation at https://docs.forgium.dev/docs. Start with these canonical resources; do not guess or enumerate undocumented URLs: 1. https://docs.forgium.dev/agent-manifest.json 2. https://docs.forgium.dev/docs/integration/use-with-an-agent 3. https://docs.forgium.dev/docs/integration/overview 4. https://docs.forgium.dev/docs/integration/environments 5. https://docs.forgium.dev/docs/integration/api.openapi.yaml Use the manifest's published links for the selected route: - HTTP quickstart: https://docs.forgium.dev/docs/integration/getting-started - Capabilities lifecycle: https://docs.forgium.dev/docs/integration/capability-handoff - Request access: https://docs.forgium.dev/docs/integration/request-access - Contract retrieval: https://docs.forgium.dev/docs/integration/contract-retrieval - HTTP integration reference: https://docs.forgium.dev/docs/integration/reference-implementation If you are only testing connectivity, do not inspect or modify an unrelated repository: use the access bundle and the HTTP quickstart to send one message. Do not run repository or git discovery commands for a connectivity-only test. If you are implementing code, first confirm the working directory with `pwd` and explicitly inspect the host application's repository. Choose the minimum integration it actually needs: - HTTP when it needs a synchronous agent response; or - capabilities when the agent needs approved live data or actions from the host. Capabilities are optional and may coexist with HTTP. When a real API call or deployment is required, confirm these values for the selected environment before using them: - FORGIUM_AGENT_BASE_URL - FORGIUM_AGENT_API_KEY If either is missing, ask the Forgium administrator for the environment-specific access bundle and continue only with local implementation or mocks. Read the canonical OpenAPI contract before generating requests. If the agent cannot locate it through the published links, follow the Contract retrieval commands once and report the exact result. Do not substitute another contract. Implement only the applicable route, run tests, and record evidence. For capabilities, use the public lifecycle: protect and expose the host endpoint, provision its scoped credential through the Public API vault, create a secret-free manifest, import, contract-test, activate, and verify through chat. Repeat separately per environment. Never use a placeholder URL or an unauthenticated endpoint. If a published page or the canonical contract is unavailable, stop and report that blocker. Do not probe guessed OpenAPI, Swagger, API, or internal URLs. Report every blocker separately with its next action. Report changes, verification evidence, and every actionable blocker. Do not claim a capability is active unless activation and final chat verification pass. Never request Admin API access or internal secrets. ``` ## Expected result A successful run leaves a tested first HTTP message and a documented choice of HTTP or capabilities. Capability work is complete only after the target revision is active and a chat response is verified against the approved host endpoint. Continue with: - [Overview](overview.md) - [Getting started](getting-started.md) for the manual HTTP quickstart - [Environments](environments.md) - [Request access](request-access.md) - [Contract retrieval](contract-retrieval.md) - [HTTP integration reference](reference-implementation.md) - [Self-service business capabilities](capability-handoff.md) - [Public API contract](api.openapi.yaml) --- END docs/integration/use-with-an-agent.md --- --- BEGIN docs/integration/overview.md --- # Forgium Agent — Public API overview Forgium Agent is a conversational-agent service. Start with [Use Forgium Agent with an agent](use-with-an-agent.md) when a coding agent is doing the integration. Your application can send a user message to the Public API and receive an agent response. For automated discovery, use the [agent manifest](/agent-manifest.json). It publishes the canonical guides, raw OpenAPI contract, environment variables, and stop conditions. The manifest is the source for the generated [agent index](/agent-index.json) and [LLM index](/llms.txt). ## What you can build Choose the path that matches the host application: | Need | Use | |---|---| | A web, mobile, or backend application needs a synchronous agent reply | `POST /v1/channels/http/messages` | | The agent needs approved live data or actions from the host application | Self-service business capabilities | The HTTP channel currently accepts text messages. ## Access boundary Before integrating, ask the Forgium administrator for this access bundle for the target environment: ```bash FORGIUM_AGENT_BASE_URL=https:// FORGIUM_AGENT_API_KEY=mg_xxx ``` Use the key only with the Public API (`/v1/*`). If it is missing or rejected, ask the administrator for help. ## Recommended reading order For an agent: 1. [Use Forgium Agent with an agent](use-with-an-agent.md) — decision protocol. 2. [Environments](environments.md) — keep environments isolated. 3. [Request access](request-access.md) — obtain and validate the bundle when needed. 4. [Contract retrieval](contract-retrieval.md) — download and validate the raw contract if an agent cannot discover it through navigation. 5. [Authentication](auth.md) — API-key rules. 6. Read [Getting started](getting-started.md) for the HTTP quickstart, or [Self-service business capabilities](capability-handoff.md) when the host application must provide live data or actions. 7. Use the [OpenAPI contract](api.openapi.yaml) for exact request and response fields. For a server-side HTTP adapter, see [HTTP integration reference](reference-implementation.md). For a manual integration, start at [Getting started](getting-started.md). --- END docs/integration/overview.md --- --- BEGIN docs/integration/environments.md --- # Environments Keep Forgium Agent access, host-application endpoints, and credentials isolated by environment. A capability registered in one environment is not a deployment mechanism for another. ## Access bundles Request a separate bundle from the platform operator for every environment you will use: ```bash # Example only; use values issued by the Forgium administrator. FORGIUM_AGENT_BASE_URL=https:// FORGIUM_AGENT_API_KEY=mg_ ``` Never point a production host application at a development or staging API key. Never reuse a capability endpoint token across environments unless its owning application explicitly authorizes that use. | Environment | Intended use | Capability endpoint | |---|---|---| | Development | Local implementation and contract preparation | Local endpoint for direct tests; an authorized HTTPS tunnel is required before a deployed Worker can call it. | | Staging | End-to-end verification before release | Staging HTTPS endpoint, staging credential reference, and staging Forgium Agent access bundle. | | Production | Customer traffic | Production HTTPS endpoint, production credential reference, and production Forgium Agent access bundle. | ## Promotion workflow Repeat the capability lifecycle in each target environment; do not copy a staging capability ID or credential reference into production. 1. Deploy the host application's endpoint to the target environment and verify its scoped-token authentication directly. 2. Use the target environment's `FORGIUM_AGENT_*` bundle to store that endpoint token with `PUT /v1/capability-credentials/{credentialRef}`. 3. Import the target environment's manifest with its exact HTTPS URL. 4. Contract-test the imported capability, then activate it. 5. Send a real chat request to verify that the agent used the target endpoint. See [business capabilities](capability-handoff.md) for the manifest and API commands. ## Release safety Before production activation, verify all of the following: - the base URL and API key belong to production; - the manifest contains the production endpoint URL and no secrets; - the endpoint accepts only its production scoped token; - the contract test passed for the current capability revision; and - a chat smoke test returns a result grounded in the production endpoint. ## Rollback If a newly activated capability behaves incorrectly, disable it: ```bash curl -fsS -X POST "$FORGIUM_AGENT_BASE_URL/v1/capabilities/$CAPABILITY_ID/disable" \ -H "Authorization: Bearer $FORGIUM_AGENT_API_KEY" ``` Then correct the host endpoint or manifest, revise the capability, run its contract test, and reactivate it. If the API key or endpoint token may have leaked, notify the Forgium administrator and rotate the affected secret before resuming traffic. --- END docs/integration/environments.md --- --- BEGIN docs/integration/request-access.md --- # Request access The Public API access bundle is issued out of band by the Forgium administrator. The operator must configure the approved recipient and channel for each environment; this public contract does not assume a specific ticketing system, chat room, or email address. ## What to request Send the following template through the operator-approved channel: ```text Subject: Forgium Agent Public API access request Application: Owner: Environment: Purpose: Callback or host endpoint: Please provide the environment-specific access bundle through the approved secret-sharing channel. I need: - FORGIUM_AGENT_BASE_URL - FORGIUM_AGENT_API_KEY Do not include the API key in this ticket, repository, prompt, or log. ``` The operator may require additional application or deployment details before issuing access. Do not invent a URL, key, credential reference, or environment. ## Validate the bundle After receiving the values, keep them in the host application's secret manager and validate the environment without echoing the key: ```bash export FORGIUM_AGENT_BASE_URL="" export FORGIUM_AGENT_API_KEY="" curl -fsS "$FORGIUM_AGENT_BASE_URL/health" curl -fsS "$FORGIUM_AGENT_BASE_URL/v1/capabilities" \ -H "Authorization: Bearer $FORGIUM_AGENT_API_KEY" ``` The first response must identify the Forgium Agent API. The authenticated request must succeed for the intended environment. A `401` means the key is missing, invalid, expired, revoked, or paired with the wrong host; ask the administrator to reissue the matching bundle rather than trying another environment's key. For a capability, also verify that the endpoint URL and endpoint credential belong to the same environment before importing the manifest. See [Environments](environments.md) and [Self-service business capabilities](capability-handoff.md). ## Security boundary - Never commit an API key or host-endpoint token. - Never place secrets in `forgium-agent.capabilities.json`, prompts, screenshots, persisted agent context, or logs. - Request only the Public API bundle. Admin API tokens, platform secrets, and internal bindings are outside the integration contract. - If a secret may have been exposed, stop and ask the administrator to rotate it before continuing. --- END docs/integration/request-access.md --- --- BEGIN docs/integration/getting-started.md --- # Getting started This path uses the HTTP channel to verify that your application can send a text message and receive a synchronous agent response. ## 1. Receive the access bundle [Request the access bundle](request-access.md) from the Forgium administrator for the target environment. It contains: ```bash FORGIUM_AGENT_BASE_URL=https:// FORGIUM_AGENT_API_KEY=mg_xxx ``` Store the key in the host application's secret manager; do not commit it, include it in a capability manifest, or put it in logs. ## 2. Configure the integration If either value is unavailable, stop here and use [Request access](request-access.md). Do not substitute a guessed host, placeholder URL, or another environment's key. ```bash export FORGIUM_AGENT_BASE_URL="https://" export FORGIUM_AGENT_API_KEY="mg_xxx" ``` Confirm the public API is reachable: ```bash curl -fsS "$FORGIUM_AGENT_BASE_URL/health" ``` Expected response: ```json {"status":"ok","service":"agent-api"} ``` ## 3. Send the first message ```bash curl -fsS -X POST "$FORGIUM_AGENT_BASE_URL/v1/channels/http/messages" \ -H "Authorization: Bearer $FORGIUM_AGENT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "integration-smoke-test", "message": { "type": "text", "body": "Hello, can you help me?" }, "metadata": { "source": "integration-smoke-test" } }' ``` A successful response contains a `conversation_id` and an assistant `message`. This is the completion evidence for a connectivity-only test. Persist the `conversation_id` in the host application and send it in later requests to continue the same conversation. ```json { "conversation_id": "conv_xxx", "message": { "id": "msg_xxx", "role": "assistant", "type": "text", "body": "..." } } ``` ## 4. Select the next integration task - Register a [business capability](capability-handoff.md) when the agent needs data or an action from the host application. - Read [authentication](auth.md) before handling `401` responses or storing the key in deployment configuration. - Read [environments](environments.md) before promoting an integration beyond development. ## Troubleshooting | Response | Meaning | Next action | |---|---|---| | `401` | The API key is missing, invalid, expired, revoked, or unavailable for this environment. | Ask the Forgium administrator for a replacement. | | `422` | The request body is invalid. | Send a `message` with `type: "text"` and a non-empty `body`. | | `500` | The agent runtime could not complete the request. | Retry only if the host application's retry policy allows it; retain the response details and contact the operator if it persists. | The [OpenAPI contract](api.openapi.yaml) is authoritative for all request and response fields. If an agent cannot locate the contract, use the exact commands in [Contract retrieval](contract-retrieval.md); do not substitute another contract. For staging or production, validate the bundle and environment isolation described in [Environments](environments.md). For a server-side adapter pattern, error mapping, conversation handling, and production security checklist, see [HTTP integration reference](reference-implementation.md). --- END docs/integration/getting-started.md --- --- BEGIN docs/integration/reference-implementation.md --- # HTTP integration reference implementation This guide describes a minimal server-side adapter for an application that needs a synchronous Forgium Agent response. It is a development pattern, not a required framework or deployment model. ## Recommended boundary Keep the Forgium API key and upstream URL behind the host application's backend: ```text Client or UI │ │ POST /api/agent/messages ▼ Host application adapter │ validates input, authenticates the caller, │ applies timeout/rate limit, maps errors │ │ POST /v1/channels/http/messages ▼ Forgium Agent Public API ``` Do not call Forgium directly from a browser or mobile client when doing so would expose `FORGIUM_AGENT_API_KEY`. ## Example adapter contract The host application may expose a route such as `POST /api/agent/messages`. The exact route and framework belong to the host application. A small JSON contract is sufficient: ```json { "message": "Hello, can you help me?", "conversationId": "conv_optional" } ``` The adapter maps that request to the public HTTP channel contract: ```json { "user_id": "host-user-id", "conversation_id": "conv_optional", "message": { "type": "text", "body": "Hello, can you help me?" } } ``` The upstream response uses `conversation_id`; the host adapter may expose the same value as `conversationId` to match its own naming conventions. Preserve that identifier for subsequent messages in the same conversation. The public [OpenAPI contract](api.openapi.yaml) is authoritative for the upstream request and response shape. Do not generate a different upstream payload from this example. ## Configuration Read these values only on the server: ```bash FORGIUM_AGENT_BASE_URL= FORGIUM_AGENT_API_KEY= ``` Fail clearly when configuration is absent. A local adapter can return a configuration error without making an upstream request; this is useful for local smoke tests. Never include the key in a response, source file, client bundle, capability manifest, log, or persisted agent context. ## Error and resilience behavior The adapter should make failures actionable without leaking upstream secrets: | Situation | Recommended behavior | |---|---| | Missing configuration | Return a stable configuration error and HTTP `503`; do not call Forgium. | | Invalid caller input | Return a validation error and HTTP `4xx`; do not call Forgium. | | Forgium rejects authentication | Return a dependency/authentication error, redact the key, and request a matching environment bundle. | | Forgium times out or is unavailable | Apply the host retry policy, then return a dependency error with a correlation ID. | | Unexpected upstream response | Validate the response before returning it and log only safe diagnostics. | Choose status codes that match the host application's existing API conventions. Do not retry validation, authentication, or non-idempotent requests blindly. Follow the [idempotency guide](idempotency.md) when adding retries or replay protection. ## Production checklist Before exposing the adapter to customer traffic: - [ ] Authenticate the host application's caller. - [ ] Apply rate limiting and an appropriate request body limit. - [ ] Keep `FORGIUM_AGENT_API_KEY` server-side and store it in a secret manager. - [ ] Configure an explicit timeout and bounded retry policy. - [ ] Redact API keys and message contents from logs unless the product has an approved data-retention policy. - [ ] Validate both incoming input and the external response. - [ ] Preserve `conversation_id` only according to the host application's privacy and retention requirements. - [ ] Add tests for missing configuration, invalid input, upstream `401`, timeout, malformed response, and successful conversation continuation. - [ ] Run the authenticated smoke test against the intended environment. The host application's authentication and rate limiting are not supplied by Forgium. They remain required even when the Forgium API key is valid. ## Definition of done A minimal HTTP integration is ready for review when: 1. local tests pass with mocked upstream responses; 2. `/health` or the host equivalent reports dependency configuration without revealing secrets; 3. the adapter sends the exact payload described by the public contract; 4. the response is validated and the conversation identifier is preserved; and 5. an authenticated smoke test passes for the target environment, or the access bundle is documented as the remaining blocker. See [Getting started](getting-started.md) for the first authenticated message and [Contract retrieval](contract-retrieval.md) when an agent cannot locate the canonical OpenAPI file. --- END docs/integration/reference-implementation.md --- --- BEGIN docs/integration/contract-retrieval.md --- # Retrieve and validate the public contract Use this guide when a coding agent cannot find the OpenAPI or API reference through the documentation navigation. The contract is public and does not require an API key. ## Canonical resources Use the published machine-readable manifest first: ```text https://docs.forgium.dev/agent-manifest.json ``` The canonical raw OpenAPI file is: ```text https://docs.forgium.dev/docs/integration/api.openapi.yaml ``` The same link is published from the [agent entrypoint](use-with-an-agent.md), the [LLM index](/llms.txt), and the [agent index](/agent-index.json). Do not infer an API host from the OpenAPI document. The API host comes from the environment-specific `FORGIUM_AGENT_BASE_URL` access bundle. ## Direct retrieval A shell-based agent can retrieve the file without a search engine or URL enumeration: ```bash CONTRACT_URL="https://docs.forgium.dev/docs/integration/api.openapi.yaml" curl -fsSL \ -H 'Accept: application/yaml,text/plain' \ "$CONTRACT_URL" \ -o /tmp/forgium-agent.openapi.yaml ``` Confirm that the response is the raw contract rather than an HTML error page: ```bash test -s /tmp/forgium-agent.openapi.yaml grep -q '^openapi:' /tmp/forgium-agent.openapi.yaml head -20 /tmp/forgium-agent.openapi.yaml ``` When the local toolchain has Redocly available, validate the syntax and references: ```bash bunx @redocly/cli lint /tmp/forgium-agent.openapi.yaml ``` The expected contract version is published in `agent-manifest.json` and in the OpenAPI `info.version` field. Do not silently continue with a different version. ## If retrieval fails Stop and report the concrete failure when any of these conditions occurs: - the manifest or raw contract returns a non-success HTTP status; - the response is HTML, empty, or does not contain an `openapi:` declaration; - the downloaded contract fails validation; or - the contract version does not match the published manifest. Report the URL, HTTP status, content type, and the next action. Do not try undocumented `openapi.json`, `swagger.json`, API, or internal URLs. Do not substitute a contract found through an unrelated search result. Example blocker report: ```text Blocker: https://docs.forgium.dev/docs/integration/api.openapi.yaml returned HTTP 404 with Content-Type text/html. Next action: deploy the public documentation artifact containing the canonical OpenAPI file, then rerun the retrieval and lint commands. ``` Missing API credentials is a separate blocker from a missing documentation contract. Report both when both are present. ## Contract evidence for an integration Record these facts in the implementation handoff: - canonical contract URL; - HTTP status and content type; - OpenAPI version and `info.version`; - lint result or the reason lint could not run; and - whether the authenticated API smoke test was run. A local adapter may be implemented with mocks while credentials are pending, but it must be labelled locally verified rather than end-to-end verified. --- END docs/integration/contract-retrieval.md --- --- BEGIN docs/integration/capability-handoff.md --- # Self-service business capabilities Use this document when your application's chat needs live data or actions from your application. An integrator can register and activate capabilities through the Public API with its API key. ## Lifecycle ```txt Implement endpoint + scoped token → test endpoint → expose HTTPS URL → encrypt token in vault → import draft → contract test → activate → verify chat response ``` The API key determines which capabilities the request can manage. No account or organization identifier is required in the manifest or URL. ## Endpoint requirements Your endpoint must: - use an exact public `https://` URL on port `443` in the manifest; - accept and return `application/json`; - validate input and enforce its business rules; - return only fields approved for the chat; and - have a stable request and response contract. A local JSON-backed endpoint is valid for development, but `localhost` cannot be called by deployed Workers. Test it locally first, then use an authorized HTTPS tunnel for a development test or deploy it through the application's authorized deployment path. Do not use an example or placeholder URL. For person lookup, prefer one read-only endpoint: ```http POST https://api.example.com/v1/people/lookup Content-Type: application/json {"name":"Juan Pérez"} ``` ```json { "person_id": "person_123", "name": "Juan Pérez", "email": "juan@example.com" } ``` ## Create `/forgium-agent.capabilities.json` Use the real endpoint URL. Every endpoint must be protected with a scoped token. Register the token in the vault first; never put a token or private header in the manifest. ```json { "domain": "people", "capabilities": [ { "name": "lookup_person", "description": "Looks up a person's approved contact details by name or DNI.", "when_to_use": "Use when the user asks for a person's email, contact details, or data by DNI.", "method": "POST", "url": "https://your-reachable-host.example/v1/people/lookup", "auth": { "type": "bearer", "credential_ref": "cred_people_api" }, "safe_headers": { "accept": "application/json", "content-type": "application/json" }, "input_schema": { "type": "object", "additionalProperties": false, "properties": { "name": { "type": "string", "maxLength": 200 }, "dni": { "type": "string", "maxLength": 20 } }, "anyOf": [{ "required": ["name"] }, { "required": ["dni"] }] }, "output_schema": { "type": "object", "additionalProperties": false, "required": ["person_id", "name"], "properties": { "person_id": { "type": "string", "maxLength": 100 }, "name": { "type": "string", "maxLength": 200 }, "email": { "type": "string", "maxLength": 254 }, "phone": { "type": "string", "maxLength": 50 } } }, "business_rules": ["The backend is authoritative for person data."], "examples": [], "side_effect": "read", "requires_approval": false, "timeout_ms": 5000, "retry_count": 1 } ] } ``` Every model-visible string needs `maxLength`; arrays need `maxItems`; objects need `additionalProperties: false`. ## Register, test, and activate ```bash export CAPABILITY_ID="" # The API implementation creates PEOPLE_API_TOKEN and validates it on every lookup. # This request stores only AES-GCM ciphertext in the credential vault. curl -fsS -X PUT "$FORGIUM_AGENT_BASE_URL/v1/capability-credentials/cred_people_api" \ -H "Authorization: Bearer $FORGIUM_AGENT_API_KEY" \ -H "Content-Type: application/json" \ -d "$(printf '{\"auth_type\":\"bearer\",\"secret\":%s}' "$(jq -Rn --arg value "$PEOPLE_API_TOKEN" '$value')")" IMPORT_RESPONSE="$(curl -fsS -X POST "$FORGIUM_AGENT_BASE_URL/v1/capabilities/import" \ -H "Authorization: Bearer $FORGIUM_AGENT_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: capability-import-$(date +%s)" \ --data-binary @forgium-agent.capabilities.json)" # Read the returned capabilities[0].id into CAPABILITY_ID with your JSON tool. curl -fsS -X POST "$FORGIUM_AGENT_BASE_URL/v1/capabilities/$CAPABILITY_ID/test" \ -H "Authorization: Bearer $FORGIUM_AGENT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"arguments":{"name":"Juan Pérez"}}' curl -fsS -X POST "$FORGIUM_AGENT_BASE_URL/v1/capabilities/$CAPABILITY_ID/activate" \ -H "Authorization: Bearer $FORGIUM_AGENT_API_KEY" ``` Useful routes: | Operation | Route | |---|---| | List own capabilities | `GET /v1/capabilities` | | Import draft | `POST /v1/capabilities/import` | | Get or revise one | `GET` / `PATCH /v1/capabilities/{capabilityId}` | | Contract test | `POST /v1/capabilities/{capabilityId}/test` | | Activate or disable | `POST /v1/capabilities/{capabilityId}/activate` or `/disable` | ## Credentials Provision the endpoint token through `PUT /v1/capability-credentials/{credentialRef}` before importing its manifest. The secret is AES-GCM ciphertext at rest; it is never returned by the API. | `auth.type` | Required request fields | |---|---| | `bearer` | `auth_type: "bearer"`, `secret` | | `api_key` | `auth_type: "api_key"`, `header_name: "x-api-key"` or `"x-api-token"`, `secret` | | `basic` | `auth_type: "basic"`, `secret` containing the pre-encoded Basic value | `auth.type: "none"` is rejected for self-service imports. Do not leave a business endpoint open just to make a capability work. ## Definition of done - [ ] Endpoint and local JSON data source implemented and directly tested. - [ ] Endpoint exposed at an exact reachable HTTPS URL on port 443. - [ ] Endpoint enforces its scoped token on every request. - [ ] Token is provisioned through the credential vault and never appears in source, manifest, logs, or output. - [ ] Manifest contains the real URL, `credential_ref`, bounded schemas, and no secrets. - [ ] Import returns a draft capability. - [ ] Contract test passes for the imported revision. - [ ] Activation returns `lifecycle_status: "active"`. - [ ] The chat query produces a response grounded in the endpoint result. --- END docs/integration/capability-handoff.md --- --- BEGIN docs/integration/auth.md --- # Authentication — API key The Forgium administrator provides an API key for each environment. Use it with the Public API (`/v1/*`): ```http Authorization: Bearer ``` ## Obtain access Request these values from the Forgium administrator: ```bash FORGIUM_AGENT_BASE_URL= FORGIUM_AGENT_API_KEY= ``` Store the key in the host application's secret manager. Do not commit it, include it in a capability manifest, or put it in logs. If a request returns `401`, ask the administrator to verify or replace the key. ## Example ```bash curl -fsS "$FORGIUM_AGENT_BASE_URL/v1/capabilities" \ -H "Authorization: Bearer $FORGIUM_AGENT_API_KEY" ``` --- END docs/integration/auth.md --- --- BEGIN docs/integration/errors.md --- # API errors The Public API uses JSON errors. The OpenAPI contract is authoritative for the status and shape of each route. Most Public API routes return: ```json { "error": "Invalid API key", "code": "UNAUTHORIZED" } ``` The HTTP channel returns a structured error object: ```json { "error": { "code": "VALIDATION_ERROR", "message": "Invalid JSON body" } } ``` ## Recovery guide | Status | Typical codes | Recovery | |---|---|---| | `400` | `VALIDATION_ERROR`, `INVALID_CREDENTIAL`, `MANIFEST_INVALID` | Fix the request using the OpenAPI schema; do not retry unchanged input. | | `401` | `UNAUTHORIZED` | Confirm the API key and base URL belong to the same environment; ask the administrator to reissue the bundle if needed. | | `404` | `CAPABILITY_NOT_FOUND` | Confirm the capability ID belongs to the current access bundle. | | `405` | `METHOD_NOT_ALLOWED` | Use the method documented for the route. | | `409` | `CONFLICT`, `CONTRACT_TEST_REQUIRED`, `CREDENTIAL_NOT_CONFIGURED` | Resolve the current capability state, then retry the logical operation. | | `413` | `REQUEST_TOO_LARGE` | Reduce the credential request to the documented limit. | | `422` | `VALIDATION_ERROR` | Send a text message with a non-empty body and valid fields. | | `500` | `AGENT_RUNTIME_ERROR`, `INTERNAL_ERROR` | Apply the host application's retry policy and retain the response code for support. | | `503` | `CREDENTIAL_VAULT_UNAVAILABLE` | Do not rotate repeatedly; retry according to the host policy and contact the operator if it persists. | Never log API keys, endpoint tokens, authorization headers, or complete request bodies containing secrets. For a suspected leak, stop and request rotation. --- END docs/integration/errors.md --- --- BEGIN docs/integration/idempotency.md --- # Idempotency ## Capability imports Every `POST /v1/capabilities/import` request requires an `Idempotency-Key` header. Generate one key for a single logical import and reuse that exact key when retrying the same request. ```bash -H "Idempotency-Key: capability-import-$(date +%s)" ``` A repeated import with the same key returns the previous result and includes `Idempotency-Replayed: true`; it does not create a second capability revision. Use a new key only for a new logical import, such as one containing a revised manifest. --- END docs/integration/idempotency.md --- --- BEGIN docs/integration/api.openapi.yaml --- openapi: 3.1.0 info: title: Forgium Agent Public API version: 2.0.0 description: | Stable public contract for sending messages to Forgium Agent and managing host-application capabilities. Authenticate with the API key issued for the target environment. contact: name: Forgium platform administrator license: name: Forgium public documentation terms identifier: LicenseRef-Forgium-Public-Docs servers: - url: https://{apiHost} description: Use the host from FORGIUM_AGENT_BASE_URL. Do not infer a host from this document. variables: apiHost: default: api.forgium.dev description: Hostname only, copied from FORGIUM_AGENT_BASE_URL. security: - bearerAuth: [] tags: - name: System description: Availability checks. - name: HTTP channel description: Synchronous text messaging. - name: Capabilities description: Self-service host-application capability lifecycle. paths: /health: get: operationId: getHealth summary: Check public API availability security: [] tags: [System] responses: '200': description: Public API is available. content: application/json: schema: $ref: '#/components/schemas/HealthResponse' example: status: ok service: agent-api '400': description: Invalid health-check request. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '503': description: Public API is temporarily unavailable. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /v1/channels/http/messages: post: operationId: sendHttpMessage summary: Send a text message and receive a synchronous response tags: [HTTP channel] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/HttpChannelRequest' example: user_id: mobile_user_123 message: type: text body: Hello, can you help me? metadata: platform: ios app_version: 1.0.0 responses: '200': description: Agent response. content: application/json: schema: $ref: '#/components/schemas/HttpChannelResponse' example: conversation_id: conv_abc123def456 message: id: msg_abc123def456 role: assistant type: text body: Hello, how can I help? '401': $ref: '#/components/responses/Unauthorized' '405': $ref: '#/components/responses/HttpMethodNotAllowed' '409': $ref: '#/components/responses/HttpDuplicateEvent' '422': $ref: '#/components/responses/HttpValidationError' '500': $ref: '#/components/responses/HttpRuntimeError' /v1/capability-credentials/{credentialRef}: put: operationId: configureCapabilityCredential summary: Store or rotate a host-endpoint credential description: The secret is encrypted at rest and is never returned or included in a capability manifest. tags: [Capabilities] parameters: - $ref: '#/components/parameters/CredentialRef' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CredentialRequest' example: auth_type: bearer secret: endpoint-token-from-secret-manager responses: '201': description: Credential configured. The secret is not returned. content: application/json: schema: $ref: '#/components/schemas/CredentialResponse' '400': $ref: '#/components/responses/ValidationError' '401': $ref: '#/components/responses/Unauthorized' '413': description: Request exceeds the credential size limit. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '503': description: Credential vault is unavailable. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /v1/capabilities: get: operationId: listCapabilities summary: List capabilities available to the API key tags: [Capabilities] responses: '200': description: Capability definitions scoped to the API key. content: application/json: schema: $ref: '#/components/schemas/CapabilityListResponse' '401': $ref: '#/components/responses/Unauthorized' /v1/capabilities/import: post: operationId: importCapabilities summary: Import capabilities as drafts description: Import does not activate a capability. A contract test is required before activation. tags: [Capabilities] parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CapabilityManifest' responses: '201': description: Draft capabilities created. content: application/json: schema: $ref: '#/components/schemas/CapabilityImportResponse' '400': $ref: '#/components/responses/ValidationError' '401': $ref: '#/components/responses/Unauthorized' '409': $ref: '#/components/responses/Conflict' /v1/capabilities/{capabilityId}: get: operationId: getCapability summary: Get one capability tags: [Capabilities] parameters: - $ref: '#/components/parameters/CapabilityId' responses: '200': description: Capability definition and revision history. content: application/json: schema: $ref: '#/components/schemas/CapabilityDetailResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: operationId: reviseCapability summary: Create a draft revision of a capability description: If-Match must contain the current numeric revision. The revised capability must be tested again. tags: [Capabilities] parameters: - $ref: '#/components/parameters/CapabilityId' - $ref: '#/components/parameters/IfMatch' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CapabilityPatchRequest' responses: '200': description: Draft revision created. content: application/json: schema: $ref: '#/components/schemas/CapabilityLifecycleResponse' '400': $ref: '#/components/responses/ValidationError' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '409': $ref: '#/components/responses/Conflict' /v1/capabilities/{capabilityId}/test: post: operationId: testCapability summary: Run a contract test for a read capability description: A passed test is tied to the current revision and is required for activation. tags: [Capabilities] parameters: - $ref: '#/components/parameters/CapabilityId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CapabilityTestRequest' example: arguments: name: Juan Pérez responses: '200': description: Contract test result. content: application/json: schema: $ref: '#/components/schemas/CapabilityTestResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '409': $ref: '#/components/responses/Conflict' /v1/capabilities/{capabilityId}/activate: post: operationId: activateCapability summary: Activate a tested capability tags: [Capabilities] parameters: - $ref: '#/components/parameters/CapabilityId' responses: '200': description: Capability is active. content: application/json: schema: $ref: '#/components/schemas/CapabilityLifecycleResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '409': $ref: '#/components/responses/Conflict' /v1/capabilities/{capabilityId}/disable: post: operationId: disableCapability summary: Disable a capability tags: [Capabilities] parameters: - $ref: '#/components/parameters/CapabilityId' responses: '200': description: Capability is disabled. content: application/json: schema: $ref: '#/components/schemas/CapabilityLifecycleResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' components: securitySchemes: bearerAuth: type: http scheme: bearer description: API key issued out of band by the Forgium administrator. parameters: CredentialRef: name: credentialRef in: path required: true schema: type: string pattern: '^cred_[A-Za-z0-9_-]{3,120}$' minLength: 7 maxLength: 128 CapabilityId: name: capabilityId in: path required: true schema: type: string pattern: '^cap_[a-z0-9]+$' minLength: 8 maxLength: 80 IdempotencyKey: name: Idempotency-Key in: header required: true schema: type: string minLength: 1 maxLength: 200 IfMatch: name: If-Match in: header required: true schema: type: string minLength: 1 maxLength: 80 schemas: HealthResponse: type: object additionalProperties: false required: [status, service] properties: status: type: string enum: [ok] maxLength: 16 service: type: string maxLength: 64 HttpChannelRequest: type: object additionalProperties: false required: [message] properties: conversation_id: type: string minLength: 1 maxLength: 128 user_id: type: string minLength: 1 maxLength: 200 message: $ref: '#/components/schemas/TextMessageRequest' metadata: type: object additionalProperties: type: string maxLength: 500 maxProperties: 30 TextMessageRequest: type: object additionalProperties: false required: [type, body] properties: type: type: string enum: [text] maxLength: 16 body: type: string minLength: 1 maxLength: 10000 HttpChannelResponse: type: object additionalProperties: false required: [conversation_id, message] properties: conversation_id: type: string minLength: 1 maxLength: 128 message: $ref: '#/components/schemas/AssistantMessage' AssistantMessage: type: object additionalProperties: false required: [id, role, type, body] properties: id: type: string minLength: 1 maxLength: 128 role: type: string enum: [assistant] maxLength: 16 type: type: string enum: [text] maxLength: 16 body: type: string maxLength: 20000 CredentialRequest: type: object additionalProperties: false required: [auth_type, secret] properties: auth_type: type: string enum: [bearer, api_key, basic] maxLength: 16 header_name: type: string enum: [x-api-key, x-api-token] maxLength: 32 secret: type: string minLength: 1 maxLength: 4096 CredentialResponse: type: object additionalProperties: false required: [credential_ref, status] properties: credential_ref: type: string maxLength: 128 status: type: string enum: [configured] maxLength: 32 CapabilityManifest: type: object additionalProperties: false required: [domain, capabilities] properties: domain: type: string pattern: '^[a-z][a-z0-9_-]{1,63}$' minLength: 2 maxLength: 64 capabilities: type: array minItems: 1 maxItems: 50 items: $ref: '#/components/schemas/CapabilityDefinition' CapabilityDefinition: type: object additionalProperties: false required: [name, description, when_to_use, method, url, auth, safe_headers, input_schema, output_schema, side_effect, requires_approval, timeout_ms, retry_count] properties: name: type: string pattern: '^[a-z][a-z0-9_]{1,63}$' minLength: 2 maxLength: 64 description: type: string minLength: 1 maxLength: 1000 when_to_use: type: string minLength: 1 maxLength: 1000 method: type: string enum: [GET, POST, PUT, PATCH, DELETE] maxLength: 6 url: type: string format: uri pattern: '^https://' maxLength: 2048 allowed_host: type: string maxLength: 253 auth: $ref: '#/components/schemas/CapabilityAuth' safe_headers: type: object additionalProperties: false properties: accept: type: string maxLength: 100 content-type: type: string enum: [application/json] maxLength: 100 input_schema: $ref: '#/components/schemas/JsonSchemaDocument' output_schema: $ref: '#/components/schemas/JsonSchemaDocument' business_rules: type: array maxItems: 50 items: type: string maxLength: 1000 examples: type: array maxItems: 20 items: type: object additionalProperties: true side_effect: type: string enum: [read, create, update, delete, external_send] maxLength: 32 requires_approval: type: boolean idempotency_header: type: string maxLength: 100 timeout_ms: type: integer minimum: 1000 maximum: 10000 retry_count: type: integer minimum: 0 maximum: 1 cache_ttl_seconds: type: integer minimum: 0 maximum: 86400 CapabilityAuth: type: object additionalProperties: false required: [type, credential_ref] properties: type: type: string enum: [bearer, api_key, basic] maxLength: 16 credential_ref: type: string pattern: '^cred_[A-Za-z0-9_-]{3,120}$' maxLength: 128 header_name: type: string enum: [x-api-key, x-api-token] maxLength: 32 JsonSchemaDocument: type: object description: Bounded JSON Schema document used to validate capability arguments or results. additionalProperties: true CapabilityImportResponse: type: object additionalProperties: false required: [capabilities] properties: capabilities: type: array maxItems: 50 items: $ref: '#/components/schemas/CapabilityLifecycleResponse' CapabilityListResponse: type: object additionalProperties: false required: [capabilities] properties: capabilities: type: array maxItems: 1000 items: $ref: '#/components/schemas/CapabilitySummary' CapabilitySummary: type: object unevaluatedProperties: false required: [id, name, description, when_to_use, input_schema, output_schema, business_rules, examples, side_effect, requires_approval, revision, lifecycle_status] properties: id: type: string maxLength: 80 name: type: string maxLength: 64 description: type: string maxLength: 1000 when_to_use: type: string maxLength: 1000 input_schema: $ref: '#/components/schemas/JsonSchemaDocument' output_schema: $ref: '#/components/schemas/JsonSchemaDocument' business_rules: type: array maxItems: 50 items: type: string maxLength: 1000 examples: type: array maxItems: 20 items: type: object additionalProperties: true side_effect: type: string maxLength: 32 requires_approval: type: boolean revision: type: integer minimum: 1 lifecycle_status: type: string enum: [draft, active, disabled] maxLength: 16 credential_configured: type: boolean updated_at: type: string format: date-time maxLength: 64 CapabilityDetailResponse: allOf: - $ref: '#/components/schemas/CapabilitySummary' - type: object unevaluatedProperties: false required: [method, url, revisions] properties: method: type: string maxLength: 6 url: type: string format: uri maxLength: 2048 revisions: type: array maxItems: 100 items: $ref: '#/components/schemas/CapabilityRevision' CapabilityRevision: type: object additionalProperties: false required: [revision, change_type, actor_type, actor_id, created_at] properties: revision: type: integer minimum: 1 change_type: type: string maxLength: 32 actor_type: type: string maxLength: 32 actor_id: type: string maxLength: 128 created_at: type: string format: date-time maxLength: 64 CapabilityPatchRequest: type: object additionalProperties: false required: [capability] properties: domain: type: string maxLength: 64 capability: $ref: '#/components/schemas/CapabilityDefinition' CapabilityTestRequest: type: object additionalProperties: false required: [arguments] properties: arguments: type: object additionalProperties: true CapabilityTestResponse: type: object additionalProperties: false required: [status, capability_id, revision] properties: status: type: string enum: [passed, failed] maxLength: 16 capability_id: type: string maxLength: 80 revision: type: integer minimum: 1 error_code: type: string maxLength: 100 CapabilityLifecycleResponse: type: object additionalProperties: false required: [id, lifecycle_status, revision] properties: id: type: string maxLength: 80 lifecycle_status: type: string enum: [draft, active, disabled] maxLength: 16 revision: type: integer minimum: 1 ErrorResponse: type: object additionalProperties: false required: [error, code] properties: error: type: string maxLength: 500 code: type: string maxLength: 100 HttpErrorResponse: type: object additionalProperties: false required: [error] properties: error: type: object additionalProperties: false required: [code, message] properties: code: type: string maxLength: 100 message: type: string maxLength: 500 details: type: object additionalProperties: true responses: Unauthorized: description: API key is missing, invalid, expired, or revoked. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: Invalid API key code: UNAUTHORIZED ValidationError: description: Request body or parameter is invalid. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: VALIDATION_ERROR code: VALIDATION_ERROR HttpMethodNotAllowed: description: HTTP method is not supported for this route. headers: Allow: schema: type: string maxLength: 100 content: application/json: schema: $ref: '#/components/schemas/HttpErrorResponse' HttpDuplicateEvent: description: The message event was already processed. content: application/json: schema: $ref: '#/components/schemas/HttpErrorResponse' HttpValidationError: description: The HTTP channel request is invalid. content: application/json: schema: $ref: '#/components/schemas/HttpErrorResponse' HttpRuntimeError: description: The agent runtime could not produce a response. content: application/json: schema: $ref: '#/components/schemas/HttpErrorResponse' NotFound: description: Capability does not exist for this API key. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' Conflict: description: The requested operation conflicts with the current capability state. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' --- END docs/integration/api.openapi.yaml --- --- BEGIN docs/integration/agent-consumer-pack.md --- # Forgium Agent — integration package This exported package is the public contract for an external developer or AI agent integrating an application with Forgium Agent. > **Compatibility URL:** the canonical agent entrypoint is > [Use Forgium Agent with an agent](use-with-an-agent.md). This page remains > available so existing public links do not break. ## Start here Read the documents in this order: 1. [Overview](overview.md) — what Forgium Agent does and which integration path to choose. 2. [Getting started](getting-started.md) — receive the access bundle and send the first HTTP message. 3. [Environments](environments.md) — isolate development, staging, and production. 4. Choose the task-specific guide: - [Business capabilities](capability-handoff.md) for live data or actions from the host application. - [OpenAPI](api.openapi.yaml) for the complete Public API contract. The Skill source is not currently distributed as an installable artifact. Use the universal agent entrypoint above instead. ## Authority boundary The Forgium administrator provides this access bundle: ```bash FORGIUM_AGENT_BASE_URL=https:// FORGIUM_AGENT_API_KEY=mg_xxx ``` Use the API key with the Public API (`/v1/*`) to send messages and manage business capabilities. If either value is missing, ask the administrator. ## Completion paths | Goal | Completion condition | |---|---| | Send a message from a host application | A request to `POST /v1/channels/http/messages` returns an assistant message. | | Give the agent live business data or an action | A scoped host endpoint is imported, contract-tested, activated, and verified through chat. | A generic response to a domain query usually means the required business capability is absent or inactive. Follow the complete lifecycle in [capability-handoff.md](capability-handoff.md); do not substitute chat middleware, a proxy workaround, a placeholder URL, or an unauthenticated host endpoint. --- END docs/integration/agent-consumer-pack.md --- --- BEGIN docs/skill/micro-agent-integrator/SKILL.md --- --- name: micro-agent-integrator description: >- Optional workflow for integrating an external application with Forgium Agent over the public HTTP channel and host-application capabilities. version: 1.1.0 --- # Forgium Agent Integrator This source is public for runtimes that already support a local `SKILL.md`; it is not currently distributed through an installable package or registry. The canonical contract remains the public documentation. ## Read first `` means the root of the exported public documentation package. Read in this order: 1. `/integration/use-with-an-agent.md` 2. `/integration/overview.md` 3. `/integration/environments.md` 4. `/integration/request-access.md` when access is missing 5. `/integration/getting-started.md` for HTTP 6. `/integration/capability-handoff.md` for capabilities 7. `/integration/api.openapi.yaml` for exact schemas ## Workflow 1. Determine whether the task is connectivity-only or code integration. 2. For connectivity-only, do not inspect or modify an unrelated repository: use the access bundle and the HTTP quickstart to send one message. 3. For code integration, inspect the host repository and identify the requested behavior. Choose the minimum route: HTTP for a synchronous agent response, or capabilities for approved live host data/actions. Capabilities are optional. 4. Confirm `FORGIUM_AGENT_BASE_URL` and `FORGIUM_AGENT_API_KEY` only when a real API call or deployment is required. If either is missing, request the environment-specific bundle and continue with local work or mocks. 5. Implement only the selected route using the canonical guide and OpenAPI contract. Do not invent a data source, tunnel, framework, or deployment. 6. Run local tests and the applicable authenticated smoke test. 7. For capabilities, follow the canonical lifecycle: protect and expose the endpoint, provision its scoped credential, create a secret-free manifest, import, contract-test, activate, and verify through chat. Never use a placeholder URL or unauthenticated endpoint. 8. Report changes, verification evidence, and every actionable blocker. Do not claim a capability is active without successful activation and chat verification. ## Security boundary Use only the Public API with the supplied bundle. Never request Admin API credentials, platform secrets, internal bindings, or secrets from source control. Keep API keys and endpoint tokens out of manifests, prompts, logs, screenshots, and persisted agent context. --- END docs/skill/micro-agent-integrator/SKILL.md ---