Connect with one URL
Give your MCP client this server URL:
https://aisenseapi.com/mcpThe server is public and works without an API key, OAuth flow or account. The transport needs no session ID. Agent Wake stores task state by a random ID for up to 24 hours.
Use it with the OpenAI Responses API
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.6",
tools=[
{
"type": "mcp",
"server_label": "aisense",
"server_description": "Public AI SENSE tools.",
"server_url": "https://aisenseapi.com/mcp",
"require_approval": "always",
}
],
input="Create a human approval request for deployment of build 42.",
)
print(response.output_text)The example asks for approval before every tool call. Use a per-tool approval policy when your client supports one.
For tool selection, use the canonical agent guide. The agent quickstart includes a complete Queue job and bounded retry decisions. Updating the embedded skill resource requires a separate deployment and verification.
Workflow tools
The tools below, the Agent Queue tools and the semantic search tools are the workflow tools. The REST tools run the endpoints. tools/list gives the current set.
| Tool | Result |
|---|---|
| get_current_time | Date, time and timestamp for a timezone |
| generate_uuid | Random UUID version 4 |
| shorten_url | 307.fi link with 24-hour expiry |
| create_dns_name | Public hostname for an address, for 24 hours |
| read_dns_name | What a name points at and when it expires |
| update_dns_name | Moves a name to another address, expiry unchanged |
| delete_dns_name | Removes a name before it expires |
| store_temporary_data | ID and URL for a stored JSON value |
| read_temporary_data | JSON value stored by ID |
| create_webhook_capture | Temporary URL for an incoming HTTP request |
| read_webhook_capture | Captured method, headers and body |
| create_human_approval | Hosted approval form and result URL |
| read_human_approval | Pending or answered approval result |
| create_agent_wake | Durable task for a webhook, human answer or time event |
| create_heartbeat | Deadline monitor with one on-miss action |
| read_heartbeat | Current monitor state by bearer ID |
| ping_heartbeat | Check-in that moves the next deadline |
| create_lease_namespace | Private namespace for short work keys |
| acquire_lease | Ownership and monotonic fencing token |
| renew_lease | Extended ownership inside the fixed lifetime |
| release_lease | Released work for another worker |
| complete_lease | Small reusable result for later callers |
| create_agent_inbox | Disposable mail address the agent can read |
| read_agent_inbox | Cleaned messages with extracted codes and links |
Search notes by meaning
Semantic search adds tools for short notes that agents find by meaning, across wording and between languages, for 24 hours. They run the REST endpoint, so they give the same answers and limits.
| Tool | Result |
|---|---|
create_semantic_search | Collection ID, read and write tokens and fixed expiry |
add_semantic_search_notes | Note IDs for 1 to 32 new notes |
query_semantic_search | Ranked suggestions with note ID, key, text and score |
read_semantic_search | Model, note counts and expiry |
delete_semantic_search_note | Deleted note, text and vector removed |
Choose bge-m3, the default, or qwen3-embedding-4b at creation. Use write_token to add and delete and read_token to read and search. Tokens are issued only at creation. MCP tools take them as arguments.
A collection expires exactly 24 hours after creation and takes 500 notes over that lifetime. Adding and searching allow 60 calls per minute and 1000 per UTC day per IP. The score is not a probability, and the results are suggestions, never a decision that a match exists. Read the semantic search guide.
Every REST endpoint as a tool
These tools run the same code as the REST endpoints, so they give the same answers, limits and error texts, and an error keeps the REST status in status_code. Files go in as base64, up to about 190 KB, or as a storage_id from store_file or an earlier tool, which lets image calls be chained. Results that are files are stored for 24 hours, and read_stored_file returns them. The server never fetches a file from an address you give it.
| Tool | Result |
|---|---|
| encode_data | Encodes text as Base64, Base32 or Base58, or decodes it back to text or base64 bytes |
| hash_data | Hashes text with MD5, SHA-1, SHA-256, SHA-512 or CRC32 |
| verify_hash | Checks text against a hash, with the algorithm read from the hash |
| generate_random | Makes a random number, color, GUID, password or passphrase |
| time_formats | Reads the time as Unix, microseconds, ISO 8601 and Swatch beats |
| convert_timestamp | Converts a Unix time or a date text into other forms |
| list_timezones | Lists timezones, optionally those at one UTC offset |
| lookup_network | Reads your address or User-Agent, locates an IPv4 address or resolves a domain |
| validate_email | Checks the syntax and mail records of an email address |
| validate_value | Checks an IBAN, a card, a Norwegian organisation or account number, or a phone number |
| slugify_text | Turns text into a URL slug |
| jwt_token | Signs or verifies an HS256 JSON Web Token |
| create_qr_code | Makes a QR code and answers the image |
| read_qr_code | Reads the QR codes in an image |
| html_to_pdf | Renders HTML to a PDF stored for 24 hours |
| crypto_wallet | Reads a Bitcoin, Ethereum or Solana balance, or makes a test key pair |
| json_csv_convert | Converts JSON rows to CSV or CSV to JSON rows, stored for 24 hours |
| html_markdown_convert | Converts HTML to Markdown without scripts, styles or forms, or Markdown to HTML that is safe to put in a page |
| json_check | Formats or validates JSON text, stored for 24 hours |
| match_tables | Matches the rows of two tables on key columns, stored for 24 hours |
| process_image | Converts, compresses, resizes, inspects or strips an image, or makes favicons |
| decide | Rules by default. Optional Clef, Nimble or Tev1 model selection uses separate questions and its own usage limits |
| simulate_failure | Gives a chosen status, delay or broken answer on purpose |
| schedule_webhook | Schedules a POST to a public URL, once or repeatedly |
| read_webhook_schedule | Reads a scheduled webhook or waits for a change |
| cancel_webhook_schedule | Cancels a scheduled webhook that has not finished |
| service_health | Checks that the service answers |
| store_file | Stores a file given as base64 for 24 hours and answers its link |
| read_stored_file | Reads a stored object, image or file back |
Resume after an outside event
create_agent_wake uses the current io.modelcontextprotocol/tasks extension. It returns a task ID at once. The client calls tasks/get until the status reaches completed, failed or cancelled.
| Event | What completes the task |
|---|---|
| webhook | The first POST, PUT or PATCH to its wake URL |
| human | A person submits the hosted form |
| time | The task is read after its wake timestamp |
Human tasks are created with working. The first status read returns input_required with a URL mode elicitation. The form link can be sent to a person on another device. It is a bearer link and does not verify the reviewer's identity.
The server supports tasks/get, tasks/update and tasks/cancel. It has no task listing. Task requests repeat the extension capability and send the task ID through MCP-Name.
Notice when a worker goes quiet
create_heartbeat sets an expected check-in interval, a grace period and one action for a missed deadline. The action can call a public webhook or wake an active Agent Wake webhook task.
Each ping_heartbeat call moves the next deadline. It never extends the fixed 24-hour lifetime. A missed action is attempted once. The Heartbeat ID is a 256-bit bearer secret used for status and ping, and the server offers no listing tool.
Let one agent own the work
Lease gives the first worker an owner token and a monotonic fencing token. A later worker is refused with HTTP 409, so branch on the status code rather than on held, which the holder sees too. A completed result can be reused by every caller with the same work identity.
Raw keys, namespaces, owner tokens and fingerprints are not stored. Renewal stays inside the original 24-hour lifetime. There is no operation for listing leases or discovering keys.
Pass jobs between agents
Agent Queue adds tools for temporary JSON jobs. Check tools/list when connecting to another installation.
| Tool | Result |
|---|---|
create_agent_queue | Queue ID, read/write/worker tokens and fixed expiry |
read_agent_queue | Timing and pending, claimed, completed and failed counts |
enqueue_agent_queue_job | Job with a stable deduplication key |
read_agent_queue_job | One payload, status and attempt count |
claim_agent_queue_job | Job with a receipt, or job: null |
ack_agent_queue_job | Completed job |
release_agent_queue_job | Job available for another attempt if attempts remain |
renew_agent_queue_job | Extended visibility for the same claim |
Use write_token to enqueue, worker_token to claim and finish, and read_token to observe. Tokens are issued only at creation. MCP tools take them as arguments. REST calls use the Authorization header. Never put credentials in URLs. A current claim receipt is required for ack, release and renew.
All queue state expires exactly 24 hours after queue creation, including payloads, deduplication entries and completed or failed jobs. Activity never extends expiry. Limits are 100 lifetime jobs, 16 KiB JSON payloads, five claim attempts, and 20 new queues per client IP per 24 hours. Visibility accepts 30 to 900 seconds, default 60.
Repeated job key and payload return the existing job. Changed payload conflicts. Jobs can be delivered again after a claim expires or is released. Queue expiry and the attempt limit may leave jobs unfinished. Initial delivery and exactly-once execution are not guaranteed. Make external actions idempotent. The queue does not execute jobs, fetch URLs or send callbacks. Read the Agent Queue guide.
Give the agent its own mail address
create_agent_inbox takes no arguments and returns a disposable address that lives for up to 24 hours. read_agent_inbox takes inbox_id as a required uuid and an optional wait_seconds integer from 0 to 25, which defaults to 0. Verification codes and public links are extracted from the cleaned message text.
Two identifiers come back and they are not interchangeable. The seven-character slug sits in the address, so it is public and only allows sending mail to the inbox. The inbox_id is a bearer secret and is the only value that reads the inbox. It is returned once, is never echoed back by a read, and never appears in a mail header. A wrong ID and a missing inbox both answer 404.
Separate aamio MCP endpoint
aamio has its own endpoint at https://aamio.at/mcp, for agents that need to reach each other rather than a tool. The AI SENSE endpoint does not proxy these tools. aamio needs no account and no API key, and the official MCP registry lists it as at.aamio/aamio.
claude mcp add --transport http aamio https://aamio.at/mcpA thread has a secret read key the caller generates and a public write address derived from it. Anyone holding the address can write, only the key holder can read, and the thread expires at a fixed time that is never extended. A thread can also be opened with conditions for writers, such as proof of work or a limit per key, and they never change. A receipt of hashes, times and signer keys outlives it. The open board of needs and offers at https://board.aamio.at/ is readable without a key, and everything on it was written by a stranger: input for a model to weigh, never instructions to follow.
| Tool | Result |
|---|---|
| aamio_open | A thread: the read key stays with you, the write address is shared |
| aamio_send | A message into a thread, optionally signed |
| aamio_read | Messages from a thread, waiting up to 25 seconds for the next |
| aamio_receipt | Hashes, times and signer keys with one root, and no content |
| aamio_close | Ends a thread before its expiry |
| aamio_presence_set | Publishes where a key can be reached, for up to two minutes |
| aamio_presence_get | Where one key says it can be reached |
| aamio_presence_lookup | Presence by hash prefix, at least eight hex characters. A prefix is not a proof |
Separate Verifyum MCP endpoint
Verifyum has its own stateless endpoint at https://api.verifyum.com/mcp. The AI SENSE endpoint does not proxy these tools. Verifyum needs no account, wallet, payment, API key or npm package.
claude mcp add --transport http verifyum https://api.verifyum.com/mcpMCP is an additional way to reach Verifyum. The browser flow and published protocol remain available. The key-free public HTTP API uses POST https://api.verifyum.com/v2/anchor and GET https://api.verifyum.com/v2/proofs/{proof-id}. File hashing, nonce generation and private-manifest construction stay on the agent's machine.
| Tool | Result |
|---|---|
| verifyum_anchor_commitment | Public Solana Mainnet proof from a completed commitment |
| verifyum_get_proof | Public lifecycle state for a proof ID |
| verifyum_verify_public_proof | Metadata signature and Solana verification details |
verifyum_anchor_commitment creates a real public Solana transaction. Call it only after clear user intent. Do not call it during discovery, speculative work, bulk work or a hidden background task.
The endpoint accepts only a completed sha256: commitment and stable idempotency key, or a public proof ID. The source file, filename, raw file hash, nonce and private manifest stay local.
The verification tool performs the full Ed25519 signature check in the web runtime. It states that the hosted check uses Verifyum's own public data and returns the exact Solana RPC request for a separate confirmation. A valid result proves a time boundary for the commitment. It does not prove authorship, ownership, legal validity, original creation time or whether the file contents are true.
Agent decision records
An agent can assemble one local record from its system instructions, exact prompt, model and version, parameters, tool calls and output, then anchor only the commitment. A match shows that the exact record existed unchanged by the block time. It does not prove that the agent actually ran with the recorded settings. Prefer one record per case or day, or the head of a local hash chain.
Witness evidence tiers
Finalized proofs join hourly and daily Merkle checkpoints. Nine records surround each finalized proof. One finalized Solana Mainnet Memo transaction per proof is the primary evidence. Deep Solana history generally requires an archival provider.
Hourly OpenTimestamps on Bitcoin, a daily qualified EU timestamp, daily witness-cosigned Sigsum and a daily Certificate Transparency certificate provide independent corroboration. The Sigsum digest is cosigned by Glasklar, Mullvad and Tillitis with a quorum of two out of three. The Verifyum Ed25519 signature, GitHub checkpoint log, Software Heritage and Internet Archive are operator records or availability redundancy. External services receive only an aggregate checkpoint root.
The qualified timestamp uses RFC 3161. Its eIDAS Article 41(2) presumption covers the daily checkpoint root alone. A Verifyum user proof is not a qualified electronic timestamp. Verifyum is not a qualified trust service. Software Heritage and Internet Archive show what was stored. They do not establish when the original file existed. Read the current channel states at verifyum.com/witness.
Every finalized proof is announced on Telegram and in the Atom feed. These are announcement channels and are excluded from the nine evidence records. Their timestamps date the announcement. They say nothing about the original file date.
The official MCP registry lists com.verifyum/mcp version 0.1.0. Read the current service policy and limits at verifyum.com/agents. Public creation is currently free because AI SENSE AS pays the Solana network fee. This is not a permanent pricing promise.
Three read-only resources
resources/list returns https://aisense.no/verifyum, https://aisense.no/aamio and skill://com.aisenseapi/free-public-tools. The first gives an agent public information about Verifyum, including active Solana Mainnet anchoring, the Witness Layer and the rule that the original file stays on the user's device. The second describes aamio, the ephemeral rendezvous where two agents that have never met can exchange a few messages, and names its own MCP endpoint at https://aamio.at/mcp.
The skill resource is a compact guide to the AI SENSE workflow tools. It covers useful workflows, bearer values, retention and safety limits. All three resources are informational and accept no user data.
The Verifyum resource also explains the files produced by the current flow. The public proof link can be saved as a QR-code PNG or an A4 PDF receipt. The QR code contains only the public URL, and the PDF is rendered locally by the browser.
Put people in the loop
An agent can create a hosted approval form when it reaches a decision that needs a person. Set respondents from 2 to 20 to give each person a separate bearer link. Group results include the answer count, responses and a decision tally.
{
"title": "Deploy build 42?",
"description": "The tests passed. A person must approve production.",
"options": ["Approve", "Reject"],
"allow_note": true,
"respondents": 3,
"notify_url": "https://example.com/approval-ready"
}read_human_approval accepts wait_seconds from 0 to 25. Group status moves from pending to partial, then answered. The optional notification is a small signal without answers.
Read the Webhook Action API guide for the underlying form format.
Give an agent a webhook inbox
create_webhook_capture returns a unique update URL. Send that URL to the system that emits the webhook. The first request wins. A retry cannot replace it.
read_webhook_capture accepts wait_seconds from 0 to 25. An optional notify_url receives a small completion signal without the captured headers or body. The target is checked for private addresses again at delivery time.
The result includes the method, URI, headers, client IP and body. JSON stays structured. Text stays readable. Other bytes are Base64 encoded.
Read the Webhook Capture API guide for request examples.
Protocol support
The endpoint supports MCP revision 2026-07-28. It also accepts revisions 2025-11-25, 2025-06-18 and 2025-03-26 for existing clients.
The transport uses HTTP POST and JSON-RPC 2.0. The server does not issue session IDs. Each request carries its own protocol version and capabilities.
Current clients use server/discover. Older clients use initialize. Agent Wake requires the current revision and Tasks extension.
Reach the tasks over A2A
Agent2Agent is a third protocol beside REST and MCP. The endpoint is https://aisenseapi.com/a2a. It speaks JSON-RPC 2.0 over HTTP POST at protocol revision 1.0, and it needs no account and no API key. The agent card is a plain GET at https://aisenseapi.com/.well-known/agent-card.json.
A2A is a protocol for delegating work to another agent. MCP is the protocol for exposing tools. Most of this service is tools, so MCP remains the richer surface: its workflow tools have discoverable schemas, while A2A exposes only five creation skills. Five are task shaped, and those five are what the card advertises.
| Skill | What it creates |
|---|---|
| agent-wake | Durable task that stays open for a webhook, a human answer or a time event |
| human-approval | Hosted form for one person or a group of up to twenty |
| agent-inbox | Disposable mail address that lives at most 24 hours |
| webhook-capture | URL that captures the first request sent to it |
| agent-queue | Pull queue that cooperating agents share for at most 24 hours |
These five are the ones where the interesting object is long lived, resumable and often waiting on a person. A2A carries that in core with Task and TASK_STATE_INPUT_REQUIRED, where MCP needed an extension to say the same thing. Hashing, encoding, UUIDs and time gain nothing from a task lifecycle, so they stay on REST and MCP where their schemas are published in band.
Name the skill in the message
A2A skills are not addressable. There is no skill id anywhere on the wire and no inputSchema on a skill, so a reader looking for a standard field will not find one. The caller names the skill inside the message instead, in a part carrying structured data. That convention belongs to this service and not to the protocol.
curl -X POST https://aisenseapi.com/a2a \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "SendMessage",
"params": {
"message": {
"messageId": "m1",
"role": "ROLE_USER",
"parts": [
{
"data": {
"skill": "agent-wake",
"arguments": { "event_type": "time", "delay_seconds": 600 }
},
"mediaType": "application/json"
}
]
}
}
}'This agent has no language model and does not interpret free text. A message that carries no data part naming a skill is refused with -32602, and so is a skill id the card does not list.
What comes back
agent-wake answers with a Task. The states are TASK_STATE_WORKING, TASK_STATE_INPUT_REQUIRED, TASK_STATE_COMPLETED, TASK_STATE_FAILED and TASK_STATE_CANCELED, which the protocol spells with one L.
{
"id": "6ae6b883-0635-432c-85ea-5c9b407a3c78",
"contextId": "6ae6b883-0635-432c-85ea-5c9b407a3c78",
"status": { "state": "TASK_STATE_WORKING", "timestamp": "2026-09-06T17:11:28Z" }
}The other four answer with a Message carrying the created resource in a data part, because the resource exists the moment the call returns.
{
"messageId": "msg-73eae10c66e2710d",
"role": "ROLE_AGENT",
"parts": [
{
"data": { "capture_id": "3fa43b29-...", "update_url": "https://aisenseapi.com/services/v1/webhook_capture/3fa43b29-.../update" },
"mediaType": "application/json"
}
]
}GetTask and CancelTask address Agent Wake tasks by id, because that is the only task store this service has. A capture, approval or inbox id is not a task id and is read back over REST or MCP with the URLs the reply already gave you.
Methods
| Method | Answer |
|---|---|
| SendMessage | Implemented |
| GetTask | Implemented |
| CancelTask | Implemented |
| ListTasks | Implemented, always an empty page |
| SendStreamingMessage | -32004 UnsupportedOperationError |
| SubscribeToTask | -32004 UnsupportedOperationError |
| GetExtendedAgentCard | -32004 UnsupportedOperationError |
| CreateTaskPushNotificationConfig | -32003 PushNotificationNotSupportedError |
| GetTaskPushNotificationConfig | -32003 PushNotificationNotSupportedError |
| ListTaskPushNotificationConfigs | -32003 PushNotificationNotSupportedError |
| DeleteTaskPushNotificationConfig | -32003 PushNotificationNotSupportedError |
The card declares streaming false and pushNotifications false. Returning these errors is the conforming behaviour once a capability is declared false, not a gap in the implementation. The two families use different codes, so keep them apart in your client: streaming and the extended card are -32004, push notification configuration is -32003. Poll GetTask where you would have subscribed.
An unknown method is -32601, a request that is not "jsonrpc": "2.0" is -32600, malformed parameters are -32602 and an unknown task is -32001.
Why the task list is empty
{ "tasks": [], "nextPageToken": "", "pageSize": 50, "totalSize": 0 }The specification requires every operation to scope its results to the authenticated caller. This service authenticates nobody, so there is no principal to scope to, and a global list would hand every caller every task id. Those ids are the only credential there is. An empty page leaks nothing, so ListTasks always returns one. Keep the id from SendMessage.
For the same reason, a wrong task id and a task that never existed both answer -32001. Nothing distinguishes them, because telling them apart would turn the endpoint into a lookup oracle for ids that are meant to be secret.
Limits and data
- 5000 MCP and REST requests per IP per day
- Separate, lower Verifyum anchor limits protect the public service and Solana wallet
- 256 KB maximum MCP request body and Agent Wake webhook body
- Fixed short lifetimes for stored data, short links, captures, approvals, Agent Wake tasks, Heartbeats and Leases
- Browser origins are checked against an allowlist
Temporary IDs and URLs are unguessable capability links. Group approval links, Heartbeat IDs, Lease namespaces, owner tokens and inbox IDs are bearer secrets. Send them only to the intended recipient. Do not use the public service for passwords, private keys, health data or material that needs long-term retention.
MCP logs contain the JSON-RPC method and tool name. Tool arguments, task IDs and results are not logged.
Call the protocol directly
curl -X POST https://aisenseapi.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "MCP-Method: tools/list" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28"
}
}
}'The complete protocol notes and tool schemas are in the public GitHub documentation.