Skip to main content

Handshake Prompt Protocol - grant AI Agents access to web services via a single copy-paste prompt

Project description

handshake-prompt (Python Server SDK)

Server-side SDK for the Handshake Prompt Protocol (HPP) — a lightweight way to grant any AI Agent access to your web service via a single copy-paste prompt. No API keys, no MCP servers, no env vars for end users.

Install

pip install handshake-prompt

Quick start (Flask)

from flask import Flask
from flask_sock import Sock
from handshake_prompt import HandshakeManager

app  = Flask(__name__)
sock = Sock(app)
hm   = HandshakeManager(app, sock)   # done! HPP endpoints are now mounted.

if __name__ == '__main__':
    app.run(port=5000)

That's it. Your service now exposes:

Endpoint Method Purpose
/handshake/session POST Browser creates a handshake session
/handshake/context/<sid> GET Agent reads current state (token-auth)
/handshake/action/<sid> POST Agent submits actions (token-auth)
/handshake/notify/<sid> POST Browser reports user edits
/handshake/diff/<sid> GET Agent fetches incremental changes
/ws/handshake/<sid> WS Real-time push channel (token-auth)

Build a handshake prompt

prompt_text = hm.build_prompt(session, base_url='https://your-service.com')
# Display this text in the UI, let user copy-paste it to their Agent.

Configure schema

Schemas describe what fields the Agent should fill. Sent by the browser when creating a session:

{
  "mode": "form-fill",
  "schema": [
    {"key": "name",  "label": "Name",  "type": "string", "required": true, "example": "Alice"},
    {"key": "age",   "label": "Age",   "type": "int",    "example": 30},
    {"key": "vip",   "label": "VIP",   "type": "bool"}
  ],
  "context": {}    // current state, used by browser to pre-populate
}

Supported types: string / int / float / bool / datetime / array<string> / enum. Custom validators can be plugged in via HandshakeManager(validator=...).

Hooks

Attach custom logic at key lifecycle points:

@hm.on_create_session
def bind_owner(sess, request):
    """Bind a session to the current logged-in user"""
    from flask import session as flask_session
    sess.owner = flask_session.get('user_id')

@hm.on_action
def audit(sess, action, request):
    """Audit every action; return False to veto"""
    print(f'[AUDIT] sid={sess.sid} user={sess.owner} action={action}')

@hm.on_done
def notify_done(sess, applied, rejected, errors):
    """Called after each batch of actions"""
    pass

Browser auth for /notify

By default /notify/<sid> accepts any request (it's only used by browsers within the same origin). For stricter setups, supply a callable:

def my_auth(request, sess):
    return flask_session.get('user_id') == sess.owner

hm = HandshakeManager(app, sock, require_browser_auth=my_auth)

Security defaults

  • Token entropy: 192 bits (secrets.token_urlsafe(24))
  • Session ID entropy: 128 bits (secrets.token_hex(16))
  • Timing-safe comparison: secrets.compare_digest
  • TTL: 30 minutes default
  • Rate limit: 60 requests / minute / session
  • User-data protection: AI cannot overwrite fields marked by=user or by=user_edit
  • WebSocket auth: connection-time token verification

See SPEC.md of the main repository for full protocol details.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

handshake_prompt-0.1.1.tar.gz (11.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

handshake_prompt-0.1.1-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file handshake_prompt-0.1.1.tar.gz.

File metadata

  • Download URL: handshake_prompt-0.1.1.tar.gz
  • Upload date:
  • Size: 11.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for handshake_prompt-0.1.1.tar.gz
Algorithm Hash digest
SHA256 6fd457bac9823f9f0791ddfa8d5a3e06de77dbe977ac19f736a82f6ec6d6c530
MD5 342f30fbfdd87da547d3beb8582eefdb
BLAKE2b-256 85ac6c8f0d84393e72dce35c4ab18b1f1ac8ebbafb983aae9f02957454057b4c

See more details on using hashes here.

File details

Details for the file handshake_prompt-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for handshake_prompt-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3346c445866942b51599a38ddd0ddd701209af2d587d7da1d7efd98a9e5f618c
MD5 3e27b8a6c25d40ad5654887444d9bde7
BLAKE2b-256 8e55800375e9d6fa00a3200f48f6f406bf731b07b14fcdcb60b8cd8a67323ef3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page